]> git.saurik.com Git - apple/xnu.git/commitdiff
xnu-3248.30.4.tar.gz os-x-10113 v3248.30.4
authorApple <opensource@apple.com>
Thu, 25 Feb 2016 22:12:46 +0000 (22:12 +0000)
committerApple <opensource@apple.com>
Thu, 25 Feb 2016 22:12:46 +0000 (22:12 +0000)
bsd/kern/kern_descrip.c
bsd/sys/priv.h
config/MasterVersion
iokit/IOKit/IOUserClient.h
iokit/Kernel/IOBufferMemoryDescriptor.cpp
iokit/Kernel/IOMemoryDescriptor.cpp
iokit/Kernel/IOUserClient.cpp
libkern/libkern/Makefile

index df33970cada3a8e90028e65904fd136bd94dbcc7..62a9d94f730065bccdf78dd1b77d895ad243f45d 100644 (file)
@@ -81,6 +81,7 @@
 #include <sys/kauth.h>
 #include <sys/file_internal.h>
 #include <sys/guarded.h>
+#include <sys/priv.h>
 #include <sys/socket.h>
 #include <sys/socketvar.h>
 #include <sys/stat.h>
@@ -2018,7 +2019,11 @@ fcntl_nocancel(proc_t p, struct fcntl_nocancel_args *uap, int32_t *retval)
                struct vnode *dst_vp = NULLVP;
                /* We need to grab the 2nd FD out of the argments before moving on. */
                int fd2 = CAST_DOWN_EXPLICIT(int32_t, uap->arg);
