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>
This commit is contained in:
Austin Eng 2021-06-23 14:55:13 +00:00 committed by Dawn LUCI CQ
parent d5f44ce68c
commit 00c999acd5
5 changed files with 19 additions and 11 deletions

View File

@ -127,7 +127,7 @@ namespace dawn_native {
} }
if (indirectOffset >= indirectBuffer->GetSize() || if (indirectOffset >= indirectBuffer->GetSize() ||
indirectOffset + kDrawIndirectSize > indirectBuffer->GetSize()) { kDrawIndirectSize > indirectBuffer->GetSize() - indirectOffset) {
return DAWN_VALIDATION_ERROR("Indirect offset out of bounds"); return DAWN_VALIDATION_ERROR("Indirect offset out of bounds");
} }
} }
@ -165,7 +165,7 @@ namespace dawn_native {
} }
if ((indirectOffset >= indirectBuffer->GetSize() || if ((indirectOffset >= indirectBuffer->GetSize() ||
indirectOffset + kDrawIndexedIndirectSize > indirectBuffer->GetSize())) { kDrawIndexedIndirectSize > indirectBuffer->GetSize() - indirectOffset)) {
return DAWN_VALIDATION_ERROR("Indirect offset out of bounds"); return DAWN_VALIDATION_ERROR("Indirect offset out of bounds");
} }
} }

View File

@ -592,8 +592,10 @@ namespace dawn_native {
// Compressed Textures will have paddings if their width or height is not a multiple of // Compressed Textures will have paddings if their width or height is not a multiple of
// 4 at non-zero mipmap levels. // 4 at non-zero mipmap levels.
if (mFormat.isCompressed) { if (mFormat.isCompressed && level != 0) {
// TODO(crbug.com/dawn/830): check if there are any overflows. // 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; const TexelBlockInfo& blockInfo = mFormat.GetAspectInfo(wgpu::TextureAspect::All).block;
extent.width = (extent.width + blockInfo.width - 1) / blockInfo.width * blockInfo.width; extent.width = (extent.width + blockInfo.width - 1) / blockInfo.width * blockInfo.width;
extent.height = extent.height =
@ -607,10 +609,12 @@ namespace dawn_native {
const Origin3D& origin, const Origin3D& origin,
const Extent3D& extent) const { const Extent3D& extent) const {
const Extent3D virtualSizeAtLevel = GetMipLevelVirtualSize(level); 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) ? (virtualSizeAtLevel.width - origin.x)
: extent.width; : extent.width;
uint32_t clampedCopyExtentHeight = (origin.y + extent.height > virtualSizeAtLevel.height) uint32_t clampedCopyExtentHeight = (extent.height > virtualSizeAtLevel.height - origin.y)
? (virtualSizeAtLevel.height - origin.y) ? (virtualSizeAtLevel.height - origin.y)
: extent.height; : extent.height;
return {clampedCopyExtentWidth, clampedCopyExtentHeight, extent.depthOrArrayLayers}; return {clampedCopyExtentWidth, clampedCopyExtentHeight, extent.depthOrArrayLayers};

View File

@ -205,7 +205,7 @@ namespace dawn_native { namespace null {
MaybeError Device::IncrementMemoryUsage(uint64_t bytes) { MaybeError Device::IncrementMemoryUsage(uint64_t bytes) {
static_assert(kMaxMemoryUsage <= std::numeric_limits<size_t>::max(), ""); 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."); return DAWN_OUT_OF_MEMORY_ERROR("Out of memory.");
} }
mMemoryUsage += bytes; mMemoryUsage += bytes;

View File

@ -458,11 +458,13 @@ namespace dawn_native { namespace opengl {
Extent3D validTextureCopyExtent = copySize; Extent3D validTextureCopyExtent = copySize;
const TextureBase* texture = textureCopy.texture.Get(); const TextureBase* texture = textureCopy.texture.Get();
Extent3D virtualSizeAtLevel = texture->GetMipLevelVirtualSize(textureCopy.mipLevel); 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); ASSERT(texture->GetFormat().isCompressed);
validTextureCopyExtent.width = virtualSizeAtLevel.width - textureCopy.origin.x; 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); ASSERT(texture->GetFormat().isCompressed);
validTextureCopyExtent.height = virtualSizeAtLevel.height - textureCopy.origin.y; validTextureCopyExtent.height = virtualSizeAtLevel.height - textureCopy.origin.y;
} }

View File

@ -83,11 +83,13 @@ namespace dawn_native { namespace vulkan {
Extent3D validTextureCopyExtent = copySize; Extent3D validTextureCopyExtent = copySize;
const TextureBase* texture = textureCopy.texture.Get(); const TextureBase* texture = textureCopy.texture.Get();
Extent3D virtualSizeAtLevel = texture->GetMipLevelVirtualSize(textureCopy.mipLevel); 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); ASSERT(texture->GetFormat().isCompressed);
validTextureCopyExtent.width = virtualSizeAtLevel.width - textureCopy.origin.x; 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); ASSERT(texture->GetFormat().isCompressed);
validTextureCopyExtent.height = virtualSizeAtLevel.height - textureCopy.origin.y; validTextureCopyExtent.height = virtualSizeAtLevel.height - textureCopy.origin.y;
} }