Skip to content

Commit

Permalink
spirv-fuzz: Disallow copying of null and undefined pointers (#3172)
Browse files Browse the repository at this point in the history
If the fuzzer object-copies a pointer we would like to be able to
perform loads from the copy (and stores to it, if its value is known
not to matter).  Undefined and null pointers present a problem here,
so this change disallows copying them.
  • Loading branch information
afd authored Feb 4, 2020
1 parent a9624b4 commit b7e0998
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 0 deletions.
14 changes: 14 additions & 0 deletions source/fuzz/fuzzer_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,20 @@ bool CanMakeSynonymOf(opt::IRContext* ir_context, opt::Instruction* inst) {
// We can only make a synonym of an instruction that has a type.
return false;
}
auto type_inst = ir_context->get_def_use_mgr()->GetDef(inst->type_id());
if (type_inst->opcode() == SpvOpTypePointer) {
switch (inst->opcode()) {
case SpvOpConstantNull:
case SpvOpUndef:
// We disallow making synonyms of null or undefined pointers. This is
// to provide the property that if the original shader exhibited no bad
// pointer accesses, the transformed shader will not either.
return false;
default:
break;
}
}

// We do not make synonyms of objects that have decorations: if the synonym is
// not decorated analogously, using the original object vs. its synonymous
// form may not be equivalent.
Expand Down
2 changes: 2 additions & 0 deletions source/fuzz/transformation_copy_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ class TransformationCopyObject : public Transformation {
// - It must be legal to insert an OpCopyObject instruction directly
// before 'inst'.
// - |message_.object| must be available directly before 'inst'.
// - |message_.object| must not be a null pointer or undefined pointer (so as
// to make it legal to load from copied pointers).
bool IsApplicable(opt::IRContext* context,
const FactManager& fact_manager) const override;

Expand Down
38 changes: 38 additions & 0 deletions test/fuzz/transformation_copy_object_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,44 @@ TEST(TransformationCopyObjectTest, MiscellaneousCopies) {
ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
}

TEST(TransformationCopyObjectTest, DoNotCopyNullOrUndefPointers) {
std::string shader = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main"
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeInt 32 1
%7 = OpTypePointer Function %6
%8 = OpConstantNull %7
%9 = OpUndef %7
%4 = OpFunction %2 None %3
%5 = OpLabel
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;

// Illegal to copy null.
ASSERT_FALSE(TransformationCopyObject(
8, MakeInstructionDescriptor(5, SpvOpReturn, 0), 100)
.IsApplicable(context.get(), fact_manager));

// Illegal to copy an OpUndef of pointer type.
ASSERT_FALSE(TransformationCopyObject(
9, MakeInstructionDescriptor(5, SpvOpReturn, 0), 100)
.IsApplicable(context.get(), fact_manager));
}

} // namespace
} // namespace fuzz
} // namespace spvtools

0 comments on commit b7e0998

Please sign in to comment.