bool publish;
OSDictionary * user;
static IOMessage sSystemPower;
+ clock_sec_t now = 0;
+ clock_usec_t microsecs;
regEntry = IORegistryEntry::getRegistryRoot();
}
#if HIBERNATION
if (!loginLocked) gIOConsoleBooterLockState = 0;
+ IOLog("IOConsoleUsers: time(%d) %ld->%d, lin %d, llk %d, \n",
+ (num != 0), gIOConsoleLockTime, (num ? num->unsigned32BitValue() : 0),
+ gIOConsoleLoggedIn, loginLocked);
#endif /* HIBERNATION */
gIOConsoleLockTime = num ? num->unsigned32BitValue() : 0;
}
#endif /* HIBERNATION */
else if (gIOConsoleLockTime)
{
- clock_sec_t now;
- clock_usec_t microsecs;
-
clock_get_calendar_microtime(&now, µsecs);
if (gIOConsoleLockTime > now)
{
else if (gIOConsoleLockTime) gIOScreenLockState = kIOScreenLockUnlocked;
else gIOScreenLockState = kIOScreenLockNoLock;
gIOChosenEntry->setProperty(kIOScreenLockStateKey, &gIOScreenLockState, sizeof(gIOScreenLockState));
+
+ IOLog("IOConsoleUsers: gIOScreenLockState %d, hs %d, bs %d, now %ld, sm 0x%x\n",
+ gIOScreenLockState, gIOHibernateState, (gIOConsoleBooterLockState != 0), now, systemMessage);
}
#endif /* HIBERNATION */
if (voucher == IV_NULL)
return MACH_SEND_INVALID_DEST;
- mach_msg_type_number_t __assert_only max_sz = sz;
+ mach_msg_type_number_t max_sz = sz;
if (sz < MACH_VOUCHER_TRAP_STACK_LIMIT) {
/* keep small recipes on the stack for speed */
if (kr == KERN_SUCCESS && sz > 0)
kr = copyout(krecipe, (void *)args->recipe, sz);
} else {
- uint8_t *krecipe = kalloc((vm_size_t)sz);
+ uint8_t *krecipe = kalloc((vm_size_t)max_sz);
if (!krecipe) {
kr = KERN_RESOURCE_SHORTAGE;
goto done;
}
- if (copyin(args->recipe, (void *)krecipe, args->recipe_size)) {
- kfree(krecipe, (vm_size_t)sz);
+ if (copyin(args->recipe, (void *)krecipe, sz)) {
+ kfree(krecipe, (vm_size_t)max_sz);
kr = KERN_MEMORY_ERROR;
goto done;
}
if (kr == KERN_SUCCESS && sz > 0)
kr = copyout(krecipe, (void *)args->recipe, sz);
- kfree(krecipe, (vm_size_t)sz);
+ kfree(krecipe, (vm_size_t)max_sz);
}
kr = copyout(&sz, args->recipe_size, sizeof(sz));
--- /dev/null
+/*
+ * Test voucher trap APIs.
+ * There was an unfortunate bug in the trap interface that used the user space
+ * _address_ of a trap parameter as a copyin size. This test validates there
+ * are no other kernel panics in the voucher create and voucher attribute
+ * extraction mach traps.
+ *
+ * clang -o voucher_traps voucher_traps.c -ldarwintest -Weverything -Wno-gnu-flexible-array-initializer
+ *
+ * <rdar://problem/29379175>
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <mach/mach.h>
+#include <mach/mach_vm.h>
+#include <mach/mach_traps.h>
+
+#include <atm/atm_types.h>
+
+#include <darwintest.h>
+
+
+static mach_port_t get_atm_voucher(void)
+{
+ mach_voucher_attr_recipe_data_t r = {
+ .key = MACH_VOUCHER_ATTR_KEY_ATM,
+ .command = MACH_VOUCHER_ATTR_ATM_CREATE
+ };
+ mach_port_t port = MACH_PORT_NULL;
+ kern_return_t kr = host_create_mach_voucher(mach_host_self(),
+ (mach_voucher_attr_raw_recipe_array_t)&r,
+ sizeof(r), &port);
+ T_ASSERT_MACH_SUCCESS(kr, "Create ATM voucher: 0x%x", (unsigned int)port);
+
+ return port;
+}
+
+
+T_DECL(voucher_extract_attr_recipe, "voucher_extract_attr_recipe")
+{
+ kern_return_t kr;
+ mach_vm_size_t alloc_sz;
+ mach_port_t port;
+ mach_vm_address_t alloc_addr;
+
+ /* map at least a page of memory at some arbitrary location */
+ alloc_sz = (mach_vm_size_t)round_page(MACH_VOUCHER_TRAP_STACK_LIMIT + 1);
+
+ /*
+ * We could theoretically ask for a fixed location, but this is more
+ * reliable, and we're not actually trying to exploit anything - a
+ * kernel panic on failure should suffice :-)
+ */
+ alloc_addr = (mach_vm_address_t)round_page(MACH_VOUCHER_ATTR_MAX_RAW_RECIPE_ARRAY_SIZE + 1);
+ kr = mach_vm_allocate(mach_task_self(), &alloc_addr,
+ alloc_sz, VM_FLAGS_ANYWHERE);
+
+ /*
+ * Make sure that the address of the allocation is larger than the
+ * maximum recipe size: this will test for the bug that was fixed in
+ * <rdar://problem/29379175>.
+ */
+ T_ASSERT_GT_ULLONG((uint64_t)alloc_addr,
+ (uint64_t)MACH_VOUCHER_ATTR_MAX_RAW_RECIPE_ARRAY_SIZE,
+ "Recipe addr (%llu bytes): 0x%llx > max recipe sz: %llu",
+ (uint64_t)alloc_sz, (uint64_t)alloc_addr,
+ (uint64_t)MACH_VOUCHER_ATTR_MAX_RAW_RECIPE_ARRAY_SIZE);
+
+ /* make the allocation look like a pointer to an int */
+ mach_msg_type_number_t *recipe_size;
+ recipe_size = (mach_msg_type_number_t *)((uintptr_t)alloc_addr);
+ bzero(recipe_size, (unsigned long)alloc_sz);
+ if (alloc_sz > MACH_VOUCHER_ATTR_MAX_RAW_RECIPE_ARRAY_SIZE)
+ *recipe_size = MACH_VOUCHER_ATTR_MAX_RAW_RECIPE_ARRAY_SIZE;
+ else
+ *recipe_size = (mach_msg_type_number_t)alloc_sz;
+
+ /* recipe buffer on the heap: memset it so panics show up loudly */
+ size_t size = (size_t)(10 * 1024 * 1024);
+ void *recipe = malloc(size);
+ memset(recipe, 0x41, size);
+
+ port = get_atm_voucher();
+
+ /*
+ * This should try to extract the ATM attribute using a buffer on the
+ * kernel heap (probably zone memory).
+ */
+ kr = mach_voucher_extract_attr_recipe_trap(port, MACH_VOUCHER_ATTR_KEY_ATM,
+ recipe, recipe_size);
+ T_ASSERT_MACH_SUCCESS(kr, "Extract attribute data with recipe: heap");
+
+ /* reset the recipe memory */
+ memset(recipe, 0x41, size);
+ /* reduce the size to get an allocation on the kernel stack */
+ *recipe_size = MACH_VOUCHER_TRAP_STACK_LIMIT - 1;
+
+ /*
+ * This should try to extract the ATM attribute using a buffer on the
+ * kernel stack.
+ */
+ kr = mach_voucher_extract_attr_recipe_trap(port, MACH_VOUCHER_ATTR_KEY_ATM,
+ recipe, recipe_size);
+ T_ASSERT_MACH_SUCCESS(kr, "Extract attribute data with recipe: stack");
+
+ /* cleanup */
+
+ free(recipe);
+ kr = mach_vm_deallocate(mach_task_self(), alloc_addr, alloc_sz);
+ T_ASSERT_MACH_SUCCESS(kr, "Deallocate recipe buffers");
+}