Tighten when signal trap is used in SPIRV-Cross fuzzers

Due the jump within the signal trap used in these fuzzers, local scope
allocations cannot occur while the signal trap is on, otherwise there
is a possibility of leaks. This CL rewrites how the code under test is
run, so that the potentially aborting code is tightly wrapped by
signal trap without any local scope allocations.

BUG=chromium:906416

Change-Id: Ie52647433dcac57e3ea065d5bdcb6e14c5929494
Reviewed-on: https://dawn-review.googlesource.com/c/2521
Commit-Queue: Ryan Harrison <rharrison@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
Ryan Harrison 2018-11-19 19:20:08 +00:00 committed by Commit Bot service account
parent 391c8a9224
commit fbeca676d4
8 changed files with 87 additions and 47 deletions

View File

@ -52,29 +52,32 @@ namespace {
namespace DawnSPIRVCrossFuzzer { namespace DawnSPIRVCrossFuzzer {
int Run(const uint8_t* data, size_t size, std::function<int(std::vector<uint32_t>)> task) { void ExecuteWithSignalTrap(std::function<void()> exec) {
if (!data || size < 1)
return 0;
std::vector<uint32_t> input(data, data + (4 * (size / 4)));
BeginSIGABRTTrap(); BeginSIGABRTTrap();
// On the first pass through setjmp will return 0, if returning here // On the first pass through setjmp will return 0, if returning here
// from the longjmp in the signal handler it will return 1. // from the longjmp in the signal handler it will return 1.
if (setjmp(jump_buffer) == 0) { if (setjmp(jump_buffer) == 0) {
task(input); exec();
} }
EndSIGABRTTrap(); EndSIGABRTTrap();
}
int Run(const uint8_t* data, size_t size, Task task) {
if (!data || size < 1)
return 0;
size_t sizeInU32 = size / sizeof(uint32_t);
const uint32_t* u32Data = reinterpret_cast<const uint32_t*>(data);
std::vector<uint32_t> input(u32Data, u32Data + sizeInU32);
task(input);
return 0; return 0;
} }
template <class Options> template <class Options>
int RunWithOptions(const uint8_t* data, int RunWithOptions(const uint8_t* data, size_t size, TaskWithOptions<Options> task) {
size_t size,
std::function<int(std::vector<uint32_t>, Options)> task) {
if (!data || size < sizeof(Options) + 1) if (!data || size < sizeof(Options) + 1)
return 0; return 0;
@ -84,15 +87,7 @@ namespace DawnSPIRVCrossFuzzer {
std::vector<uint32_t> input(data, data + (4 * (size / 4))); std::vector<uint32_t> input(data, data + (4 * (size / 4)));
BeginSIGABRTTrap(); task(input, options);
// On the first pass through setjmp will return 0, if returning here
// from the longjmp in the signal handler it will return 1.
if (setjmp(jump_buffer) == 0) {
task(input, options);
}
EndSIGABRTTrap();
return 0; return 0;
} }

View File

@ -26,9 +26,13 @@ namespace DawnSPIRVCrossFuzzer {
spirv_cross::CompilerHLSL::Options hlsl; spirv_cross::CompilerHLSL::Options hlsl;
}; };
using Task = std::function<int(std::vector<uint32_t>)>; using Task = std::function<int(const std::vector<uint32_t>&)>;
template <class Options> template <class Options>
using TaskWithOptions = std::function<int(std::vector<uint32_t>, Options)>; using TaskWithOptions = std::function<int(const std::vector<uint32_t>&, Options)>;
// Used to wrap code that may fire a SIGABRT. Do not allocate anything local within |exec|, as
// it is not guaranteed to return.
void ExecuteWithSignalTrap(std::function<void()> exec);
// Used to fuzz by mutating the input data, but with fixed options to the compiler // Used to fuzz by mutating the input data, but with fixed options to the compiler
int Run(const uint8_t* data, size_t size, Task task); int Run(const uint8_t* data, size_t size, Task task);

View File

@ -20,15 +20,22 @@
namespace { namespace {
int GLSLFastFuzzTask(std::vector<uint32_t> input) { int GLSLFastFuzzTask(const std::vector<uint32_t>& input) {
spirv_cross::CompilerGLSL compiler(input); std::unique_ptr<spirv_cross::CompilerGLSL> compiler;
DawnSPIRVCrossFuzzer::ExecuteWithSignalTrap([&compiler, input]() {
compiler = std::make_unique<spirv_cross::CompilerGLSL>(input);
});
if (compiler == nullptr) {
return 0;
}
// Using the options that are used by Dawn, they appear in ShaderModuleGL.cpp // Using the options that are used by Dawn, they appear in ShaderModuleGL.cpp
spirv_cross::CompilerGLSL::Options options; spirv_cross::CompilerGLSL::Options options;
options.version = 440; options.version = 440;
compiler.set_common_options(options); compiler->set_common_options(options);
DawnSPIRVCrossFuzzer::ExecuteWithSignalTrap([&compiler]() { compiler->compile(); });
std::string result = compiler.compile();
return 0; return 0;
} }

View File

@ -20,11 +20,19 @@
namespace { namespace {
int GLSLFullFuzzTask(std::vector<uint32_t> input, spirv_cross::CompilerGLSL::Options options) { int GLSLFullFuzzTask(const std::vector<uint32_t>& input,
spirv_cross::CompilerGLSL compiler(input); spirv_cross::CompilerGLSL::Options options) {
compiler.set_common_options(options); std::unique_ptr<spirv_cross::CompilerGLSL> compiler;
DawnSPIRVCrossFuzzer::ExecuteWithSignalTrap([&compiler, input]() {
compiler = std::make_unique<spirv_cross::CompilerGLSL>(input);
});
if (compiler == nullptr) {
return 0;
}
std::string result = compiler.compile(); compiler->set_common_options(options);
DawnSPIRVCrossFuzzer::ExecuteWithSignalTrap([&compiler]() { compiler->compile(); });
return 0; return 0;
} }

View File

@ -22,20 +22,27 @@
namespace { namespace {
int FuzzTask(std::vector<uint32_t> input) { int FuzzTask(const std::vector<uint32_t>& input) {
spirv_cross::CompilerHLSL compiler(input); std::unique_ptr<spirv_cross::CompilerHLSL> compiler;
DawnSPIRVCrossFuzzer::ExecuteWithSignalTrap([&compiler, input]() {
compiler = std::make_unique<spirv_cross::CompilerHLSL>(input);
});
if (compiler == nullptr) {
return 0;
}
// Using the options that are used by Dawn, they appear in ShaderModuleD3D12.cpp // Using the options that are used by Dawn, they appear in ShaderModuleD3D12.cpp
spirv_cross::CompilerGLSL::Options options_glsl; spirv_cross::CompilerGLSL::Options options_glsl;
options_glsl.vertex.fixup_clipspace = true; options_glsl.vertex.fixup_clipspace = true;
options_glsl.vertex.flip_vert_y = true; options_glsl.vertex.flip_vert_y = true;
compiler.set_common_options(options_glsl); compiler->set_common_options(options_glsl);
spirv_cross::CompilerHLSL::Options options_hlsl; spirv_cross::CompilerHLSL::Options options_hlsl;
options_hlsl.shader_model = 51; options_hlsl.shader_model = 51;
compiler.set_hlsl_options(options_hlsl); compiler->set_hlsl_options(options_hlsl);
DawnSPIRVCrossFuzzer::ExecuteWithSignalTrap([&compiler]() { compiler->compile(); });
std::string result = compiler.compile();
return 0; return 0;
} }

View File

@ -21,13 +21,20 @@
#include "spirv-cross/spirv_hlsl.hpp" #include "spirv-cross/spirv_hlsl.hpp"
namespace { namespace {
int FuzzTask(std::vector<uint32_t> input, DawnSPIRVCrossFuzzer::CombinedOptions options) { int FuzzTask(const std::vector<uint32_t>& input,
spirv_cross::CompilerHLSL compiler(input); DawnSPIRVCrossFuzzer::CombinedOptions options) {
std::unique_ptr<spirv_cross::CompilerHLSL> compiler;
DawnSPIRVCrossFuzzer::ExecuteWithSignalTrap([&compiler, input]() {
compiler = std::make_unique<spirv_cross::CompilerHLSL>(input);
});
if (compiler == nullptr) {
return 0;
}
compiler.set_common_options(options.glsl); compiler->set_common_options(options.glsl);
compiler.set_hlsl_options(options.hlsl); compiler->set_hlsl_options(options.hlsl);
std::string result = compiler.compile(); DawnSPIRVCrossFuzzer::ExecuteWithSignalTrap([&compiler]() { compiler->compile(); });
return 0; return 0;
} }

View File

@ -22,15 +22,21 @@
namespace { namespace {
int FuzzTask(std::vector<uint32_t> input) { int FuzzTask(const std::vector<uint32_t>& input) {
spirv_cross::CompilerMSL compiler(input); std::unique_ptr<spirv_cross::CompilerMSL> compiler;
DawnSPIRVCrossFuzzer::ExecuteWithSignalTrap(
[&compiler, input]() { compiler = std::make_unique<spirv_cross::CompilerMSL>(input); });
if (compiler == nullptr) {
return 0;
}
// Using the options that are used by Dawn, they appear in ShaderModuleMTL.mm // Using the options that are used by Dawn, they appear in ShaderModuleMTL.mm
spirv_cross::CompilerGLSL::Options options; spirv_cross::CompilerGLSL::Options options;
options.vertex.flip_vert_y = true; options.vertex.flip_vert_y = true;
compiler.spirv_cross::CompilerGLSL::set_common_options(options); compiler->spirv_cross::CompilerGLSL::set_common_options(options);
DawnSPIRVCrossFuzzer::ExecuteWithSignalTrap([&compiler]() { compiler->compile(); });
std::string result = compiler.compile();
return 0; return 0;
} }

View File

@ -22,12 +22,18 @@
namespace { namespace {
int FuzzTask(std::vector<uint32_t> input, spirv_cross::CompilerGLSL::Options options) { int FuzzTask(const std::vector<uint32_t>& input, spirv_cross::CompilerGLSL::Options options) {
spirv_cross::CompilerMSL compiler(input); std::unique_ptr<spirv_cross::CompilerMSL> compiler;
DawnSPIRVCrossFuzzer::ExecuteWithSignalTrap(
[&compiler, input]() { compiler = std::make_unique<spirv_cross::CompilerMSL>(input); });
if (compiler == nullptr) {
return 0;
}
compiler.spirv_cross::CompilerGLSL::set_common_options(options); compiler->spirv_cross::CompilerGLSL::set_common_options(options);
DawnSPIRVCrossFuzzer::ExecuteWithSignalTrap([&compiler]() { compiler->compile(); });
std::string result = compiler.compile();
return 0; return 0;
} }