Use safe math in ValidateCopyBufferSubData.
This should fix any potential out of bounds reads/writes.
BUG=chromium:660854
Change-Id: Iffa00e4551d7362115cbf023a09b1d0e15f724c8
Reviewed-on: https://chromium-review.googlesource.com/405816
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/tests/gl_tests/BufferDataTest.cpp b/src/tests/gl_tests/BufferDataTest.cpp
index 572cce9..7707a4a 100644
--- a/src/tests/gl_tests/BufferDataTest.cpp
+++ b/src/tests/gl_tests/BufferDataTest.cpp
@@ -5,6 +5,7 @@
//
#include "test_utils/ANGLETest.h"
+#include "test_utils/gl_raii.h"
#include <stdint.h>
@@ -447,24 +448,8 @@
{
protected:
BufferDataOverflowTest()
- : mProgram(0)
{
}
-
- ~BufferDataOverflowTest()
- {
- if (!mBuffers.empty())
- {
- glDeleteBuffers(static_cast<GLsizei>(mBuffers.size()), &mBuffers[0]);
- }
- if (mProgram != 0u)
- {
- glDeleteProgram(mProgram);
- }
- }
-
- std::vector<GLuint> mBuffers;
- GLuint mProgram;
};
// See description above.
@@ -472,9 +457,9 @@
{
// These values are special, to trigger the rounding bug.
unsigned int numItems = 0x7FFFFFE;
- GLsizei bufferCnt = 8;
+ constexpr GLsizei bufferCnt = 8;
- mBuffers.resize(bufferCnt);
+ std::vector<GLBuffer> buffers(bufferCnt);
std::stringstream vertexShaderStr;
@@ -502,30 +487,27 @@
" gl_FragColor = vec4(v_attrib, 0, 0, 1);\n"
"}";
- mProgram = CompileProgram(vertexShaderStr.str(), fragmentShader);
- ASSERT_NE(0u, mProgram);
- glUseProgram(mProgram);
-
- glGenBuffers(bufferCnt, &mBuffers[0]);
+ ANGLE_GL_PROGRAM(program, vertexShaderStr.str(), fragmentShader);
+ glUseProgram(program.get());
std::vector<GLfloat> data(numItems, 1.0f);
for (GLsizei bufferIndex = 0; bufferIndex < bufferCnt; ++bufferIndex)
{
- glBindBuffer(GL_ARRAY_BUFFER, mBuffers[bufferIndex]);
+ glBindBuffer(GL_ARRAY_BUFFER, buffers[bufferIndex].get());
glBufferData(GL_ARRAY_BUFFER, numItems * sizeof(float), &data[0], GL_DYNAMIC_DRAW);
std::stringstream attribNameStr;
attribNameStr << "attrib" << bufferIndex;
- GLint attribLocation = glGetAttribLocation(mProgram, attribNameStr.str().c_str());
+ GLint attribLocation = glGetAttribLocation(program.get(), attribNameStr.str().c_str());
ASSERT_NE(-1, attribLocation);
glVertexAttribPointer(attribLocation, 1, GL_FLOAT, GL_FALSE, 4, nullptr);
glEnableVertexAttribArray(attribLocation);
}
- GLint positionLocation = glGetAttribLocation(mProgram, "position");
+ GLint positionLocation = glGetAttribLocation(program.get(), "position");
ASSERT_NE(-1, positionLocation);
glDisableVertexAttribArray(positionLocation);
glVertexAttrib2f(positionLocation, 1.0f, 1.0f);
@@ -535,6 +517,28 @@
EXPECT_GL_ERROR(GL_OUT_OF_MEMORY);
}
+// Tests a security bug in our CopyBufferSubData validation (integer overflow).
+TEST_P(BufferDataOverflowTest, CopySubDataValidation)
+{
+ GLBuffer readBuffer, writeBuffer;
+
+ glBindBuffer(GL_COPY_READ_BUFFER, readBuffer.get());
+ glBindBuffer(GL_COPY_WRITE_BUFFER, writeBuffer.get());
+
+ constexpr int bufSize = 100;
+
+ glBufferData(GL_COPY_READ_BUFFER, bufSize, nullptr, GL_STATIC_DRAW);
+ glBufferData(GL_COPY_WRITE_BUFFER, bufSize, nullptr, GL_STATIC_DRAW);
+
+ GLintptr big = std::numeric_limits<GLintptr>::max() - bufSize + 90;
+
+ glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, big, 0, 50);
+ EXPECT_GL_ERROR(GL_INVALID_VALUE);
+
+ glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, big, 50);
+ EXPECT_GL_ERROR(GL_INVALID_VALUE);
+}
+
ANGLE_INSTANTIATE_TEST(BufferDataOverflowTest, ES3_D3D11());
#endif // _WIN64