mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2025-01-11 09:00:06 +00:00
spirv-fuzz: Disallow copying of null and undefined pointers (#3172)
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.
This commit is contained in:
parent
a9624b4d5d
commit
b7e0998e3d
@ -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.
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user