Protect against integer overflows in the VertexBuffer class by validating the reserved space.

Issue 444

Signed-off-by: Jamie Madil
Signed-off-by: Shannon Woods
Author: Geoff Lang
diff --git a/src/libGLESv2/renderer/VertexBuffer.cpp b/src/libGLESv2/renderer/VertexBuffer.cpp
index 16e1486..a858946 100644
--- a/src/libGLESv2/renderer/VertexBuffer.cpp
+++ b/src/libGLESv2/renderer/VertexBuffer.cpp
@@ -125,14 +125,30 @@
     return oldWritePos;
 }
 
-void VertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances)
+bool VertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances)
 {
-    mReservedSpace += mVertexBuffer->getSpaceRequired(attribute, count, instances);
+    unsigned int requiredSpace = mVertexBuffer->getSpaceRequired(attribute, count, instances);
+
+    // Protect against integer overflow
+    if (mReservedSpace + requiredSpace < mReservedSpace)
+    {
+         return false;
+    }
+
+    mReservedSpace += requiredSpace;
+    return true;
 }
 
-void VertexBufferInterface::reserveRawDataSpace(unsigned int size)
+bool VertexBufferInterface::reserveRawDataSpace(unsigned int size)
 {
+    // Protect against integer overflow
+    if (mReservedSpace + size < mReservedSpace)
+    {
+         return false;
+    }
+
     mReservedSpace += size;
+    return true;
 }
 
 VertexBuffer* VertexBufferInterface::getVertexBuffer() const
diff --git a/src/libGLESv2/renderer/VertexBuffer.h b/src/libGLESv2/renderer/VertexBuffer.h
index 6ecffd0..c474b05 100644
--- a/src/libGLESv2/renderer/VertexBuffer.h
+++ b/src/libGLESv2/renderer/VertexBuffer.h
@@ -60,8 +60,8 @@
     VertexBufferInterface(rx::Renderer *renderer, bool dynamic);
     virtual ~VertexBufferInterface();
 
-    void reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances);
-    void reserveRawDataSpace(unsigned int size);
+    bool reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances);
+    bool reserveRawDataSpace(unsigned int size);
 
     unsigned int getBufferSize() const;
 
diff --git a/src/libGLESv2/renderer/VertexDataManager.cpp b/src/libGLESv2/renderer/VertexDataManager.cpp
index ec85857..fd869b1 100644
--- a/src/libGLESv2/renderer/VertexDataManager.cpp
+++ b/src/libGLESv2/renderer/VertexDataManager.cpp
@@ -116,12 +116,18 @@
                     if (staticBuffer->getBufferSize() == 0)
                     {
                         int totalCount = elementsInBuffer(attribs[i], buffer->size());
-                        staticBuffer->reserveVertexSpace(attribs[i], totalCount, 0);
+                        if (!staticBuffer->reserveVertexSpace(attribs[i], totalCount, 0))
+                        {
+                            return GL_OUT_OF_MEMORY;
+                        }
                     }
                 }
                 else
                 {
-                    mStreamingBuffer->reserveVertexSpace(attribs[i], count, instances);
+                    if (!mStreamingBuffer->reserveVertexSpace(attribs[i], count, instances))
+                    {
+                        return GL_OUT_OF_MEMORY;
+                    }
                 }
             }
         }
@@ -217,7 +223,10 @@
                     mCurrentValue[i][3] != attribs[i].mCurrentValue[3])
                 {
                     unsigned int requiredSpace = sizeof(float) * 4;
-                    buffer->reserveRawDataSpace(requiredSpace);
+                    if (!buffer->reserveRawDataSpace(requiredSpace))
+                    {
+                        return GL_OUT_OF_MEMORY;
+                    }
                     int streamOffset = buffer->storeRawData(attribs[i].mCurrentValue, requiredSpace);
                     if (streamOffset == -1)
                     {