diff options
author | Vasiliy Telezhnikov <vasilyt@chromium.org> | 2023-01-16 15:41:34 +0000 |
---|---|---|
committer | Michael BrĂ¼ning <michael.bruning@qt.io> | 2023-02-27 11:57:02 +0000 |
commit | fddc72c22f78e68e272c5f3624facc885ce76f8e (patch) | |
tree | adc559de11e23de779da99b886a34e3304d5543e /chromium | |
parent | aac991c9f246e3e1cdbd0eb4b959c7457da82e3e (diff) | |
download | qtwebengine-chromium-fddc72c22f78e68e272c5f3624facc885ce76f8e.tar.gz |
[Backport] CVE-2023-0929: Use after free in Vulkan
Cherry-pick of patch originally reviewed on
https://chromium-review.googlesource.com/c/chromium/src/+/4143606:
CHECK that YUV readback finished synchronously
DoReadbackYUVImagePixelsINTERNAL is implemented using skia asynchronous
readback and to make it synchronous we use sync cpu and gpu. In some
edge cases on linux we saw that doesn't happen if readback triggered
vulkan device lost.
To avoid use after free, CHECK that callback was actually called. In
case of device-lost gpu process will restart anyway, so while this is
not proper fix of the problem, it doesn't result in worse user visible
behaviour.
Bug: 1399742
Change-Id: Ie2172539bb907b9696ef62c70d398aca3967177c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4143606
Reviewed-by: Peng Huang <penghuang@chromium.org>
Commit-Queue: Vasiliy Telezhnikov <vasilyt@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1093064}
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/462812
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
Diffstat (limited to 'chromium')
-rw-r--r-- | chromium/gpu/command_buffer/service/raster_decoder.cc | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/chromium/gpu/command_buffer/service/raster_decoder.cc b/chromium/gpu/command_buffer/service/raster_decoder.cc index 5ec69959c20..0160b309fc6 100644 --- a/chromium/gpu/command_buffer/service/raster_decoder.cc +++ b/chromium/gpu/command_buffer/service/raster_decoder.cc @@ -2484,6 +2484,7 @@ void RasterDecoderImpl::DoReadbackARGBImagePixelsINTERNAL( namespace { struct YUVReadbackResult { std::unique_ptr<const SkImage::AsyncReadResult> async_result; + bool finished = false; }; void OnReadYUVImagePixelsDone( @@ -2491,6 +2492,7 @@ void OnReadYUVImagePixelsDone( std::unique_ptr<const SkImage::AsyncReadResult> async_result) { YUVReadbackResult* context = reinterpret_cast<YUVReadbackResult*>(raw_ctx); context->async_result = std::move(async_result); + context->finished = true; } } // namespace @@ -2688,6 +2690,10 @@ void RasterDecoderImpl::DoReadbackYUVImagePixelsINTERNAL( // asynchronous by removing this flush and implementing a query that can // signal back to client process. gr_context()->flushAndSubmit(true); + + // The call above will sync up gpu and CPU, resulting in callback being run + // during flushAndSubmit. To prevent UAF make sure it indeed happened. + CHECK(yuv_result.finished); if (!yuv_result.async_result) { LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glReadbackYUVImagePixels", "Failed to read pixels from SkImage"); |