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 <enga@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Bryan Bernhart <bryan.bernhart@intel.com>
diff --git a/src/dawn_native/BuddyMemoryAllocator.cpp b/src/dawn_native/BuddyMemoryAllocator.cpp
index 6a428d9..eb7320c 100644
--- a/src/dawn_native/BuddyMemoryAllocator.cpp
+++ b/src/dawn_native/BuddyMemoryAllocator.cpp
@@ -45,6 +45,11 @@
             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 f722308..a2d60ea 100644
--- a/src/tests/unittests/BuddyMemoryAllocatorTests.cpp
+++ b/src/tests/unittests/BuddyMemoryAllocatorTests.cpp
@@ -345,3 +345,14 @@
 
     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