Browse Source

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

Pedro Pontes 3 years ago
parent
commit
09e40aca61

+ 1 - 0
patches/angle/.patches

@@ -4,3 +4,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

+ 112 - 0
patches/angle/fix_integer_overflow_in_blocklayoutencoder.patch

@@ -0,0 +1,112 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Alexis Hetu <[email protected]>
+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 <[email protected]>
+Reviewed-by: Kenneth Russell <[email protected]>
+Reviewed-by: Geoff Lang <[email protected]>
+Commit-Queue: Alexis Hétu <[email protected]>
+(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 65a729e05d9f9abca5ca1ca72466f68751ed602b..f523da7de61a156212ac578481b679fd626b5046 100644
+--- a/src/compiler/translator/blocklayout.cpp
++++ b/src/compiler/translator/blocklayout.cpp
+@@ -198,6 +198,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;
+@@ -225,7 +232,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.
+@@ -288,7 +301,7 @@ void Std140BlockEncoder::getBlockLayoutInfo(GLenum type,
+         baseAlignment              = ComponentAlignment(numComponents);
+     }
+ 
+-    mCurrentOffset = rx::roundUp(mCurrentOffset, baseAlignment);
++    align(baseAlignment);
+ 
+     *matrixStrideOut = matrixStride;
+     *arrayStrideOut  = arrayStride;
+@@ -302,16 +315,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 27b2247cb5f14c77577d46c9deec7308bcf1e73c..5004a5c206a6148faba29983044207046de1dcd4 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.