已关闭
[ArkWeb][安全][上游社区漏洞修复][BUG-535379043] 帧缓冲校验修复 #471
[ArkWeb][安全][上游社区漏洞修复][BUG-535379043] 帧缓冲校验修复 #471
已关闭
。创建于 8月27日关闭于 8月28日
共 2 个文件变更+90-2
@@ -1332,10 +1332,19 @@ angle::Result FramebufferGL::ensureAttachmentsInitialized(
1332 bool depth,1332 bool depth,
1333 bool stencil)1333 bool stencil)
1334{1334{
1335- if (colorAttachments != getState().getEnabledDrawBuffers())1335+ const gl::FramebufferState &state = getState();
1336+ const gl::FramebufferAttachment *depthAttachment = state.getDepthAttachment();
1337+ const gl::FramebufferAttachment *stencilAttachment = state.getStencilAttachment();
1338+ 
1339+ const bool isPartialDepthStencilInit =
1340+ depthAttachment && stencilAttachment &&
1341+ depthAttachment->getResource() == stencilAttachment->getResource() && depth != stencil;
1342+ 
1343+ if (colorAttachments != state.getEnabledDrawBuffers() || isPartialDepthStencilInit)
1336 {1344 {
1337 // Fall back to the default implementation when there are gaps in the enabled draw buffers1345 // Fall back to the default implementation when there are gaps in the enabled draw buffers
1338- // to avoid modifying the draw buffer state.1346+ // to avoid modifying the draw buffer state, or when we are performing a partial clear of a
1347+ // packed depth-stencil attachment.
1339 return FramebufferImpl::ensureAttachmentsInitialized(context, colorAttachments, depth,1348 return FramebufferImpl::ensureAttachmentsInitialized(context, colorAttachments, depth,
1340 stencil);1349 stencil);
1341 }1350 }
@@ -2017,6 +2017,85 @@ TEST_P(RobustResourceInitTestES3, MaskedStencilClearBuffer)
2017 maskedStencilClear(clearFunc);2017 maskedStencilClear(clearFunc);
2018}2018}
2019 2019 
2020+// Test that performing a partial clear on a packed depth-stencil resource does not bypass robust
2021+// init for the other aspect.
2022+TEST_P(RobustResourceInitTestES3, PackedDepthStencilPartialClearLeaking)
2023+{
2024+ ANGLE_SKIP_TEST_IF(!hasGLExtension());
2025+ 
2026+ constexpr int kSize = 16;
2027+ 
2028+ GLRenderbuffer rb;
2029+ glBindRenderbuffer(GL_RENDERBUFFER, rb);
2030+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kSize, kSize);
2031+ 
2032+ GLFramebuffer setupFBO;
2033+ glBindFramebuffer(GL_FRAMEBUFFER, setupFBO);
2034+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
2035+ ASSERT_GL_NO_ERROR();
2036+ ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2037+ 
2038+ // Poison stencil with 0x5A
2039+ glClearStencil(0x5A);
2040+ glClear(GL_STENCIL_BUFFER_BIT);
2041+ ASSERT_GL_NO_ERROR();
2042+ 
2043+ // Invalidate to force ANGLE to re-initialize it on next use.
2044+ const GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2045+ glInvalidateFramebuffer(GL_FRAMEBUFFER, 2, attachments);
2046+ ASSERT_GL_NO_ERROR();
2047+ 
2048+ // Create a FBO with no color attachments, only depth-stencil.
2049+ GLFramebuffer dsOnlyFBO;
2050+ glBindFramebuffer(GL_FRAMEBUFFER, dsOnlyFBO);
2051+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
2052+ ASSERT_GL_NO_ERROR();
2053+ ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2054+ 
2055+ // Clear depth only.
2056+ // If bug is present, this clears depth natively, but marks both depth and stencil as
2057+ // initialized. Stencil is NOT cleared natively.
2058+ float depthClearValue = 1.0f;
2059+ glClearBufferfv(GL_DEPTH, 0, &depthClearValue);
2060+ ASSERT_GL_NO_ERROR();
2061+ 
2062+ // Bind to FBO with color attachment to verify stencil.
2063+ GLTexture colorBuffer;
2064+ glBindTexture(GL_TEXTURE_2D, colorBuffer);
2065+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2066+ 
2067+ GLFramebuffer readFBO;
2068+ glBindFramebuffer(GL_FRAMEBUFFER, readFBO);
2069+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBuffer, 0);
2070+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
2071+ ASSERT_GL_NO_ERROR();
2072+ ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2073+ 
2074+ // Clear color to blue.
2075+ glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
2076+ glClear(GL_COLOR_BUFFER_BIT);
2077+ ASSERT_GL_NO_ERROR();
2078+ 
2079+ glEnable(GL_STENCIL_TEST);
2080+ glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
2081+ 
2082+ // Draw green if stencil is 0 (expected robust init value).
2083+ glStencilFunc(GL_EQUAL, 0, 0xFF);
2084+ ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
2085+ drawQuad(drawGreen, essl1_shaders::PositionAttrib(), 0.0f);
2086+ ASSERT_GL_NO_ERROR();
2087+ 
2088+ // Draw red if stencil is 0x5A (poison value, indicates leak).
2089+ glStencilFunc(GL_EQUAL, 0x5A, 0xFF);
2090+ ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
2091+ drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.0f);
2092+ ASSERT_GL_NO_ERROR();
2093+ 
2094+ // We expect the stencil to be 0, so the final color should be green.
2095+ // If the bug is present, it might be red.
2096+ EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2097+}
2098+ 
2020template <int Size, typename InitializedTest>2099template <int Size, typename InitializedTest>
2021void VerifyRGBA8PixelRect(InitializedTest inInitialized)2100void VerifyRGBA8PixelRect(InitializedTest inInitialized)
2022{2101{