From ab79e33ef3a21a2b14bf15bc4c85aef247b4ad95 Mon Sep 17 00:00:00 2001 From: Dan Stoza Date: Wed, 29 Apr 2015 13:30:31 -0700 Subject: [PATCH] SurfaceFlinger: Fix integer overflow in Mesh ctor Performs range checking on the inputs to Mesh::Mesh() before allocating the storage array. Bug: 20674682 Change-Id: I4fc918a8c312d967dd6d9f91a098b2e0a7081027 --- services/surfaceflinger/RenderEngine/Mesh.cpp | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/services/surfaceflinger/RenderEngine/Mesh.cpp b/services/surfaceflinger/RenderEngine/Mesh.cpp index 3f50cb0a9..ffd9be2a8 100644 --- a/services/surfaceflinger/RenderEngine/Mesh.cpp +++ b/services/surfaceflinger/RenderEngine/Mesh.cpp @@ -16,14 +16,40 @@ #include "Mesh.h" +#include + namespace android { Mesh::Mesh(Primitive primitive, size_t vertexCount, size_t vertexSize, size_t texCoordSize) : mVertexCount(vertexCount), mVertexSize(vertexSize), mTexCoordsSize(texCoordSize), mPrimitive(primitive) { - mVertices = new float[(vertexSize + texCoordSize) * vertexCount]; - mStride = mVertexSize + mTexCoordsSize; + if (vertexCount == 0) { + mVertices = new float[1]; + mVertices[0] = 0.0f; + mStride = 0; + return; + } + + size_t stride = vertexSize + texCoordSize; + size_t remainder = (stride * vertexCount) / vertexCount; + // Since all of the input parameters are unsigned, if stride is less than + // either vertexSize or texCoordSize, it must have overflowed. remainder + // will be equal to stride as long as stride * vertexCount doesn't overflow. + if ((stride < vertexSize) || (remainder != stride)) { + ALOGE("Overflow in Mesh(..., %zu, %zu, %zu)", vertexCount, vertexSize, + texCoordSize); + mVertices = new float[1]; + mVertices[0] = 0.0f; + mVertexCount = 0; + mVertexSize = 0; + mTexCoordsSize = 0; + mStride = 0; + return; + } + + mVertices = new float[stride * vertexCount]; + mStride = stride; } Mesh::~Mesh() {