]> git.saurik.com Git - apple/xnu.git/commitdiff
xnu-3789.41.3.tar.gz macos-10123 v3789.41.3
authorApple <opensource@apple.com>
Thu, 19 Jan 2017 19:27:37 +0000 (19:27 +0000)
committerApple <opensource@apple.com>
Thu, 19 Jan 2017 19:27:37 +0000 (19:27 +0000)
config/MasterVersion
iokit/Kernel/IOPMrootDomain.cpp
iokit/Kernel/IOService.cpp
osfmk/ipc/mach_kernelrpc.c
osfmk/kern/ipc_host.c
tools/tests/darwintests/voucher_traps.c [new file with mode: 0644]

index 5c5f71e02996a67b07fbe4f654cdd364166f23cc..dec53ed767cc3cff32331d1895f9884c97cd42ce 100644 (file)
@@ -1,4 +1,4 @@
-16.3.0
+16.4.0
 
 # The first line of this file contains the master version number for the kernel.
 # All other instances of the kernel version in xnu are derived from this file.
index e967cb33f2e74e54616b1e7e41ab131572ff0ca8..f2015f3868faf2a60cfed296ca262be3a16b004c 100644 (file)
@@ -5021,6 +5021,9 @@ void IOPMrootDomain::handleOurPowerChangeStart(
             _systemMessageClientMask &= ~kSystemMessageClientLegacyApp;
         if ((_highestCapability & kIOPMSystemCapabilityGraphics) == 0)
             _systemMessageClientMask &= ~kSystemMessageClientKernel;
+#if HIBERNATION
+        gIOHibernateState = 0;
+#endif
 
         // Record the reason for dark wake back to sleep
         // System may not have ever achieved full wake
index 440b5c589e6ae26ab33a18098a2e85e88ab8cc31..57323e108dd36d33c635ad574e13c1df3f78d6b1 100644 (file)
@@ -4984,6 +4984,8 @@ void IOService::updateConsoleUsers(OSArray * consoleUsers, IOMessage systemMessa
     bool              publish;
     OSDictionary *    user;
     static IOMessage  sSystemPower;
+    clock_sec_t       now = 0;
+    clock_usec_t      microsecs;
 
     regEntry = IORegistryEntry::getRegistryRoot();
 
@@ -5040,6 +5042,9 @@ void IOService::updateConsoleUsers(OSArray * consoleUsers, IOMessage systemMessa
        }
 #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;
     }
@@ -5058,9 +5063,6 @@ void IOService::updateConsoleUsers(OSArray * consoleUsers, IOMessage systemMessa
 #endif /* HIBERNATION */
     else if (gIOConsoleLockTime)
     {
-       clock_sec_t  now;
-       clock_usec_t microsecs;
-
        clock_get_calendar_microtime(&now, &microsecs);
        if (gIOConsoleLockTime > now)
        {
@@ -5092,6 +5094,9 @@ void IOService::updateConsoleUsers(OSArray * consoleUsers, IOMessage systemMessa
        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 */
 
index 1b50efbb70a949df9be73959ed61dc039732fc04..b24f4d5dd2ea3947251ab2ad65ae32d0bd596e6c 100644 (file)
@@ -450,7 +450,7 @@ mach_voucher_extract_attr_recipe_trap(struct mach_voucher_extract_attr_recipe_ar
        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 */
@@ -466,14 +466,14 @@ mach_voucher_extract_attr_recipe_trap(struct mach_voucher_extract_attr_recipe_ar
                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;
                }
@@ -484,7 +484,7 @@ mach_voucher_extract_attr_recipe_trap(struct mach_voucher_extract_attr_recipe_ar
 
                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));
index b68bd0a0902888f5410960603055d742c6f2e94b..8e61a5dfea38d62650e1232f17f839dd655e4a09 100644 (file)
@@ -167,10 +167,13 @@ mach_port_name_t
 host_self_trap(
        __unused struct host_self_trap_args *args)
 {
+       task_t self = current_task();
        ipc_port_t sright;
        mach_port_name_t name;
 
-       sright = ipc_port_copy_send(current_task()->itk_host);
+       itk_lock(self);
+       sright = ipc_port_copy_send(self->itk_host);
+       itk_unlock(self);
        name = ipc_port_copyout_send(sright, current_space());
        return name;
 }
diff --git a/tools/tests/darwintests/voucher_traps.c b/tools/tests/darwintests/voucher_traps.c
new file mode 100644 (file)
index 0000000..f3e5a0a
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * 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");
+}