Protect VBOs against buffer overflows.

Nicky 2013-03-25 16:19:47 +01:00
parent f8986cf39d
commit 0d4ecdefa4
3 changed files with 113 additions and 10 deletions

View File

@ -38,10 +38,10 @@ template <class Object> class LLStrider
U32 mSkip;
public:
LLStrider() { mObjectp = NULL; mSkip = sizeof(Object); }
LLStrider() { mObjectp = NULL; mSkip = sizeof(Object); mBufferEnd = 0; }
~LLStrider() { }
const LLStrider<Object>& operator = (Object *first) { mObjectp = first; return *this;}
const LLStrider<Object>& operator = (Object *first) { mObjectp = first; mBufferEnd = 0; return *this;}
void setStride (S32 skipBytes) { mSkip = (skipBytes ? skipBytes : sizeof(Object));}
LLStrider<Object> operator+(const S32& index)
@ -49,19 +49,102 @@ public:
LLStrider<Object> ret;
ret.mBytep = mBytep + mSkip*index;
ret.mSkip = mSkip;
ret.mBufferEnd = mBufferEnd;
return ret;
}
void skip(const U32 index) { mBytep += mSkip*index;}
U32 getSkip() const { return mSkip; }
Object* get() { return mObjectp; }
Object* operator->() { return mObjectp; }
Object& operator *() { return *mObjectp; }
Object* operator ++(int) { Object* old = mObjectp; mBytep += mSkip; return old; }
Object* operator +=(int i) { mBytep += mSkip*i; return mObjectp; }
void skip(const U32 index) { mBytep += mSkip*index;}
U32 getSkip() const { return mSkip; }
Object& operator[](U32 index) { return *(Object*)(mBytep + (mSkip * index)); }
// <FS:ND> protect against buffer overflows
// Object* get() { return mObjectp; }
// Object* operator->() { return mObjectp; }
// Object& operator *() { return *mObjectp; }
// Object* operator ++(int) { Object* old = mObjectp; mBytep += mSkip; return old; }
// Object* operator +=(int i) { mBytep += mSkip*i; return mObjectp; }
// Object& operator[](U32 index) { return *(Object*)(mBytep + (mSkip * index)); }
Object* get()
{
if( !assertValid( mBytep ) )
return &mDummy;
return mObjectp;
}
Object* operator->()
{
if( !assertValid( mBytep ) )
return &mDummy;
return mObjectp;
}
Object& operator *()
{
if( !assertValid( mBytep ) )
return mDummy;
return *mObjectp;
}
Object* operator ++(int)
{
Object* old = mObjectp;
mBytep += mSkip;
if( !assertValid( (U8*)old ) )
return &mDummy;
return old;
}
Object* operator +=(int i)
{
mBytep += mSkip*i;
assertValid( mBytep );
return mObjectp;
}
Object& operator[](U32 index)
{
if( !assertValid( mBytep + mSkip*index ) )
return mDummy;
return *(Object*)(mBytep + (mSkip * index));
}
void setCount( U32 aCount )
{
mBufferEnd = mBytep + mSkip*aCount;
#if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG
mCount = aCount;
#endif
}
bool assertValid( U8 const *aBuffer )
{
if( !aBuffer || !mBufferEnd )
return true;
if( aBuffer < mBufferEnd )
return true;
llerrs << "Vertex buffer access beyond end of VBO" << llendl;
return false;
}
private:
U8 *mBufferEnd;
#if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG
U32 mCount;
#endif
Object mDummy;
// <FS:ND>
};
#endif // LL_LLSTRIDER_H

View File

@ -2056,6 +2056,13 @@ template <class T,S32 type> struct VertexBufferStrider
strider = (T*)ptr;
strider.setStride(0);
// <FS:ND> protect against buffer overflows
if( count == -1 )
count = vbo.getNumIndices()-index;
strider.setCount( count );
// <FS:ND>
return true;
}
else if (vbo.hasDataType(type))
@ -2072,6 +2079,13 @@ template <class T,S32 type> struct VertexBufferStrider
strider = (T*)ptr;
strider.setStride(stride);
// <FS:ND> protect against buffer overflows
if( count == -1 )
count = vbo.getNumVerts()-index;
strider.setCount( count );
// <FS:ND>
return true;
}
else

View File

@ -829,6 +829,12 @@ void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance)
LLStrider<LLVector2> tc;
tc = (LLVector2*) vf.mTexCoords; tc.setStride(8);
// <FS:ND> protect against buffer overflows
pos.setCount( vf.mNumVertices );
norm.setCount( vf.mNumVertices );
tc.setCount( vf.mNumVertices );
// </FS:ND>
for (U32 i = 0; i < num_vertices; i++)
{
*(vertex_strider++) = *pos++;