Validate allocation size in PoolAllocator BUG=chromium:8662046 Change-Id: I3f8371b586b3a497c871a56bdf3c2b489e383b7d Reviewed-on: https://swiftshader-review.googlesource.com/1360 Reviewed-by: Nicolas Capens <nicolascapens@google.com> Tested-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/OpenGL/compiler/PoolAlloc.cpp b/src/OpenGL/compiler/PoolAlloc.cpp index c0ae1ec..9cdbeaa 100644 --- a/src/OpenGL/compiler/PoolAlloc.cpp +++ b/src/OpenGL/compiler/PoolAlloc.cpp
@@ -227,24 +227,27 @@ void* TPoolAllocator::allocate(size_t numBytes) { - // If we are using guard blocks, all allocations are bracketed by - // them: [guardblock][allocation][guardblock]. numBytes is how - // much memory the caller asked for. allocationSize is the total - // size including guard blocks. In release build, - // guardBlockSize=0 and this all gets optimized away. - size_t allocationSize = TAllocation::allocationSize(numBytes); - // // Just keep some interesting statistics. // ++numCalls; totalBytes += numBytes; + // If we are using guard blocks, all allocations are bracketed by + // them: [guardblock][allocation][guardblock]. numBytes is how + // much memory the caller asked for. allocationSize is the total + // size including guard blocks. In release build, + // guardBlockSize=0 and this all gets optimized away. + size_t allocationSize = TAllocation::allocationSize(numBytes); + // Detect integer overflow. + if (allocationSize < numBytes) + return 0; + // // Do the allocation, most likely case first, for efficiency. // This step could be moved to be inline sometime. // - if (currentPageOffset + allocationSize <= pageSize) { + if (allocationSize <= pageSize - currentPageOffset) { // // Safe to allocate from currentPageOffset. // @@ -255,12 +258,16 @@ return initializeAllocation(inUseList, memory, numBytes); } - if (allocationSize + headerSkip > pageSize) { + if (allocationSize > pageSize - headerSkip) { // // Do a multi-page allocation. Don't mix these with the others. // The OS is efficient and allocating and free-ing multiple pages. // size_t numBytesToAlloc = allocationSize + headerSkip; + // Detect integer overflow. + if (numBytesToAlloc < allocationSize) + return 0; + tHeader* memory = reinterpret_cast<tHeader*>(::new char[numBytesToAlloc]); if (memory == 0) return 0;
diff --git a/src/Radiance/compiler/PoolAlloc.cpp b/src/Radiance/compiler/PoolAlloc.cpp index c0ae1ec..9cdbeaa 100644 --- a/src/Radiance/compiler/PoolAlloc.cpp +++ b/src/Radiance/compiler/PoolAlloc.cpp
@@ -227,24 +227,27 @@ void* TPoolAllocator::allocate(size_t numBytes) { - // If we are using guard blocks, all allocations are bracketed by - // them: [guardblock][allocation][guardblock]. numBytes is how - // much memory the caller asked for. allocationSize is the total - // size including guard blocks. In release build, - // guardBlockSize=0 and this all gets optimized away. - size_t allocationSize = TAllocation::allocationSize(numBytes); - // // Just keep some interesting statistics. // ++numCalls; totalBytes += numBytes; + // If we are using guard blocks, all allocations are bracketed by + // them: [guardblock][allocation][guardblock]. numBytes is how + // much memory the caller asked for. allocationSize is the total + // size including guard blocks. In release build, + // guardBlockSize=0 and this all gets optimized away. + size_t allocationSize = TAllocation::allocationSize(numBytes); + // Detect integer overflow. + if (allocationSize < numBytes) + return 0; + // // Do the allocation, most likely case first, for efficiency. // This step could be moved to be inline sometime. // - if (currentPageOffset + allocationSize <= pageSize) { + if (allocationSize <= pageSize - currentPageOffset) { // // Safe to allocate from currentPageOffset. // @@ -255,12 +258,16 @@ return initializeAllocation(inUseList, memory, numBytes); } - if (allocationSize + headerSkip > pageSize) { + if (allocationSize > pageSize - headerSkip) { // // Do a multi-page allocation. Don't mix these with the others. // The OS is efficient and allocating and free-ing multiple pages. // size_t numBytesToAlloc = allocationSize + headerSkip; + // Detect integer overflow. + if (numBytesToAlloc < allocationSize) + return 0; + tHeader* memory = reinterpret_cast<tHeader*>(::new char[numBytesToAlloc]); if (memory == 0) return 0;