Protect against integer overflows when generating index buffers for line loop and triangle fan drawing.
Issue 444
Signed-off-by: Jamie Madil
Signed-off-by: Shannon Woods
Author: Geoff Lang
diff --git a/src/libGLESv2/renderer/Renderer11.cpp b/src/libGLESv2/renderer/Renderer11.cpp
index 415de2c..c56aa1f 100644
--- a/src/libGLESv2/renderer/Renderer11.cpp
+++ b/src/libGLESv2/renderer/Renderer11.cpp
@@ -1146,7 +1146,13 @@
}
}
- const int spaceNeeded = (count + 1) * sizeof(unsigned int);
+ if (static_cast<unsigned int>(count + 1) > (std::numeric_limits<unsigned int>::max() / sizeof(unsigned int)))
+ {
+ ERR("Could not create a 32-bit looping index buffer for GL_LINE_LOOP, too many indices required.");
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+
+ const unsigned int spaceNeeded = (count + 1) * sizeof(unsigned int);
if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT))
{
ERR("Could not reserve enough space in looping index buffer for GL_LINE_LOOP.");
@@ -1240,8 +1246,15 @@
}
}
- const int numTris = count - 2;
- const int spaceNeeded = (numTris * 3) * sizeof(unsigned int);
+ const unsigned int numTris = count - 2;
+
+ if (numTris * 3 > (std::numeric_limits<unsigned int>::max() / sizeof(unsigned int)))
+ {
+ ERR("Could not create a scratch index buffer for GL_TRIANGLE_FAN, too many indices required.");
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+
+ const unsigned int spaceNeeded = (numTris * 3) * sizeof(unsigned int);
if (!mTriangleFanIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT))
{
ERR("Could not reserve enough space in scratch index buffer for GL_TRIANGLE_FAN.");
@@ -1262,7 +1275,7 @@
switch (type)
{
case GL_NONE: // Non-indexed draw
- for (int i = 0; i < numTris; i++)
+ for (unsigned int i = 0; i < numTris; i++)
{
data[i*3 + 0] = 0;
data[i*3 + 1] = i + 1;
@@ -1270,7 +1283,7 @@
}
break;
case GL_UNSIGNED_BYTE:
- for (int i = 0; i < numTris; i++)
+ for (unsigned int i = 0; i < numTris; i++)
{
data[i*3 + 0] = static_cast<const GLubyte*>(indices)[0];
data[i*3 + 1] = static_cast<const GLubyte*>(indices)[i + 1];
@@ -1278,7 +1291,7 @@
}
break;
case GL_UNSIGNED_SHORT:
- for (int i = 0; i < numTris; i++)
+ for (unsigned int i = 0; i < numTris; i++)
{
data[i*3 + 0] = static_cast<const GLushort*>(indices)[0];
data[i*3 + 1] = static_cast<const GLushort*>(indices)[i + 1];
@@ -1286,7 +1299,7 @@
}
break;
case GL_UNSIGNED_INT:
- for (int i = 0; i < numTris; i++)
+ for (unsigned int i = 0; i < numTris; i++)
{
data[i*3 + 0] = static_cast<const GLuint*>(indices)[0];
data[i*3 + 1] = static_cast<const GLuint*>(indices)[i + 1];