summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShahbaz Youssefi <syoussefi@chromium.org>2023-12-05 13:36:53 -0500
committerMichael BrĂ¼ning <michael.bruning@qt.io>2024-01-22 10:33:06 +0000
commitaac73f3a715655476ce5b347a9614d1ca0ba9b93 (patch)
tree9160c2815f123efdf669ee4dbb4824920600e6e5
parentc8088aea77818f87d42f709ddcb743b907c38e9c (diff)
[Backport] CVE-2024-0222: Use after free in ANGLE
Manual cherry-pick of patch originally reviewed on https://chromium-review.googlesource.com/c/angle/angle/+/5143829: M120: Vulkan: Don't crash when glCopyTexImage2D redefines itself The Vulkan backend marks a level being redefined as such before doing the copy. If a single-level texture was being redefined, it releases it so it can be immediately reallocated. If the source of the copy is the same texture, this causes a crash. This can be properly supported by using a temp image to do the copy, but that is not implemented in this change. Bug: chromium:1501798 Change-Id: I3a902b1e9eec41afd385d9c75a8c95dc986070a8 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5143829 Reviewed-by: Cody Northrop <cnorthrop@google.com> Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/532069 Reviewed-by: Michal Klocek <michal.klocek@qt.io>
-rw-r--r--chromium/third_party/angle/src/libANGLE/renderer/vulkan/TextureVk.cpp23
1 files changed, 22 insertions, 1 deletions
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 1950375b9b1..a098da4bfd3 100644
--- a/chromium/third_party/angle/src/libANGLE/renderer/vulkan/TextureVk.cpp
+++ b/chromium/third_party/angle/src/libANGLE/renderer/vulkan/TextureVk.cpp
@@ -466,8 +466,28 @@ angle::Result TextureVk::copyImage(const gl::Context *context,
gl::GetInternalFormatInfo(internalFormat, GL_UNSIGNED_BYTE);
const vk::Format &vkFormat = renderer->getFormat(internalFormatInfo.sizedInternalFormat);
+ // The texture level being redefined might be the same as the one bound to the framebuffer.
+ // This _could_ be supported by using a temp image before redefining the level (and potentially
+ // discarding the image). However, this is currently unimplemented.
+ FramebufferVk *framebufferVk = vk::GetImpl(source);
+ RenderTargetVk *colorReadRT = framebufferVk->getColorReadRenderTarget();
+ vk::ImageHelper *srcImage = &colorReadRT->getImageForCopy();
+ const bool isCubeMap = index.getType() == gl::TextureType::CubeMap;
+ gl::LevelIndex levelIndex(getNativeImageIndex(index).getLevelIndex());
+ const uint32_t layerIndex = index.hasLayer() ? index.getLayerIndex() : 0;
+ const uint32_t redefinedFace = isCubeMap ? layerIndex : 0;
+ const uint32_t sourceFace = isCubeMap ? colorReadRT->getLayerIndex() : 0;
+ const bool isSelfCopy = mImage == srcImage && levelIndex == colorReadRT->getLevelIndex() &&
+ redefinedFace == sourceFace;
+
ANGLE_TRY(redefineLevel(context, index, vkFormat, newImageSize));
+ if (isSelfCopy)
+ {
+ UNIMPLEMENTED();
+ return angle::Result::Continue;
+ }
+
return copySubImageImpl(context, index, gl::Offset(0, 0, 0), sourceArea, internalFormatInfo,
source);
}
@@ -1393,7 +1413,8 @@ angle::Result TextureVk::redefineLevel(const gl::Context *context,
mImage->getLevelCount() == 1 && mImage->getBaseLevel() == levelIndexGL;
// If incompatible, and redefining the single-level image, release it so it can be
- // recreated immediately. This is an optimization to avoid an extra copy.
+ // recreated immediately. This is needed so that the texture can be reallocated with
+ // the correct format/size.
if (!isCompatibleRedefinition && isUpdateToSingleLevelImage)
{
releaseImage(contextVk);