Skip to content
Snippets Groups Projects
Unverified Commit 09e40aca authored by Pedro Pontes's avatar Pedro Pontes Committed by GitHub
Browse files

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

parent f5e1934f
No related merge requests found
......@@ -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
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 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.
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment