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:
Alastair Donaldson 2020-05-01 02:50:44 +01:00 committed by GitHub
parent 54fb17b2d3
commit 2e1d208ed9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 67 additions and 4 deletions

View File

@ -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()) {

View File

@ -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;
}

View File

@ -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