-               
+
+               error = priv_check_cred(kauth_cred_get(), PRIV_VFS_MOVE_DATA_EXTENTS, 0);
+               if (error)
+                       goto out;
+
                if (fp->f_type != DTYPE_VNODE) {
                        error = EBADF;
                        goto out;
index ff38da81d10db0ea64d851fbf09de3ae638764de..fe42c655d3824a2034521925d98c0c9601207a01 100644 (file)
 /*
  * VFS privileges
  */
-#define PRIV_VFS_OPEN_BY_ID    14000   /*Allow calling openbyid_np()*/
+#define PRIV_VFS_OPEN_BY_ID            14000   /* Allow calling openbyid_np() */
+#define PRIV_VFS_MOVE_DATA_EXTENTS     14001   /* Allow F_MOVEDATAEXTENTS fcntl */
 
 #ifdef KERNEL
 /*
index a378f284b59cbe5fc1484d5d321b11fd73262549..6e5b5944bdb5eb8452c37f2a8d36b25f8ee6b35e 100644 (file)
@@ -1,4 +1,4 @@
-15.2.0
+15.3.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 6286b853584802eec8688259c682ed2d8c712ae7..06a9931dbe750d178688c2833ea19114fbc28135 100644 (file)
@@ -207,7 +207,8 @@ private:
 #endif
     OSSet * mappings;
     UInt8   sharedInstance;
-    UInt8   __reservedA[3];
+    UInt8   closed;
+    UInt8   __reservedA[2];
     void  * __reserved[7];
 
 public:
index 9f190260568723c5ebda960eb7401c2a3521c0e8..046274c5945f768b2e6a3e6baff6ed77714b12fc 100644 (file)
@@ -554,6 +554,7 @@ vm_size_t IOBufferMemoryDescriptor::getCapacity() const
 void IOBufferMemoryDescriptor::setLength(vm_size_t length)
 {
     assert(length <= _capacity);
+    if (length > _capacity) return;
 
     _length = length;
     _ranges.v64->length = length;
index 4bd9659e79e523b4793c713f88f7e8788b5ec963..f61b0f9d60e8e29ff3cf9cfb1fd6252c9c9aca14 100644 (file)
@@ -1571,19 +1571,18 @@ IOGeneralMemoryDescriptor::initWithOptions(void *       buffers,
 
        // Find starting address within the vector of ranges
        Ranges vec = _ranges;
-       UInt32 length = 0;
-       UInt32 pages = 0;
-       for (unsigned ind = 0; ind < count;  ind++) {
+       mach_vm_size_t totalLength = 0;
+       unsigned int ind, pages = 0;
+       for (ind = 0; ind < count; ind++) {
            mach_vm_address_t addr;
            mach_vm_size_t len;
 
            // addr & len are returned by this function
            getAddrLenForInd(addr, len, type, vec, ind);
+           if ((addr + len + PAGE_MASK) < addr) break;                 /* overflow */
            pages += (atop_64(addr + len + PAGE_MASK) - atop_64(addr));
-           len += length;
-           assert(len >= length);      // Check for 32 bit wrap around
-           length = len;
-
+           totalLength += len;
+           if (totalLength < len) break;                               /* overflow */
            if ((kIOMemoryTypePhysical == type) || (kIOMemoryTypePhysical64 == type))
            {
                ppnum_t highPage = atop_64(addr + len - 1);
@@ -1591,7 +1590,10 @@ IOGeneralMemoryDescriptor::initWithOptions(void *        buffers,
                    _highestPage = highPage;
            }
        } 
-       _length      = length;
+       if ((ind < count)
+        || (totalLength != ((IOByteCount) totalLength))) return (false); /* overflow */
+
+       _length      = totalLength;
        _pages       = pages;
        _rangesCount = count;
 
@@ -1601,7 +1603,8 @@ IOGeneralMemoryDescriptor::initWithOptions(void * buffers,
             _wireCount++;      // Physical MDs are, by definition, wired
         else { /* kIOMemoryTypeVirtual | kIOMemoryTypeVirtual64 | kIOMemoryTypeUIO */
             ioGMDData *dataP;
-            unsigned dataSize = computeDataSize(_pages, /* upls */ count * 2);
+            mach_vm_size_t dataSize = computeDataSize(_pages, /* upls */ count * 2);
+           if (dataSize != ((unsigned) dataSize)) return false;         /* overflow */
 
             if (!initMemoryEntries(dataSize, mapper)) return false;
             dataP = getDataP(_memoryEntries);
@@ -1758,7 +1761,8 @@ IOByteCount IOMemoryDescriptor::readBytes
     // Assert that this entire I/O is withing the available range
     assert(offset <= _length);
     assert(offset + length <= _length);
-    if (offset >= _length) {
+    if ((offset >= _length)
+     || ((offset + length) > _length)) {
         return 0;
     }
 
@@ -1807,7 +1811,9 @@ IOByteCount IOMemoryDescriptor::writeBytes
 
     assert( !(kIOMemoryPreparedReadOnly & _flags) );
 
-    if ( (kIOMemoryPreparedReadOnly & _flags) || offset >= _length) {
+    if ( (kIOMemoryPreparedReadOnly & _flags)
+     || (offset >= _length)
+     || ((offset + length) > _length)) {
         return 0;
     }
 
index 8c628ddf1f83c7ee367a4c792fc1793ee69de629..06e4a612c2220a43946e1820b11265be1e5ef6f9 100644 (file)
@@ -1299,7 +1299,14 @@ void IOUserClient::free()
 
 IOReturn IOUserClient::clientDied( void )
 {
-    return( clientClose());
+    IOReturn ret = kIOReturnNotReady;
+
+    if (sharedInstance || OSCompareAndSwap8(0, 1, &closed)) 
+    {
+       ret = clientClose();
+    }
+
+    return (ret);
 }
 
 IOReturn IOUserClient::clientClose( void )
@@ -1930,6 +1937,8 @@ kern_return_t is_io_service_get_matching_services_ool(
 
     if( KERN_SUCCESS == kr) {
         // must return success after vm_map_copyout() succeeds
+        // and mig will copy out objects on success
+        *existing = 0;
        *result = internal_io_service_get_matching_services(master_port,
                        (const char *) data, matchingCnt, existing);
        vm_deallocate( kernel_map, data, matchingCnt );
@@ -2002,6 +2011,8 @@ kern_return_t is_io_service_get_matching_service_ool(
 
     if( KERN_SUCCESS == kr) {
         // must return success after vm_map_copyout() succeeds
+        // and mig will copy out objects on success
+        *service = 0;
        *result = internal_io_service_get_matching_service(master_port,
                        (const char *) data, matchingCnt, service );
        vm_deallocate( kernel_map, data, matchingCnt );
@@ -2188,6 +2199,8 @@ static kern_return_t internal_io_service_add_notification_ool(
 
     if( KERN_SUCCESS == kr) {
         // must return success after vm_map_copyout() succeeds
+        // and mig will copy out objects on success
+        *notification = 0;
        *result = internal_io_service_add_notification( master_port, notification_type,
                        (char *) data, matchingCnt, wake_port, reference, referenceSize, client64, notification );
        vm_deallocate( kernel_map, data, matchingCnt );
@@ -3257,6 +3270,7 @@ kern_return_t is_io_service_open_extended(
                break;
            }
            client->sharedInstance = (0 != client->getProperty(kIOUserClientSharedInstanceKey));
+           client->closed = false;
            OSString * creatorName = IOCopyLogNameForPID(proc_selfpid());
            if (creatorName)
            {
@@ -3285,7 +3299,16 @@ kern_return_t is_io_service_close(
     CHECK( IOUserClient, connection, client );
 
     IOStatisticsClientCall();
-    client->clientClose();
+
+    if (client->sharedInstance || OSCompareAndSwap8(0, 1, &client->closed)) 
+    {
+       client->clientClose();
+    }
+    else
+    {
+       IOLog("ignored is_io_service_close(0x%qx,%s)\n", 
+               client->getRegistryEntryID(), client->getName());
+    }
 
     return( kIOReturnSuccess );
 }
index fb623933c21675e9ef1af2f7b6b28c7b02812f55..db475229bf0bec868f5dae5d5c721be33f22d906 100644 (file)
@@ -75,11 +75,7 @@ EXPORT_MI_LIST = \
        kxld_types.h           \
        stack_protector.h
 
-INSTALL_KF_MI_LCL_LIST +=          \
-       section_keywords.h
 
-EXPORT_MI_LIST +=          \
-       section_keywords.h
 
 EXPORT_MI_GEN_LIST = version.h