Guard against some arithmetic overflows
Fixes locations that explicitly have TODOs about
checking for overflow. Also fixup other locations found while
searching the code for arithmetic operations.
Fixes: dawn:830
Change-Id: I4ef6b97a9cde14439e573a1da8d569ab985efc53
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/55605
Reviewed-by: Jiawei Shao <jiawei.shao@intel.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Austin Eng <enga@chromium.org>
diff --git a/src/dawn_native/RenderEncoderBase.cpp b/src/dawn_native/RenderEncoderBase.cpp
index 2081a91..c586aaa 100644
--- a/src/dawn_native/RenderEncoderBase.cpp
+++ b/src/dawn_native/RenderEncoderBase.cpp
@@ -127,7 +127,7 @@
}
if (indirectOffset >= indirectBuffer->GetSize() ||
- indirectOffset + kDrawIndirectSize > indirectBuffer->GetSize()) {
+ kDrawIndirectSize > indirectBuffer->GetSize() - indirectOffset) {
return DAWN_VALIDATION_ERROR("Indirect offset out of bounds");
}
}
@@ -165,7 +165,7 @@
}
if ((indirectOffset >= indirectBuffer->GetSize() ||
- indirectOffset + kDrawIndexedIndirectSize > indirectBuffer->GetSize())) {
+ kDrawIndexedIndirectSize > indirectBuffer->GetSize() - indirectOffset)) {
return DAWN_VALIDATION_ERROR("Indirect offset out of bounds");
}
}
diff --git a/src/dawn_native/Texture.cpp b/src/dawn_native/Texture.cpp
index 14a14a9..293e0a8 100644
--- a/src/dawn_native/Texture.cpp
+++ b/src/dawn_native/Texture.cpp
@@ -592,8 +592,10 @@
// Compressed Textures will have paddings if their width or height is not a multiple of
// 4 at non-zero mipmap levels.
- if (mFormat.isCompressed) {
- // TODO(crbug.com/dawn/830): check if there are any overflows.
+ if (mFormat.isCompressed && level != 0) {
+ // If |level| is non-zero, then each dimension of |extent| is at most half of
+ // the max texture dimension. Computations here which add the block width/height
+ // to the extent cannot overflow.
const TexelBlockInfo& blockInfo = mFormat.GetAspectInfo(wgpu::TextureAspect::All).block;
extent.width = (extent.width + blockInfo.width - 1) / blockInfo.width * blockInfo.width;
extent.height =
@@ -607,10 +609,12 @@
const Origin3D& origin,
const Extent3D& extent) const {
const Extent3D virtualSizeAtLevel = GetMipLevelVirtualSize(level);
- uint32_t clampedCopyExtentWidth = (origin.x + extent.width > virtualSizeAtLevel.width)
+ ASSERT(origin.x <= virtualSizeAtLevel.width);
+ ASSERT(origin.y <= virtualSizeAtLevel.height);
+ uint32_t clampedCopyExtentWidth = (extent.width > virtualSizeAtLevel.width - origin.x)
? (virtualSizeAtLevel.width - origin.x)
: extent.width;
- uint32_t clampedCopyExtentHeight = (origin.y + extent.height > virtualSizeAtLevel.height)
+ uint32_t clampedCopyExtentHeight = (extent.height > virtualSizeAtLevel.height - origin.y)
? (virtualSizeAtLevel.height - origin.y)
: extent.height;
return {clampedCopyExtentWidth, clampedCopyExtentHeight, extent.depthOrArrayLayers};
diff --git a/src/dawn_native/null/DeviceNull.cpp b/src/dawn_native/null/DeviceNull.cpp
index 7024c7a..240df53 100644
--- a/src/dawn_native/null/DeviceNull.cpp
+++ b/src/dawn_native/null/DeviceNull.cpp
@@ -205,7 +205,7 @@
MaybeError Device::IncrementMemoryUsage(uint64_t bytes) {
static_assert(kMaxMemoryUsage <= std::numeric_limits<size_t>::max(), "");
- if (bytes > kMaxMemoryUsage || mMemoryUsage + bytes > kMaxMemoryUsage) {
+ if (bytes > kMaxMemoryUsage || mMemoryUsage > kMaxMemoryUsage - bytes) {
return DAWN_OUT_OF_MEMORY_ERROR("Out of memory.");
}
mMemoryUsage += bytes;
diff --git a/src/dawn_native/opengl/CommandBufferGL.cpp b/src/dawn_native/opengl/CommandBufferGL.cpp
index b4e98fe..e97ffb6 100644
--- a/src/dawn_native/opengl/CommandBufferGL.cpp
+++ b/src/dawn_native/opengl/CommandBufferGL.cpp
@@ -458,11 +458,13 @@
Extent3D validTextureCopyExtent = copySize;
const TextureBase* texture = textureCopy.texture.Get();
Extent3D virtualSizeAtLevel = texture->GetMipLevelVirtualSize(textureCopy.mipLevel);
- if (textureCopy.origin.x + copySize.width > virtualSizeAtLevel.width) {
+ ASSERT(textureCopy.origin.x <= virtualSizeAtLevel.width);
+ ASSERT(textureCopy.origin.y <= virtualSizeAtLevel.height);
+ if (copySize.width > virtualSizeAtLevel.width - textureCopy.origin.x) {
ASSERT(texture->GetFormat().isCompressed);
validTextureCopyExtent.width = virtualSizeAtLevel.width - textureCopy.origin.x;
}
- if (textureCopy.origin.y + copySize.height > virtualSizeAtLevel.height) {
+ if (copySize.height > virtualSizeAtLevel.height - textureCopy.origin.y) {
ASSERT(texture->GetFormat().isCompressed);
validTextureCopyExtent.height = virtualSizeAtLevel.height - textureCopy.origin.y;
}
diff --git a/src/dawn_native/vulkan/UtilsVulkan.cpp b/src/dawn_native/vulkan/UtilsVulkan.cpp
index 7375377..c6952d4 100644
--- a/src/dawn_native/vulkan/UtilsVulkan.cpp
+++ b/src/dawn_native/vulkan/UtilsVulkan.cpp
@@ -83,11 +83,13 @@
Extent3D validTextureCopyExtent = copySize;
const TextureBase* texture = textureCopy.texture.Get();
Extent3D virtualSizeAtLevel = texture->GetMipLevelVirtualSize(textureCopy.mipLevel);
- if (textureCopy.origin.x + copySize.width > virtualSizeAtLevel.width) {
+ ASSERT(textureCopy.origin.x <= virtualSizeAtLevel.width);
+ ASSERT(textureCopy.origin.y <= virtualSizeAtLevel.height);
+ if (copySize.width > virtualSizeAtLevel.width - textureCopy.origin.x) {
ASSERT(texture->GetFormat().isCompressed);
validTextureCopyExtent.width = virtualSizeAtLevel.width - textureCopy.origin.x;
}
- if (textureCopy.origin.y + copySize.height > virtualSizeAtLevel.height) {
+ if (copySize.height > virtualSizeAtLevel.height - textureCopy.origin.y) {
ASSERT(texture->GetFormat().isCompressed);
validTextureCopyExtent.height = virtualSizeAtLevel.height - textureCopy.origin.y;
}