(((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 */
// 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);
_highestPage = highPage;
}
}
- _length = length;
+ if ((ind < count)
+ || (totalLength != ((IOByteCount) totalLength))) return (false); /* overflow */
+
+ _length = totalLength;
_pages = pages;
_rangesCount = count;
_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;
// 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;
}
assert( !(kIOMemoryPreparedReadOnly & _flags) );
- if ( (kIOMemoryPreparedReadOnly & _flags) || offset >= _length) {
+ if ( (kIOMemoryPreparedReadOnly & _flags)
+ || (offset >= _length)
+ || ((offset + length) > _length)) {
return 0;
}
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)
&highPage);
}
else if (_memRef) {
- memory_object_offset_t entryOffset;
+ memory_object_offset_t entryOffset;
entryOffset = mdOffset;
entryOffset = (entryOffset - iopl.fPageOffset - memRefEntry->offset);
&ioplFlags);
}
- assert(ioplSize);
if (error != KERN_SUCCESS)
goto abortExit;
+ assert(ioplSize);
+
if (iopl.fIOPL)
highPage = upl_get_highest_page(iopl.fIOPL);
if (highPage > highestPage)