已关闭
[ArkWeb][安全][上游社区漏洞修复][BUG-536505721] fragData传参校验 #468
。创建于 18 天前关闭于 18 天前
[ArkWeb][安全][上游社区漏洞修复][BUG-536505721] fragData传参校验 #468
已关闭
共 3 个文件变更+45-0
| @@ -2784,6 +2784,22 @@ void TParseContext::functionCallRValueLValueErrorCheck(const TFunction *fnCandid | |||
| 2784 | } | 2784 | } |
| 2785 | } | 2785 | } |
| 2786 | 2786 | ||
| 2787 | +void TParseContext::functionCallFragDataCheck(const TFunction *fnCandidate, | ||
| 2788 | + TIntermAggregate *fnCall) | ||
| 2789 | +{ | ||
| 2790 | + for (size_t i = 0; i < fnCandidate->getParamCount(); ++i) | ||
| 2791 | + { | ||
| 2792 | + TIntermTyped *argument = (*fnCall->getSequence())[i]->getAsTyped(); | ||
| 2793 | + if (argument->getType().getQualifier() == EvqFragData) | ||
| 2794 | + { | ||
| 2795 | + // The whole array is passed to the function. For validation purposes, assume all | ||
| 2796 | + // indices are accessed in the function. | ||
| 2797 | + ASSERT(argument->getType().isArray()); | ||
| 2798 | + mMaxFragDataArrayIndexUsed = argument->getType().getOutermostArraySize() - 1; | ||
| 2799 | + } | ||
| 2800 | + } | ||
| 2801 | +} | ||
| 2802 | + | ||
| 2787 | void TParseContext::checkInvariantVariableQualifier(bool invariant, | 2803 | void TParseContext::checkInvariantVariableQualifier(bool invariant, |
| 2788 | const TQualifier qualifier, | 2804 | const TQualifier qualifier, |
| 2789 | const TSourceLoc &invariantLocation) | 2805 | const TSourceLoc &invariantLocation) |
| @@ -9305,6 +9321,7 @@ TIntermTyped *TParseContext::addNonConstructorFunctionCallImpl(TFunctionLookup * | |||
| 9305 | callNode->setLine(loc); | 9321 | callNode->setLine(loc); |
| 9306 | checkImageMemoryAccessForUserDefinedFunctions(fnCandidate, callNode); | 9322 | checkImageMemoryAccessForUserDefinedFunctions(fnCandidate, callNode); |
| 9307 | functionCallRValueLValueErrorCheck(fnCandidate, callNode); | 9323 | functionCallRValueLValueErrorCheck(fnCandidate, callNode); |
| 9324 | + functionCallFragDataCheck(fnCandidate, callNode); | ||
| 9308 | 9325 | ||
| 9309 | mCallGraph[mCurrentFunction].insert(fnCandidate); | 9326 | mCallGraph[mCurrentFunction].insert(fnCandidate); |
| 9310 | mIRBuilder.callFunction(mFunctionToId.at(fnCandidate)); | 9327 | mIRBuilder.callFunction(mFunctionToId.at(fnCandidate)); |
| @@ -214,6 +214,7 @@ class TParseContext : angle::NonCopyable | |||
| 214 | bool checkWorkGroupSizeIsNotSpecified(const TSourceLoc &location, | 214 | bool checkWorkGroupSizeIsNotSpecified(const TSourceLoc &location, |
| 215 | const TLayoutQualifier &layoutQualifier); | 215 | const TLayoutQualifier &layoutQualifier); |
| 216 | void functionCallRValueLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *fnCall); | 216 | void functionCallRValueLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *fnCall); |
| 217 | + void functionCallFragDataCheck(const TFunction *fnCandidate, TIntermAggregate *fnCall); | ||
| 217 | void checkInvariantVariableQualifier(bool invariant, | 218 | void checkInvariantVariableQualifier(bool invariant, |
| 218 | const TQualifier qualifier, | 219 | const TQualifier qualifier, |
| 219 | const TSourceLoc &invariantLocation); | 220 | const TSourceLoc &invariantLocation); |
| @@ -4385,6 +4385,33 @@ void main() { | |||
| 4385 | "GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT when gl_SecondaryFragDataEXT is used"); | 4385 | "GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT when gl_SecondaryFragDataEXT is used"); |
| 4386 | } | 4386 | } |
| 4387 | 4387 | ||
| 4388 | +// Shader that writes to SecondaryFragData and passes FragData to a function. | ||
| 4389 | +TEST_P(GLSLValidationTest, BlendFuncExtendedPassFragDataToFunction) | ||
| 4390 | +{ | ||
| 4391 | + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_blend_func_extended")); | ||
| 4392 | + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_draw_buffers")); | ||
| 4393 | + | ||
| 4394 | + GLint maxDrawBuffers = 0, maxDualSourceDrawBuffers = 0; | ||
| 4395 | + glGetIntegerv(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT, &maxDualSourceDrawBuffers); | ||
| 4396 | + glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers); | ||
| 4397 | + ANGLE_SKIP_TEST_IF(maxDualSourceDrawBuffers == maxDrawBuffers); | ||
| 4398 | + | ||
| 4399 | + constexpr char kFS[] = R"(#extension GL_EXT_draw_buffers : require | ||
| 4400 | + | ||
| 4401 | +precision mediump float; | ||
| 4402 | +void f(out vec4 fragData[gl_MaxDrawBuffers]) | ||
| 4403 | +{ | ||
| 4404 | + fragData[0] = vec4(0.1); | ||
| 4405 | +} | ||
| 4406 | +void main() { | ||
| 4407 | + f(gl_FragData); | ||
| 4408 | + gl_SecondaryFragDataEXT[0] = vec4(1.0); | ||
| 4409 | +})"; | ||
| 4410 | + validateError(GL_FRAGMENT_SHADER, kFS, | ||
| 4411 | + "array index for gl_FragData must be less than " | ||
| 4412 | + "GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT when gl_SecondaryFragDataEXT is used"); | ||
| 4413 | +} | ||
| 4414 | + | ||
| 4388 | // Shader that writes to FragData at an index >= than gl_MaxDualSourceDrawBuffersEXT is fine if | 4415 | // Shader that writes to FragData at an index >= than gl_MaxDualSourceDrawBuffersEXT is fine if |
| 4389 | // SecondaryFragData is not used. | 4416 | // SecondaryFragData is not used. |
| 4390 | TEST_P(GLSLValidationTest, BlendFuncExtendedDataArrayOnly) | 4417 | TEST_P(GLSLValidationTest, BlendFuncExtendedDataArrayOnly) |