From 33fd7a21ed794e4d89062b9153ff714e642773ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Br=C3=BCning?= Date: Mon, 5 Nov 2018 16:16:59 +0100 Subject: [Backport] Fix for CVE-2018-17466 Pass unpack buffer as explicit parameter to texSubImage. This allows us to override it in the incomplete texture init. Any back-end that used incomplete textures was vulnerable to a bug where the unpack buffer would be used to initialize the incomplete texture. Cherry-picked to the chromium/3538 branch cleanly. Bug: chromium:880906 Change-Id: Ifca9891ecc207a74673fe1e6ef3e0a2118837fb2 Reviewed-on: https://chromium-review.googlesource.com/1227033 Reviewed-by: Jamie Madill Reviewed-by: Allan Sandfeld Jensen --- chromium/third_party/angle/src/libANGLE/Context.cpp | 13 +++++++++---- chromium/third_party/angle/src/libANGLE/Texture.cpp | 3 ++- chromium/third_party/angle/src/libANGLE/Texture.h | 1 + .../angle/src/libANGLE/renderer/TextureImpl.h | 1 + .../angle/src/libANGLE/renderer/TextureImpl_mock.h | 3 ++- .../angle/src/libANGLE/renderer/d3d/TextureD3D.cpp | 20 ++++++++++---------- .../angle/src/libANGLE/renderer/d3d/TextureD3D.h | 6 ++++++ .../angle/src/libANGLE/renderer/gl/TextureGL.cpp | 3 +-- .../angle/src/libANGLE/renderer/gl/TextureGL.h | 1 + .../angle/src/libANGLE/renderer/null/TextureNULL.cpp | 1 + .../angle/src/libANGLE/renderer/null/TextureNULL.h | 1 + .../angle/src/libANGLE/renderer/renderer_utils.cpp | 4 ++-- .../angle/src/libANGLE/renderer/vulkan/TextureVk.cpp | 1 + .../angle/src/libANGLE/renderer/vulkan/TextureVk.h | 1 + 14 files changed, 39 insertions(+), 20 deletions(-) diff --git a/chromium/third_party/angle/src/libANGLE/Context.cpp b/chromium/third_party/angle/src/libANGLE/Context.cpp index 65252e834a8..461bf910cb9 100644 --- a/chromium/third_party/angle/src/libANGLE/Context.cpp +++ b/chromium/third_party/angle/src/libANGLE/Context.cpp @@ -3327,8 +3327,9 @@ void Context::texSubImage2D(GLenum target, Box area(xoffset, yoffset, 0, width, height, 1); Texture *texture = getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); - handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format, - type, reinterpret_cast(pixels))); + gl::Buffer *unpackBuffer = mGLState.getTargetBuffer(gl::BufferBinding::PixelUnpack); + handleError(texture->setSubImage(this, mGLState.getUnpackState(), unpackBuffer, target, level, + area, format, type, reinterpret_cast(pixels))); } void Context::texSubImage3D(GLenum target, @@ -3353,8 +3354,12 @@ void Context::texSubImage3D(GLenum target, Box area(xoffset, yoffset, zoffset, width, height, depth); Texture *texture = getTargetTexture(target); - handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format, - type, reinterpret_cast(pixels))); + + gl::Buffer *unpackBuffer = mGLState.getTargetBuffer(gl::BufferBinding::PixelUnpack); + + handleError(texture->setSubImage(this, mGLState.getUnpackState(), unpackBuffer, + target, level, area, format, type, + reinterpret_cast(pixels))); } void Context::compressedTexImage2D(GLenum target, diff --git a/chromium/third_party/angle/src/libANGLE/Texture.cpp b/chromium/third_party/angle/src/libANGLE/Texture.cpp index 24e8c221f76..9b31a161d32 100644 --- a/chromium/third_party/angle/src/libANGLE/Texture.cpp +++ b/chromium/third_party/angle/src/libANGLE/Texture.cpp @@ -930,6 +930,7 @@ Error Texture::setImage(const Context *context, Error Texture::setSubImage(const Context *context, const PixelUnpackState &unpackState, + Buffer *unpackBuffer, GLenum target, size_t level, const Box &area, @@ -942,7 +943,7 @@ Error Texture::setSubImage(const Context *context, ANGLE_TRY(ensureSubImageInitialized(context, target, level, area)); - return mTexture->setSubImage(context, target, level, area, format, type, unpackState, pixels); + return mTexture->setSubImage(context, target, level, area, format, type, unpackState, unpackBuffer, pixels); } Error Texture::setCompressedImage(const Context *context, diff --git a/chromium/third_party/angle/src/libANGLE/Texture.h b/chromium/third_party/angle/src/libANGLE/Texture.h index 7525da2b2ff..a63b6cd6a78 100644 --- a/chromium/third_party/angle/src/libANGLE/Texture.h +++ b/chromium/third_party/angle/src/libANGLE/Texture.h @@ -269,6 +269,7 @@ class Texture final : public egl::ImageSibling, const uint8_t *pixels); Error setSubImage(const Context *context, const PixelUnpackState &unpackState, + Buffer *unpackBuffer, GLenum target, size_t level, const Box &area, diff --git a/chromium/third_party/angle/src/libANGLE/renderer/TextureImpl.h b/chromium/third_party/angle/src/libANGLE/renderer/TextureImpl.h index 3b4f28f5f70..e9def243395 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/TextureImpl.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/TextureImpl.h @@ -64,6 +64,7 @@ class TextureImpl : public FramebufferAttachmentObjectImpl GLenum format, GLenum type, const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, const uint8_t *pixels) = 0; virtual gl::Error setCompressedImage(const gl::Context *context, diff --git a/chromium/third_party/angle/src/libANGLE/renderer/TextureImpl_mock.h b/chromium/third_party/angle/src/libANGLE/renderer/TextureImpl_mock.h index e7fa4417817..aa531fda4cd 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/TextureImpl_mock.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/TextureImpl_mock.h @@ -31,7 +31,7 @@ class MockTextureImpl : public TextureImpl GLenum, const gl::PixelUnpackState &, const uint8_t *)); - MOCK_METHOD8(setSubImage, + MOCK_METHOD9(setSubImage, gl::Error(const gl::Context *, GLenum, size_t, @@ -39,6 +39,7 @@ class MockTextureImpl : public TextureImpl GLenum, GLenum, const gl::PixelUnpackState &, + gl::Buffer *, const uint8_t *)); MOCK_METHOD8(setCompressedImage, gl::Error(const gl::Context *, diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/TextureD3D.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/TextureD3D.cpp index 2d0ee27b478..a5c1f21ad4b 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/TextureD3D.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/TextureD3D.cpp @@ -258,13 +258,12 @@ gl::Error TextureD3D::subImage(const gl::Context *context, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, const uint8_t *pixels, ptrdiff_t layerOffset) { // CPU readback & copy where direct GPU copy is not supported const uint8_t *pixelData = nullptr; - gl::Buffer *unpackBuffer = - context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack); ANGLE_TRY(GetUnpackPointer(context, unpack, unpackBuffer, pixels, layerOffset, &pixelData)); if (pixelData != nullptr) @@ -879,6 +878,7 @@ gl::Error TextureD3D_2D::setSubImage(const gl::Context *context, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, const uint8_t *pixels) { ASSERT(target == GL_TEXTURE_2D && area.depth == 1 && area.z == 0); @@ -886,8 +886,6 @@ gl::Error TextureD3D_2D::setSubImage(const gl::Context *context, GLint level = static_cast(imageLevel); gl::ImageIndex index = gl::ImageIndex::Make2D(level); - gl::Buffer *unpackBuffer = - context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack); if (isFastUnpackable(unpackBuffer, getInternalFormat(level)) && isLevelComplete(level)) { RenderTargetD3D *renderTarget = nullptr; @@ -899,7 +897,7 @@ gl::Error TextureD3D_2D::setSubImage(const gl::Context *context, } else { - return TextureD3D::subImage(context, index, area, format, type, unpack, pixels, 0); + return TextureD3D::subImage(context, index, area, format, type, unpack, unpackBuffer, pixels, 0); } } @@ -1669,12 +1667,13 @@ gl::Error TextureD3D_Cube::setSubImage(const gl::Context *context, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, const uint8_t *pixels) { ASSERT(area.depth == 1 && area.z == 0); gl::ImageIndex index = gl::ImageIndex::MakeCube(target, static_cast(level)); - return TextureD3D::subImage(context, index, area, format, type, unpack, pixels, 0); + return TextureD3D::subImage(context, index, area, format, type, unpack, unpackBuffer, pixels, 0); } gl::Error TextureD3D_Cube::setCompressedImage(const gl::Context *context, @@ -2458,6 +2457,7 @@ gl::Error TextureD3D_3D::setSubImage(const gl::Context *context, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, const uint8_t *pixels) { ASSERT(target == GL_TEXTURE_3D); @@ -2466,8 +2466,6 @@ gl::Error TextureD3D_3D::setSubImage(const gl::Context *context, gl::ImageIndex index = gl::ImageIndex::Make3D(level); // Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer - gl::Buffer *unpackBuffer = - context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack); if (isFastUnpackable(unpackBuffer, getInternalFormat(level)) && isLevelComplete(level)) { RenderTargetD3D *destRenderTarget = nullptr; @@ -2479,7 +2477,7 @@ gl::Error TextureD3D_3D::setSubImage(const gl::Context *context, } else { - return TextureD3D::subImage(context, index, area, format, type, unpack, pixels, 0); + return TextureD3D::subImage(context, index, area, format, type, unpack, unpackBuffer, pixels, 0); } } @@ -2997,6 +2995,7 @@ gl::Error TextureD3D_2DArray::setSubImage(const gl::Context *context, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, const uint8_t *pixels) { ASSERT(target == GL_TEXTURE_2D_ARRAY); @@ -3016,7 +3015,7 @@ gl::Error TextureD3D_2DArray::setSubImage(const gl::Context *context, gl::Box layerArea(area.x, area.y, 0, area.width, area.height, 1); gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, layer); - ANGLE_TRY(TextureD3D::subImage(context, index, layerArea, format, type, unpack, pixels, + ANGLE_TRY(TextureD3D::subImage(context, index, layerArea, format, type, unpack, unpackBuffer, pixels, layerOffset)); } @@ -3566,6 +3565,7 @@ gl::Error TextureD3D_External::setSubImage(const gl::Context *context, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, const uint8_t *pixels) { UNREACHABLE(); diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/TextureD3D.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/TextureD3D.h index eb206a6ccc1..5beeb8b67cb 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/TextureD3D.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/TextureD3D.h @@ -116,6 +116,7 @@ class TextureD3D : public TextureImpl GLenum format, GLenum type, const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, const uint8_t *pixels, ptrdiff_t layerOffset); gl::Error setCompressedImageImpl(const gl::Context *context, @@ -220,6 +221,7 @@ class TextureD3D_2D : public TextureD3D GLenum format, GLenum type, const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, const uint8_t *pixels) override; gl::Error setCompressedImage(const gl::Context *context, @@ -356,6 +358,7 @@ class TextureD3D_Cube : public TextureD3D GLenum format, GLenum type, const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, const uint8_t *pixels) override; gl::Error setCompressedImage(const gl::Context *context, @@ -493,6 +496,7 @@ class TextureD3D_3D : public TextureD3D GLenum format, GLenum type, const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, const uint8_t *pixels) override; gl::Error setCompressedImage(const gl::Context *context, @@ -607,6 +611,7 @@ class TextureD3D_2DArray : public TextureD3D GLenum format, GLenum type, const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, const uint8_t *pixels) override; gl::Error setCompressedImage(const gl::Context *context, @@ -718,6 +723,7 @@ class TextureD3D_External : public TextureD3D GLenum format, GLenum type, const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, const uint8_t *pixels) override; gl::Error setCompressedImage(const gl::Context *context, diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/TextureGL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/gl/TextureGL.cpp index 2ff6fbc42ae..996024fb7ae 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/TextureGL.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/TextureGL.cpp @@ -277,11 +277,10 @@ gl::Error TextureGL::setSubImage(const gl::Context *context, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, const uint8_t *pixels) { ASSERT(CompatibleTextureTarget(getTarget(), target)); - const gl::Buffer *unpackBuffer = - context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack); nativegl::TexSubImageFormat texSubImageFormat = nativegl::GetTexSubImageFormat(mFunctions, mWorkarounds, format, type); diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/TextureGL.h b/chromium/third_party/angle/src/libANGLE/renderer/gl/TextureGL.h index 4a48acb1720..106acbd2d4b 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/TextureGL.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/TextureGL.h @@ -79,6 +79,7 @@ class TextureGL : public TextureImpl GLenum format, GLenum type, const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, const uint8_t *pixels) override; gl::Error setCompressedImage(const gl::Context *context, diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/TextureNULL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/null/TextureNULL.cpp index 67b533aac47..cbf07a71f1c 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/null/TextureNULL.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/TextureNULL.cpp @@ -44,6 +44,7 @@ gl::Error TextureNULL::setSubImage(const gl::Context *context, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, const uint8_t *pixels) { return gl::NoError(); diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/TextureNULL.h b/chromium/third_party/angle/src/libANGLE/renderer/null/TextureNULL.h index 92dec3d416c..dd2386c5016 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/null/TextureNULL.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/TextureNULL.h @@ -37,6 +37,7 @@ class TextureNULL : public TextureImpl GLenum format, GLenum type, const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, const uint8_t *pixels) override; gl::Error setCompressedImage(const gl::Context *context, diff --git a/chromium/third_party/angle/src/libANGLE/renderer/renderer_utils.cpp b/chromium/third_party/angle/src/libANGLE/renderer/renderer_utils.cpp index 4737af9768f..ea2647f4c5c 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/renderer_utils.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/renderer_utils.cpp @@ -525,7 +525,7 @@ gl::Error IncompleteTextureSet::getIncompleteTexture( face++) { ANGLE_TRY( - t->setSubImage(context, unpack, face, 0, area, GL_RGBA, GL_UNSIGNED_BYTE, color)); + t->setSubImage(context, unpack, nullptr, face, 0, area, GL_RGBA, GL_UNSIGNED_BYTE, color)); } } else if (type == GL_TEXTURE_2D_MULTISAMPLE) @@ -536,7 +536,7 @@ gl::Error IncompleteTextureSet::getIncompleteTexture( else { ANGLE_TRY( - t->setSubImage(context, unpack, createType, 0, area, GL_RGBA, GL_UNSIGNED_BYTE, color)); + t->setSubImage(context, unpack, nullptr, createType, 0, area, GL_RGBA, GL_UNSIGNED_BYTE, color)); } t->syncState(); diff --git a/chromium/third_party/angle/src/libANGLE/renderer/vulkan/TextureVk.cpp b/chromium/third_party/angle/src/libANGLE/renderer/vulkan/TextureVk.cpp index 12397756e2c..d3a1575b394 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/vulkan/TextureVk.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/vulkan/TextureVk.cpp @@ -192,6 +192,7 @@ gl::Error TextureVk::setSubImage(const gl::Context *context, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, const uint8_t *pixels) { ContextVk *contextVk = vk::GetImpl(context); diff --git a/chromium/third_party/angle/src/libANGLE/renderer/vulkan/TextureVk.h b/chromium/third_party/angle/src/libANGLE/renderer/vulkan/TextureVk.h index 9ebffe33d1b..009cceaefd1 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/vulkan/TextureVk.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/vulkan/TextureVk.h @@ -40,6 +40,7 @@ class TextureVk : public TextureImpl, public ResourceVk GLenum format, GLenum type, const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, const uint8_t *pixels) override; gl::Error setCompressedImage(const gl::Context *context, -- cgit v1.2.3