Commit 27a1020f by Geoff Lang Committed by Shannon Woods

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
parent 2426d5fe
...@@ -163,19 +163,28 @@ GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, Translat ...@@ -163,19 +163,28 @@ GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, Translat
if (staticBuffer == previousStaticBuffer) if (staticBuffer == previousStaticBuffer)
{ {
mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[previous], count, instances)); if (!mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[previous], count, instances)))
{
return GL_OUT_OF_MEMORY;
}
} }
} }
} }
mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[i], count, instances)); if (!mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[i], count, instances)))
{
return GL_OUT_OF_MEMORY;
}
buffer->invalidateStaticData(); buffer->invalidateStaticData();
} }
} }
else else
{ {
mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[i], count, instances)); if (!mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[i], count, instances)))
{
return GL_OUT_OF_MEMORY;
}
} }
} }
} }
...@@ -272,7 +281,10 @@ GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, Translat ...@@ -272,7 +281,10 @@ GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, Translat
if (mDirtyCurrentValue[i]) if (mDirtyCurrentValue[i])
{ {
const int requiredSpace = 4 * sizeof(float); const int requiredSpace = 4 * sizeof(float);
buffer->addRequiredSpace(requiredSpace); if (!buffer->addRequiredSpace(requiredSpace))
{
return GL_OUT_OF_MEMORY;
}
buffer->reserveRequiredSpace(); buffer->reserveRequiredSpace();
float *data = static_cast<float*>(buffer->map(VertexAttribute(), requiredSpace, &mCurrentValueOffsets[i])); float *data = static_cast<float*>(buffer->map(VertexAttribute(), requiredSpace, &mCurrentValueOffsets[i]));
if (data) if (data)
...@@ -628,9 +640,16 @@ ArrayVertexBuffer::~ArrayVertexBuffer() ...@@ -628,9 +640,16 @@ ArrayVertexBuffer::~ArrayVertexBuffer()
{ {
} }
void ArrayVertexBuffer::addRequiredSpace(UINT requiredSpace) bool ArrayVertexBuffer::addRequiredSpace(UINT requiredSpace)
{ {
// Protect against integer overflow
if (mRequiredSpace + requiredSpace < mRequiredSpace)
{
return false;
}
mRequiredSpace += requiredSpace; mRequiredSpace += requiredSpace;
return true;
} }
StreamingVertexBuffer::StreamingVertexBuffer(IDirect3DDevice9 *device, std::size_t initialSize) : ArrayVertexBuffer(device, initialSize, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY) StreamingVertexBuffer::StreamingVertexBuffer(IDirect3DDevice9 *device, std::size_t initialSize) : ArrayVertexBuffer(device, initialSize, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY)
...@@ -685,7 +704,7 @@ void StreamingVertexBuffer::reserveRequiredSpace() ...@@ -685,7 +704,7 @@ void StreamingVertexBuffer::reserveRequiredSpace()
mWritePosition = 0; mWritePosition = 0;
} }
else if (mWritePosition + mRequiredSpace > mBufferSize) // Recycle else if (mWritePosition + mRequiredSpace > mBufferSize || mWritePosition + mRequiredSpace < mWritePosition) // Recycle
{ {
if (mVertexBuffer) if (mVertexBuffer)
{ {
......
...@@ -66,7 +66,7 @@ class ArrayVertexBuffer : public VertexBuffer ...@@ -66,7 +66,7 @@ class ArrayVertexBuffer : public VertexBuffer
std::size_t size() const { return mBufferSize; } std::size_t size() const { return mBufferSize; }
virtual void *map(const VertexAttribute &attribute, std::size_t requiredSpace, std::size_t *streamOffset) = 0; virtual void *map(const VertexAttribute &attribute, std::size_t requiredSpace, std::size_t *streamOffset) = 0;
virtual void reserveRequiredSpace() = 0; virtual void reserveRequiredSpace() = 0;
void addRequiredSpace(UINT requiredSpace); bool addRequiredSpace(UINT requiredSpace);
protected: protected:
std::size_t mBufferSize; std::size_t mBufferSize;
......
Markdown is supported
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