已关闭
[ArkWeb][安全][上游社区漏洞修复][BUG-535379043] 帧缓冲校验修复 #471
。创建于 8月27日关闭于 8月28日
[ArkWeb][安全][上游社区漏洞修复][BUG-535379043] 帧缓冲校验修复 #471
已关闭
共 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 buffers | 1345 | // 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 | + | ||
| 2020 | template <int Size, typename InitializedTest> | 2099 | template <int Size, typename InitializedTest> |
| 2021 | void VerifyRGBA8PixelRect(InitializedTest inInitialized) | 2100 | void VerifyRGBA8PixelRect(InitializedTest inInitialized) |
| 2022 | { | 2101 | { |