]> git.saurik.com Git - apple/xnu.git/blobdiff - iokit/Kernel/IOMemoryDescriptor.cpp
xnu-3248.60.10.tar.gz
[apple/xnu.git] / iokit / Kernel / IOMemoryDescriptor.cpp
index 4bd9659e79e523b4793c713f88f7e8788b5ec963..947461eaf531b84bb2ea876d457fbe6ca47eb046 100644 (file)
@@ -672,8 +672,7 @@ IOMemoryDescriptorMapAlloc(vm_map_t map, void * _ref)
                                  (((ref->options & kIOMapAnywhere)
                                    ? VM_FLAGS_ANYWHERE
                                    : VM_FLAGS_FIXED)
                                  (((ref->options & kIOMapAnywhere)
                                    ? VM_FLAGS_ANYWHERE
                                    : VM_FLAGS_FIXED)
-                                  | VM_MAKE_TAG(ref->tag)
-                                  | VM_FLAGS_IOKIT_ACCT), /* iokit accounting */
+                                  | VM_MAKE_TAG(ref->tag)),
                                  IPC_PORT_NULL,
                                  (memory_object_offset_t) 0,
                                  false, /* copy */
                                  IPC_PORT_NULL,
                                  (memory_object_offset_t) 0,
                                  false, /* copy */
@@ -1571,19 +1570,18 @@ IOGeneralMemoryDescriptor::initWithOptions(void *       buffers,
 
        // Find starting address within the vector of ranges
        Ranges vec = _ranges;
 
        // 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);
            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));
            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);
            if ((kIOMemoryTypePhysical == type) || (kIOMemoryTypePhysical64 == type))
            {
                ppnum_t highPage = atop_64(addr + len - 1);
@@ -1591,7 +1589,10 @@ IOGeneralMemoryDescriptor::initWithOptions(void *        buffers,
                    _highestPage = highPage;
            }
        } 
                    _highestPage = highPage;
            }
        } 
-       _length      = length;
+       if ((ind < count)
+        || (totalLength != ((IOByteCount) totalLength))) return (false); /* overflow */
+
+       _length      = totalLength;
        _pages       = pages;
        _rangesCount = count;
 
        _pages       = pages;
        _rangesCount = count;
 
@@ -1601,8 +1602,11 @@ IOGeneralMemoryDescriptor::initWithOptions(void *        buffers,
             _wireCount++;      // Physical MDs are, by definition, wired
         else { /* kIOMemoryTypeVirtual | kIOMemoryTypeVirtual64 | kIOMemoryTypeUIO */
             ioGMDData *dataP;
             _wireCount++;      // Physical MDs are, by definition, wired
         else { /* kIOMemoryTypeVirtual | kIOMemoryTypeVirtual64 | kIOMemoryTypeUIO */
             ioGMDData *dataP;
-            unsigned dataSize = computeDataSize(_pages, /* upls */ count * 2);
+            unsigned dataSize;
+
+            if (_pages > atop_64(max_mem)) return false;
 
 
+            dataSize = computeDataSize(_pages, /* upls */ count * 2);
             if (!initMemoryEntries(dataSize, mapper)) return false;
             dataP = getDataP(_memoryEntries);
             dataP->fPageCnt = _pages;
             if (!initMemoryEntries(dataSize, mapper)) return false;
             dataP = getDataP(_memoryEntries);
             dataP->fPageCnt = _pages;
@@ -1758,7 +1762,8 @@ IOByteCount IOMemoryDescriptor::readBytes
     // Assert that this entire I/O is withing the available range
     assert(offset <= _length);
     assert(offset + length <= _length);
     // 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;
     }
 
         return 0;
     }
 
@@ -1807,7 +1812,9 @@ IOByteCount IOMemoryDescriptor::writeBytes
 
     assert( !(kIOMemoryPreparedReadOnly & _flags) );
 
 
     assert( !(kIOMemoryPreparedReadOnly & _flags) );
 
-    if ( (kIOMemoryPreparedReadOnly & _flags) || offset >= _length) {
+    if ( (kIOMemoryPreparedReadOnly & _flags)
+     || (offset >= _length)
+     || ((offset + length) > _length)) {
         return 0;
     }
 
         return 0;
     }
 
@@ -2867,8 +2874,9 @@ IOReturn IOGeneralMemoryDescriptor::wireVirtual(IODirection forDirection)
            pageInfo = getPageList(dataP);
             upl_page_list_ptr_t baseInfo = &pageInfo[pageIndex];
 
            pageInfo = getPageList(dataP);
             upl_page_list_ptr_t baseInfo = &pageInfo[pageIndex];
 
-            upl_size_t ioplSize = round_page(numBytes);
-            unsigned int numPageInfo = atop_32(ioplSize);
+            mach_vm_size_t _ioplSize    = round_page(numBytes);
+            upl_size_t             ioplSize    = (_ioplSize <= MAX_UPL_SIZE_BYTES) ? _ioplSize : MAX_UPL_SIZE_BYTES;
+            unsigned int    numPageInfo = atop_32(ioplSize);
 
            if ((theMap == kernel_map) 
             && (kernelStart >= io_kernel_static_start) 
 
            if ((theMap == kernel_map) 
             && (kernelStart >= io_kernel_static_start) 
@@ -2882,7 +2890,7 @@ IOReturn IOGeneralMemoryDescriptor::wireVirtual(IODirection forDirection)
                                                &highPage);
            }
            else if (_memRef) {
                                                &highPage);
            }
            else if (_memRef) {
-               memory_object_offset_t entryOffset;
+                memory_object_offset_t entryOffset;
 
                 entryOffset = mdOffset;
                 entryOffset = (entryOffset - iopl.fPageOffset - memRefEntry->offset);
 
                 entryOffset = mdOffset;
                 entryOffset = (entryOffset - iopl.fPageOffset - memRefEntry->offset);
@@ -2911,10 +2919,11 @@ IOReturn IOGeneralMemoryDescriptor::wireVirtual(IODirection forDirection)
                                                &ioplFlags);
            }
 
                                                &ioplFlags);
            }
 
-            assert(ioplSize);
             if (error != KERN_SUCCESS)
                 goto abortExit;
 
             if (error != KERN_SUCCESS)
                 goto abortExit;
 
+            assert(ioplSize);
+
            if (iopl.fIOPL)
                highPage = upl_get_highest_page(iopl.fIOPL);
            if (highPage > highestPage)
            if (iopl.fIOPL)
                highPage = upl_get_highest_page(iopl.fIOPL);
            if (highPage > highestPage)