OSDN Git Service

Validate pixel unpack buffer offset.
authorNicolas Capens <capn@google.com>
Thu, 22 Mar 2018 04:44:07 +0000 (00:44 -0400)
committerNicolas Capens <nicolascapens@google.com>
Mon, 26 Mar 2018 20:23:58 +0000 (20:23 +0000)
When a pixel unpack buffer is bound, glTexImage calls interpret the
<pixels> parameter as an offset into the pixel buffer. We weren't
validating that the accessed data falls within the buffer, when taking
the offset into account.

Bug chromium:822976

Change-Id: I3ab23e3b135fd4ad1e55555eec95d584684f5d82
Reviewed-on: https://swiftshader-review.googlesource.com/17928
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
src/OpenGL/libGLESv2/Context.cpp
src/OpenGL/libGLESv2/utilities.cpp
src/OpenGL/libGLESv2/utilities.h

index f495e8a..39e8c96 100644 (file)
@@ -1542,22 +1542,37 @@ GLsizei Context::getRequiredBufferSize(GLsizei width, GLsizei height, GLsizei de
        return inputPitch * inputHeight * depth;
 }
 
-GLenum Context::getPixels(const GLvoid **data, GLenum type, GLsizei imageSize) const
+GLenum Context::getPixels(const GLvoid **pixels, GLenum type, GLsizei imageSize) const
 {
        if(mState.pixelUnpackBuffer)
        {
-               if(mState.pixelUnpackBuffer->name)
+               ASSERT(mState.pixelUnpackBuffer->name != 0);
+
+               if(mState.pixelUnpackBuffer->isMapped())
                {
-                       if(mState.pixelUnpackBuffer->isMapped() ||
-                          (mState.pixelUnpackBuffer->size() < static_cast<size_t>(imageSize)) ||
-                          (static_cast<GLsizei>((ptrdiff_t)(*data)) % GetTypeSize(type)))
-                       {
-                               return GL_INVALID_OPERATION;
-                       }
+                       return GL_INVALID_OPERATION;
+               }
+
+               size_t offset = static_cast<size_t>((ptrdiff_t)(*pixels));
+
+               if(offset % GetTypeSize(type) != 0)
+               {
+                       return GL_INVALID_OPERATION;
                }
 
-               *data = static_cast<const unsigned char*>(mState.pixelUnpackBuffer->data()) + (ptrdiff_t)(*data);
+               if(offset > mState.pixelUnpackBuffer->size())
+               {
+                       return GL_INVALID_OPERATION;
+               }
+
+               if(mState.pixelUnpackBuffer->size() - offset < static_cast<size_t>(imageSize))
+               {
+                       return GL_INVALID_OPERATION;
+               }
+
+               *pixels = static_cast<const unsigned char*>(mState.pixelUnpackBuffer->data()) + offset;
        }
+
        return GL_NO_ERROR;
 }
 
index facc550..cdd1e05 100644 (file)
@@ -1121,7 +1121,7 @@ namespace es2
                return GL_NO_ERROR;
        }
 
-       GLsizei GetTypeSize(GLenum type)
+       size_t GetTypeSize(GLenum type)
        {
                switch(type)
                {
index 5959751..f0fdb4b 100644 (file)
@@ -58,7 +58,7 @@ namespace es2
        int CubeFaceIndex(GLenum cubeTarget);
        bool IsTextureTarget(GLenum target);
        GLenum ValidateTextureFormatType(GLenum format, GLenum type, GLint internalformat, GLenum target, GLint clientVersion);
-       GLsizei GetTypeSize(GLenum type);
+       size_t GetTypeSize(GLenum type);
 
        bool IsColorRenderable(GLint internalformat, GLint clientVersion);
        bool IsDepthRenderable(GLint internalformat, GLint clientVersion);