From 7f1c3d07e961236201061a754dcb9cac3a56246a Mon Sep 17 00:00:00 2001 From: Nicolas Capens Date: Mon, 30 Jul 2018 16:42:49 -0400 Subject: [PATCH] Fix validation of uniform block size. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Uniform block members should not be validated against the GL_MAX_VERTEX_UNIFORM_VECTORS and GL_MAX_FRAGMENT_UNIFORM_VECTORS limits. Instead, block sizes should not exceed MAX_UNIFORM_BLOCK_SIZE. Also move uniform block index validation to the entry functions. Bug b/111803744 Change-Id: I0ea530813d1f2c29141dc64a93aa10f50460885b Reviewed-on: https://swiftshader-review.googlesource.com/20028 Reviewed-by: Alexis Hétu Tested-by: Nicolas Capens --- src/OpenGL/libGLESv2/Program.cpp | 67 ++++++++++++++++++++------------------ src/OpenGL/libGLESv2/Program.h | 10 +++--- src/OpenGL/libGLESv2/libGLESv3.cpp | 15 +++++++++ 3 files changed, 55 insertions(+), 37 deletions(-) diff --git a/src/OpenGL/libGLESv2/Program.cpp b/src/OpenGL/libGLESv2/Program.cpp index 9b10a7f52..77912cc46 100644 --- a/src/OpenGL/libGLESv2/Program.cpp +++ b/src/OpenGL/libGLESv2/Program.cpp @@ -51,14 +51,6 @@ namespace es2 matrixStride = uniform.blockInfo.matrixStride; isRowMajorMatrix = uniform.blockInfo.isRowMajorMatrix; } - else - { - index = -1; - offset = -1; - arrayStride = -1; - matrixStride = -1; - isRowMajorMatrix = false; - } } Uniform::Uniform(const glsl::Uniform &uniform, const BlockInfo &blockInfo) @@ -492,20 +484,15 @@ namespace es2 void Program::bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding) { - if(uniformBlockIndex >= getActiveUniformBlockCount()) - { - return error(GL_INVALID_VALUE); - } + ASSERT(uniformBlockIndex < getActiveUniformBlockCount()); uniformBlockBindings[uniformBlockIndex] = uniformBlockBinding; } GLuint Program::getUniformBlockBinding(GLuint uniformBlockIndex) const { - if(uniformBlockIndex >= getActiveUniformBlockCount()) - { - return error(GL_INVALID_VALUE, GL_INVALID_INDEX); - } + ASSERT(uniformBlockIndex < getActiveUniformBlockCount()); + return uniformBlockBindings[uniformBlockIndex]; } @@ -1713,8 +1700,24 @@ namespace es2 { const glsl::ActiveUniformBlocks &activeUniformBlocks = shader->activeUniformBlocks; ASSERT(static_cast(uniform.blockId) < activeUniformBlocks.size()); - blockIndex = getUniformBlockIndex(activeUniformBlocks[uniform.blockId].name); + const std::string &uniformBlockName = activeUniformBlocks[uniform.blockId].name; + blockIndex = getUniformBlockIndex(uniformBlockName); ASSERT(blockIndex != GL_INVALID_INDEX); + + if(activeUniformBlocks[uniform.blockId].dataSize > MAX_UNIFORM_BLOCK_SIZE) + { + if(shader->getType() == GL_VERTEX_SHADER) + { + appendToInfoLog("Vertex shader active uniform block (%s) exceeds GL_MAX_UNIFORM_BLOCK_SIZE (%d)", uniformBlockName.c_str(), MAX_UNIFORM_BLOCK_SIZE); + return false; + } + else if(shader->getType() == GL_FRAGMENT_SHADER) + { + appendToInfoLog("Fragment shader active uniform block (%s) exceeds GL_MAX_UNIFORM_BLOCK_SIZE (%d)", uniformBlockName.c_str(), MAX_UNIFORM_BLOCK_SIZE); + return false; + } + else UNREACHABLE(shader->getType()); + } } if(!defineUniform(shader->getType(), uniform, Uniform::BlockInfo(uniform, blockIndex))) @@ -1865,23 +1868,26 @@ namespace es2 } else UNREACHABLE(shader); - if(shader == GL_VERTEX_SHADER) + if(uniform->blockInfo.index < 0) { - if(glslUniform.registerIndex + uniform->registerCount() > MAX_VERTEX_UNIFORM_VECTORS) + if(shader == GL_VERTEX_SHADER) { - appendToInfoLog("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%d)", MAX_VERTEX_UNIFORM_VECTORS); - return false; + if(glslUniform.registerIndex + uniform->registerCount() > MAX_VERTEX_UNIFORM_VECTORS) + { + appendToInfoLog("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%d)", MAX_VERTEX_UNIFORM_VECTORS); + return false; + } } - } - else if(shader == GL_FRAGMENT_SHADER) - { - if(glslUniform.registerIndex + uniform->registerCount() > MAX_FRAGMENT_UNIFORM_VECTORS) + else if(shader == GL_FRAGMENT_SHADER) { - appendToInfoLog("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%d)", MAX_FRAGMENT_UNIFORM_VECTORS); - return false; + if(glslUniform.registerIndex + uniform->registerCount() > MAX_FRAGMENT_UNIFORM_VECTORS) + { + appendToInfoLog("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%d)", MAX_FRAGMENT_UNIFORM_VECTORS); + return false; + } } + else UNREACHABLE(shader); } - else UNREACHABLE(shader); return true; } @@ -2859,10 +2865,7 @@ namespace es2 void Program::getActiveUniformBlockName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const { - if(index >= getActiveUniformBlockCount()) - { - return error(GL_INVALID_VALUE); - } + ASSERT(index < getActiveUniformBlockCount()); const UniformBlock &uniformBlock = *uniformBlocks[index]; diff --git a/src/OpenGL/libGLESv2/Program.h b/src/OpenGL/libGLESv2/Program.h index 6f9940b78..501d081fe 100644 --- a/src/OpenGL/libGLESv2/Program.h +++ b/src/OpenGL/libGLESv2/Program.h @@ -42,11 +42,11 @@ namespace es2 { BlockInfo(const glsl::Uniform& uniform, int blockIndex); - int index; - int offset; - int arrayStride; - int matrixStride; - bool isRowMajorMatrix; + int index = -1; + int offset = -1; + int arrayStride = -1; + int matrixStride = -1; + bool isRowMajorMatrix = false; }; Uniform(const glsl::Uniform &uniform, const BlockInfo &blockInfo); diff --git a/src/OpenGL/libGLESv2/libGLESv3.cpp b/src/OpenGL/libGLESv2/libGLESv3.cpp index adb24d7f8..b4f537706 100644 --- a/src/OpenGL/libGLESv2/libGLESv3.cpp +++ b/src/OpenGL/libGLESv2/libGLESv3.cpp @@ -2629,6 +2629,11 @@ GL_APICALL void GL_APIENTRY glGetActiveUniformBlockiv(GLuint program, GLuint uni return error(GL_INVALID_OPERATION); } + if(uniformBlockIndex >= programObject->getActiveUniformBlockCount()) + { + return error(GL_INVALID_VALUE); + } + switch(pname) { case GL_UNIFORM_BLOCK_BINDING: @@ -2669,6 +2674,11 @@ GL_APICALL void GL_APIENTRY glGetActiveUniformBlockName(GLuint program, GLuint u return error(GL_INVALID_OPERATION); } + if(uniformBlockIndex >= programObject->getActiveUniformBlockCount()) + { + return error(GL_INVALID_VALUE); + } + programObject->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName); } } @@ -2694,6 +2704,11 @@ GL_APICALL void GL_APIENTRY glUniformBlockBinding(GLuint program, GLuint uniform return error(GL_INVALID_VALUE); } + if(uniformBlockIndex >= programObject->getActiveUniformBlockCount()) + { + return error(GL_INVALID_VALUE); + } + programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding); } } -- 2.11.0