mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2025-01-11 09:00:06 +00:00
spirv-fuzz: Do not allow adding stores to read-only pointers (#3316)
Re-uses IsReadOnlyPointer functionality for the optimizer to make the check that avoids storing through read-only pointers more thorough.
This commit is contained in:
parent
54fb17b2d3
commit
2e1d208ed9
@ -68,9 +68,8 @@ void FuzzerPassAddStores::Apply() {
|
||||
// Not a pointer.
|
||||
return false;
|
||||
}
|
||||
if (type_inst->GetSingleWordInOperand(0) ==
|
||||
SpvStorageClassInput) {
|
||||
// Read-only: cannot store to it.
|
||||
if (instruction->IsReadOnlyPointer()) {
|
||||
// Read only: cannot store to it.
|
||||
return false;
|
||||
}
|
||||
switch (instruction->result_id()) {
|
||||
|
@ -50,7 +50,7 @@ bool TransformationStore::IsApplicable(
|
||||
}
|
||||
|
||||
// The pointer must not be read only.
|
||||
if (pointer_type->GetSingleWordInOperand(0) == SpvStorageClassInput) {
|
||||
if (pointer->IsReadOnlyPointer()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -351,6 +351,70 @@ TEST(TransformationStoreTest, BasicTest) {
|
||||
ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
|
||||
}
|
||||
|
||||
TEST(TransformationStoreTest, DoNotAllowStoresToReadOnlyMemory) {
|
||||
std::string shader = R"(
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %4 "main"
|
||||
OpExecutionMode %4 OriginUpperLeft
|
||||
OpSource ESSL 320
|
||||
OpMemberDecorate %10 0 Offset 0
|
||||
OpMemberDecorate %10 1 Offset 4
|
||||
OpDecorate %10 Block
|
||||
OpMemberDecorate %23 0 Offset 0
|
||||
OpDecorate %23 Block
|
||||
OpDecorate %25 DescriptorSet 0
|
||||
OpDecorate %25 Binding 0
|
||||
%2 = OpTypeVoid
|
||||
%3 = OpTypeFunction %2
|
||||
%6 = OpTypeInt 32 1
|
||||
%7 = OpTypePointer Function %6
|
||||
%9 = OpTypeFloat 32
|
||||
%10 = OpTypeStruct %6 %9
|
||||
%11 = OpTypePointer PushConstant %10
|
||||
%12 = OpVariable %11 PushConstant
|
||||
%13 = OpConstant %6 0
|
||||
%14 = OpTypePointer PushConstant %6
|
||||
%17 = OpConstant %6 1
|
||||
%18 = OpTypePointer PushConstant %9
|
||||
%23 = OpTypeStruct %9
|
||||
%24 = OpTypePointer UniformConstant %23
|
||||
%25 = OpVariable %24 UniformConstant
|
||||
%26 = OpTypePointer UniformConstant %9
|
||||
%50 = OpConstant %9 0
|
||||
%4 = OpFunction %2 None %3
|
||||
%5 = OpLabel
|
||||
%15 = OpAccessChain %14 %12 %13
|
||||
%19 = OpAccessChain %18 %12 %17
|
||||
%27 = OpAccessChain %26 %25 %13
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
const auto env = SPV_ENV_UNIVERSAL_1_3;
|
||||
const auto consumer = nullptr;
|
||||
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
|
||||
ASSERT_TRUE(IsValid(env, context.get()));
|
||||
|
||||
FactManager fact_manager;
|
||||
spvtools::ValidatorOptions validator_options;
|
||||
TransformationContext transformation_context(&fact_manager,
|
||||
validator_options);
|
||||
|
||||
fact_manager.AddFactBlockIsDead(5);
|
||||
|
||||
ASSERT_FALSE(
|
||||
TransformationStore(15, 13, MakeInstructionDescriptor(27, SpvOpReturn, 0))
|
||||
.IsApplicable(context.get(), transformation_context));
|
||||
ASSERT_FALSE(
|
||||
TransformationStore(19, 50, MakeInstructionDescriptor(27, SpvOpReturn, 0))
|
||||
.IsApplicable(context.get(), transformation_context));
|
||||
ASSERT_FALSE(
|
||||
TransformationStore(27, 50, MakeInstructionDescriptor(27, SpvOpReturn, 0))
|
||||
.IsApplicable(context.get(), transformation_context));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace fuzz
|
||||
} // namespace spvtools
|
||||
|
Loading…
Reference in New Issue
Block a user