chore: cherry-pick e8cb0e7aa32 from angle (#31236)

This commit is contained in:
Pedro Pontes
2021-10-04 08:47:52 +02:00
committed by GitHub
parent cf9ae70dbc
commit a7bbb47ec2
2 changed files with 113 additions and 0 deletions

View File

@@ -2,3 +2,4 @@ cherry-pick-d8cb996.patch
cherry-pick-1fb846c.patch
cherry-pick-72473550f6ff.patch
webgl_make_unsuccessful_links_fail_subsequent_draw_calls.patch
fix_integer_overflow_in_blocklayoutencoder.patch

View File

@@ -0,0 +1,112 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexis Hetu <sugoi@google.com>
Date: Wed, 15 Sep 2021 13:40:28 -0400
Subject: Fix integer overflow in BlockLayoutEncoder
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
BlockLayoutEncoder::mCurrentOffset's computation had the
possibility of causing integer overflows in multiple places,
so this CL adds CheckedNumeric variables in a number of
these occurrences in order to prevent integer overflows and
causing issues.
The issue in this case was an integer overflow causing the
code in ValidateTypeSizeLimitations.cpp to use an invalid
result from "layoutEncoder.getCurrentOffset()", which ended
up compiling a shader which would later cause an OOM error.
Bug: chromium:1248665
Change-Id: I688d669f21c6dc2957e43bdf91f8f8f08180a6f7
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3163356
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Kenneth Russell <kbr@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Alexis Hétu <sugoi@chromium.org>
(cherry picked from commit 158ef351fc8b827c201e056a8ddba50fd4235671)
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3194392
diff --git a/src/compiler/translator/blocklayout.cpp b/src/compiler/translator/blocklayout.cpp
index 0539923bc75f5b88228dcb387c8aba4c701edc1b..1e6b143a1e1ee9a127b71685febd36416a8840f6 100644
--- a/src/compiler/translator/blocklayout.cpp
+++ b/src/compiler/translator/blocklayout.cpp
@@ -199,6 +199,13 @@ BlockMemberInfo BlockLayoutEncoder::encodeType(GLenum type,
return memberInfo;
}
+size_t BlockLayoutEncoder::getCurrentOffset() const
+{
+ angle::base::CheckedNumeric<size_t> checkedOffset(mCurrentOffset);
+ checkedOffset *= kBytesPerComponent;
+ return checkedOffset.ValueOrDefault(std::numeric_limits<size_t>::max());
+}
+
size_t BlockLayoutEncoder::getShaderVariableSize(const ShaderVariable &structVar, bool isRowMajor)
{
size_t currentOffset = mCurrentOffset;
@@ -226,7 +233,13 @@ size_t BlockLayoutEncoder::GetBlockRegisterElement(const BlockMemberInfo &info)
void BlockLayoutEncoder::align(size_t baseAlignment)
{
- mCurrentOffset = rx::roundUp<size_t>(mCurrentOffset, baseAlignment);
+ angle::base::CheckedNumeric<size_t> checkedOffset(mCurrentOffset);
+ checkedOffset += baseAlignment;
+ checkedOffset -= 1;
+ angle::base::CheckedNumeric<size_t> checkedAlignmentOffset = checkedOffset;
+ checkedAlignmentOffset %= baseAlignment;
+ checkedOffset -= checkedAlignmentOffset.ValueOrDefault(std::numeric_limits<size_t>::max());
+ mCurrentOffset = checkedOffset.ValueOrDefault(std::numeric_limits<size_t>::max());
}
// StubBlockEncoder implementation.
@@ -289,7 +302,7 @@ void Std140BlockEncoder::getBlockLayoutInfo(GLenum type,
baseAlignment = ComponentAlignment(numComponents);
}
- mCurrentOffset = rx::roundUp(mCurrentOffset, baseAlignment);
+ align(baseAlignment);
*matrixStrideOut = matrixStride;
*arrayStrideOut = arrayStride;
@@ -303,16 +316,23 @@ void Std140BlockEncoder::advanceOffset(GLenum type,
{
if (!arraySizes.empty())
{
- mCurrentOffset += arrayStride * gl::ArraySizeProduct(arraySizes);
+ angle::base::CheckedNumeric<size_t> checkedOffset(arrayStride);
+ checkedOffset *= gl::ArraySizeProduct(arraySizes);
+ checkedOffset += mCurrentOffset;
+ mCurrentOffset = checkedOffset.ValueOrDefault(std::numeric_limits<size_t>::max());
}
else if (gl::IsMatrixType(type))
{
- const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix);
- mCurrentOffset += matrixStride * numRegisters;
+ angle::base::CheckedNumeric<size_t> checkedOffset(matrixStride);
+ checkedOffset *= gl::MatrixRegisterCount(type, isRowMajorMatrix);
+ checkedOffset += mCurrentOffset;
+ mCurrentOffset = checkedOffset.ValueOrDefault(std::numeric_limits<size_t>::max());
}
else
{
- mCurrentOffset += gl::VariableComponentCount(type);
+ angle::base::CheckedNumeric<size_t> checkedOffset(mCurrentOffset);
+ checkedOffset += gl::VariableComponentCount(type);
+ mCurrentOffset = checkedOffset.ValueOrDefault(std::numeric_limits<size_t>::max());
}
}
diff --git a/src/compiler/translator/blocklayout.h b/src/compiler/translator/blocklayout.h
index 726d76fa178f77a978ff2c82ec20fb8f1ad03f0b..ff90a2487830b365697ce41d660a689857b75319 100644
--- a/src/compiler/translator/blocklayout.h
+++ b/src/compiler/translator/blocklayout.h
@@ -80,7 +80,7 @@ class BlockLayoutEncoder
const std::vector<unsigned int> &arraySizes,
bool isRowMajorMatrix);
- size_t getCurrentOffset() const { return mCurrentOffset * kBytesPerComponent; }
+ size_t getCurrentOffset() const;
size_t getShaderVariableSize(const ShaderVariable &structVar, bool isRowMajor);
// Called when entering/exiting a structure variable.