From c7778a27cbdf7b39bf5be0ce851192d918f255a3 Mon Sep 17 00:00:00 2001 From: Bryan Bernhart Date: Thu, 11 Jun 2020 18:58:26 +0000 Subject: [PATCH] Prevent size overflow for sub-allocation. D3D/VK driver may return a size larger than requested and could cause PowerOfTwo() to overflow. This change adds a check to ensure the size is within the limit before attempting sub-allocation. BUG=dawn:27 Change-Id: I2b2ce727abff953642a69b65c8f30be8e53e562d Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/23060 Reviewed-by: Austin Eng Reviewed-by: Corentin Wallez Commit-Queue: Bryan Bernhart --- src/dawn_native/BuddyMemoryAllocator.cpp | 5 +++++ src/tests/unittests/BuddyMemoryAllocatorTests.cpp | 11 +++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/dawn_native/BuddyMemoryAllocator.cpp b/src/dawn_native/BuddyMemoryAllocator.cpp index 6a428d97a4..eb7320c56a 100644 --- a/src/dawn_native/BuddyMemoryAllocator.cpp +++ b/src/dawn_native/BuddyMemoryAllocator.cpp @@ -45,6 +45,11 @@ namespace dawn_native { return std::move(invalidAllocation); } + // Check the unaligned size to avoid overflowing NextPowerOfTwo. + if (allocationSize > mMemoryBlockSize) { + return std::move(invalidAllocation); + } + // Round allocation size to nearest power-of-two. allocationSize = NextPowerOfTwo(allocationSize); diff --git a/src/tests/unittests/BuddyMemoryAllocatorTests.cpp b/src/tests/unittests/BuddyMemoryAllocatorTests.cpp index f72230894c..a2d60eaf16 100644 --- a/src/tests/unittests/BuddyMemoryAllocatorTests.cpp +++ b/src/tests/unittests/BuddyMemoryAllocatorTests.cpp @@ -345,3 +345,14 @@ TEST(BuddyMemoryAllocatorTests, VariousSizeSameAlignment) { ASSERT_EQ(allocator.ComputeTotalNumOfHeapsForTesting(), 3u); } + +// Verify allocating a very large resource does not overflow. +TEST(BuddyMemoryAllocatorTests, AllocationOverflow) { + constexpr uint64_t heapSize = 128; + constexpr uint64_t maxBlockSize = 512; + DummyBuddyResourceAllocator allocator(maxBlockSize, heapSize); + + constexpr uint64_t largeBlock = (1ull << 63) + 1; + ResourceMemoryAllocation invalidAllocation = allocator.Allocate(largeBlock); + ASSERT_EQ(invalidAllocation.GetInfo().mMethod, AllocationMethod::kInvalid); +} \ No newline at end of file