Commit ff7f1003 by Nicolas Capens Committed by Nicolas Capens

Validate allocation size in PoolAllocator

BUG=chromium:8662046 Change-Id: I3f8371b586b3a497c871a56bdf3c2b489e383b7d Reviewed-on: https://swiftshader-review.googlesource.com/1360Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Tested-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 42a584d5
...@@ -227,24 +227,27 @@ void TPoolAllocator::popAll() ...@@ -227,24 +227,27 @@ void TPoolAllocator::popAll()
void* TPoolAllocator::allocate(size_t numBytes) void* TPoolAllocator::allocate(size_t numBytes)
{ {
//
// Just keep some interesting statistics.
//
++numCalls;
totalBytes += numBytes;
// If we are using guard blocks, all allocations are bracketed by // If we are using guard blocks, all allocations are bracketed by
// them: [guardblock][allocation][guardblock]. numBytes is how // them: [guardblock][allocation][guardblock]. numBytes is how
// much memory the caller asked for. allocationSize is the total // much memory the caller asked for. allocationSize is the total
// size including guard blocks. In release build, // size including guard blocks. In release build,
// guardBlockSize=0 and this all gets optimized away. // guardBlockSize=0 and this all gets optimized away.
size_t allocationSize = TAllocation::allocationSize(numBytes); size_t allocationSize = TAllocation::allocationSize(numBytes);
// Detect integer overflow.
// if (allocationSize < numBytes)
// Just keep some interesting statistics. return 0;
//
++numCalls;
totalBytes += numBytes;
// //
// Do the allocation, most likely case first, for efficiency. // Do the allocation, most likely case first, for efficiency.
// This step could be moved to be inline sometime. // This step could be moved to be inline sometime.
// //
if (currentPageOffset + allocationSize <= pageSize) { if (allocationSize <= pageSize - currentPageOffset) {
// //
// Safe to allocate from currentPageOffset. // Safe to allocate from currentPageOffset.
// //
...@@ -255,12 +258,16 @@ void* TPoolAllocator::allocate(size_t numBytes) ...@@ -255,12 +258,16 @@ void* TPoolAllocator::allocate(size_t numBytes)
return initializeAllocation(inUseList, memory, numBytes); 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. // Do a multi-page allocation. Don't mix these with the others.
// The OS is efficient and allocating and free-ing multiple pages. // The OS is efficient and allocating and free-ing multiple pages.
// //
size_t numBytesToAlloc = allocationSize + headerSkip; size_t numBytesToAlloc = allocationSize + headerSkip;
// Detect integer overflow.
if (numBytesToAlloc < allocationSize)
return 0;
tHeader* memory = reinterpret_cast<tHeader*>(::new char[numBytesToAlloc]); tHeader* memory = reinterpret_cast<tHeader*>(::new char[numBytesToAlloc]);
if (memory == 0) if (memory == 0)
return 0; return 0;
......
...@@ -227,24 +227,27 @@ void TPoolAllocator::popAll() ...@@ -227,24 +227,27 @@ void TPoolAllocator::popAll()
void* TPoolAllocator::allocate(size_t numBytes) void* TPoolAllocator::allocate(size_t numBytes)
{ {
//
// Just keep some interesting statistics.
//
++numCalls;
totalBytes += numBytes;
// If we are using guard blocks, all allocations are bracketed by // If we are using guard blocks, all allocations are bracketed by
// them: [guardblock][allocation][guardblock]. numBytes is how // them: [guardblock][allocation][guardblock]. numBytes is how
// much memory the caller asked for. allocationSize is the total // much memory the caller asked for. allocationSize is the total
// size including guard blocks. In release build, // size including guard blocks. In release build,
// guardBlockSize=0 and this all gets optimized away. // guardBlockSize=0 and this all gets optimized away.
size_t allocationSize = TAllocation::allocationSize(numBytes); size_t allocationSize = TAllocation::allocationSize(numBytes);
// Detect integer overflow.
// if (allocationSize < numBytes)
// Just keep some interesting statistics. return 0;
//
++numCalls;
totalBytes += numBytes;
// //
// Do the allocation, most likely case first, for efficiency. // Do the allocation, most likely case first, for efficiency.
// This step could be moved to be inline sometime. // This step could be moved to be inline sometime.
// //
if (currentPageOffset + allocationSize <= pageSize) { if (allocationSize <= pageSize - currentPageOffset) {
// //
// Safe to allocate from currentPageOffset. // Safe to allocate from currentPageOffset.
// //
...@@ -255,12 +258,16 @@ void* TPoolAllocator::allocate(size_t numBytes) ...@@ -255,12 +258,16 @@ void* TPoolAllocator::allocate(size_t numBytes)
return initializeAllocation(inUseList, memory, numBytes); 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. // Do a multi-page allocation. Don't mix these with the others.
// The OS is efficient and allocating and free-ing multiple pages. // The OS is efficient and allocating and free-ing multiple pages.
// //
size_t numBytesToAlloc = allocationSize + headerSkip; size_t numBytesToAlloc = allocationSize + headerSkip;
// Detect integer overflow.
if (numBytesToAlloc < allocationSize)
return 0;
tHeader* memory = reinterpret_cast<tHeader*>(::new char[numBytesToAlloc]); tHeader* memory = reinterpret_cast<tHeader*>(::new char[numBytesToAlloc]);
if (memory == 0) if (memory == 0)
return 0; return 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment