Skip to content

Commit 7d388ce

Browse files
vonturemibrunin
authored andcommitted
[Backport] CVE-2021-21233: Heap buffer overflow in ANGLE
Manual cherry-pick of patch orignally reviewed on https://chromium-review.googlesource.com/c/angle/angle/+/2836786: D3D11: Skip blits if there is no intersection of dest areas Blit11 would clip the destination rectangle with the destination size but ignore the result. gl::ClipRectangle returns false when the rectangles do not intersect at all, indicating the blit can be skipped. This could lead to an out-of-bounds write to the GPU memory for the destination texture. Mark ClipRectangle as nodiscard to prevent future issues. Bug: chromium:1199402 Change-Id: I260e82d0917b8aa7e7887f2c9f7ed4b1a03ba785 Reviewed-by: Jamie Madill <[email protected]> Commit-Queue: Geoff Lang <[email protected]> Also fixes Chromium bug 1182937. Change-Id: I6cb64f2e888c605b0c205bb296f1d5143612796e Reviewed-by: Allan Sandfeld Jensen <[email protected]>
1 parent 364aa54 commit 7d388ce

File tree

5 files changed

+18
-6
lines changed

5 files changed

+18
-6
lines changed

chromium/third_party/angle/src/libANGLE/angletypes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ struct Rectangle
7474
bool operator==(const Rectangle &a, const Rectangle &b);
7575
bool operator!=(const Rectangle &a, const Rectangle &b);
7676

77-
bool ClipRectangle(const Rectangle &source, const Rectangle &clip, Rectangle *intersection);
77+
ANGLE_NO_DISCARD bool ClipRectangle(const Rectangle &source, const Rectangle &clip, Rectangle *intersection);
7878

7979
struct Offset
8080
{

chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,10 @@ void StretchedBlitNearest(const gl::Box &sourceArea,
141141
uint8_t *destData)
142142
{
143143
gl::Rectangle clippedDestArea(destArea.x, destArea.y, destArea.width, destArea.height);
144-
gl::ClipRectangle(clippedDestArea, clipRect, &clippedDestArea);
144+
if (!gl::ClipRectangle(clippedDestArea, clipRect, &clippedDestArea))
145+
{
146+
return;
147+
}
145148

146149
// Determine if entire rows can be copied at once instead of each individual pixel. There
147150
// must be no out of bounds lookups, whole rows copies, and no scale.

chromium/third_party/angle/src/libANGLE/renderer/gl/FramebufferGL.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1117,7 +1117,10 @@ angle::Result FramebufferGL::clipSrcRegion(const gl::Context *context,
11171117
// If pixels lying outside the read framebuffer, adjust src region
11181118
// and dst region to appropriate in-bounds regions respectively.
11191119
gl::Rectangle realSourceRegion;
1120-
ClipRectangle(bounds.sourceRegion, bounds.sourceBounds, &realSourceRegion);
1120+
if (!ClipRectangle(bounds.sourceRegion, bounds.sourceBounds, &realSourceRegion))
1121+
{
1122+
return angle::Result::Stop;
1123+
}
11211124
GLuint xOffset = realSourceRegion.x - bounds.sourceRegion.x;
11221125
GLuint yOffset = realSourceRegion.y - bounds.sourceRegion.y;
11231126

chromium/third_party/angle/src/libANGLE/renderer/metal/ContextMtl.mm

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1362,7 +1362,10 @@ bool NeedToInvertDepthRange(float near, float far)
13621362

13631363
// Clip the render area to the viewport.
13641364
gl::Rectangle viewportClippedRenderArea;
1365-
gl::ClipRectangle(renderArea, glState.getViewport(), &viewportClippedRenderArea);
1365+
if (!gl::ClipRectangle(renderArea, glState.getViewport(), &viewportClippedRenderArea))
1366+
{
1367+
viewportClippedRenderArea = gl::Rectangle();
1368+
}
13661369

13671370
gl::Rectangle scissoredArea = ClipRectToScissor(getState(), viewportClippedRenderArea, false);
13681371
if (framebufferMtl->flipY())

chromium/third_party/angle/src/libANGLE/renderer/vulkan/ContextVk.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2824,8 +2824,11 @@ angle::Result ContextVk::updateScissorImpl(const gl::State &glState, bool should
28242824

28252825
// Clip the render area to the viewport.
28262826
gl::Rectangle viewportClippedRenderArea;
2827-
gl::ClipRectangle(renderArea, getCorrectedViewport(glState.getViewport()),
2828-
&viewportClippedRenderArea);
2827+
if (!gl::ClipRectangle(renderArea, getCorrectedViewport(glState.getViewport()),
2828+
&viewportClippedRenderArea))
2829+
{
2830+
viewportClippedRenderArea = gl::Rectangle();
2831+
}
28292832

28302833
gl::Rectangle scissoredArea = ClipRectToScissor(getState(), viewportClippedRenderArea, false);
28312834
gl::Rectangle rotatedScissoredArea;

0 commit comments

Comments
 (0)