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 {
int Run(const uint8_t* data, size_t size, std::function<int(std::vector<uint32_t>)> task) {
if (!data || size < 1)
return 0;
std::vector<uint32_t> input(data, data + (4 * (size / 4)));
void ExecuteWithSignalTrap(std::function<void()> exec) {
BeginSIGABRTTrap();
// 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);
exec();
}
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;
}
template <class Options>
int RunWithOptions(const uint8_t* data,
size_t size,
std::function<int(std::vector<uint32_t>, Options)> task) {
int RunWithOptions(const uint8_t* data, size_t size, TaskWithOptions<Options> task) {
if (!data || size < sizeof(Options) + 1)
return 0;
@ -84,15 +87,7 @@ namespace DawnSPIRVCrossFuzzer {
std::vector<uint32_t> input(data, data + (4 * (size / 4)));
BeginSIGABRTTrap();
// 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();
task(input, options);
return 0;
}

View File

@ -26,9 +26,13 @@ namespace DawnSPIRVCrossFuzzer {
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>
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
int Run(const uint8_t* data, size_t size, Task task);

View File

@ -20,15 +20,22 @@
namespace {
int GLSLFastFuzzTask(std::vector<uint32_t> input) {
spirv_cross::CompilerGLSL compiler(input);
int GLSLFastFuzzTask(const std::vector<uint32_t>& 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
spirv_cross::CompilerGLSL::Options options;
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;
}

View File

@ -20,11 +20,19 @@
namespace {
int GLSLFullFuzzTask(std::vector<uint32_t> input, spirv_cross::CompilerGLSL::Options options) {
spirv_cross::CompilerGLSL compiler(input);
compiler.set_common_options(options);
int GLSLFullFuzzTask(const std::vector<uint32_t>& input,
spirv_cross::CompilerGLSL::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;
}

View File

@ -22,20 +22,27 @@
namespace {
int FuzzTask(std::vector<uint32_t> input) {
spirv_cross::CompilerHLSL compiler(input);
int FuzzTask(const std::vector<uint32_t>& 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
spirv_cross::CompilerGLSL::Options options_glsl;
options_glsl.vertex.fixup_clipspace = 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;
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;
}

View File

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

View File

@ -22,15 +22,21 @@
namespace {
int FuzzTask(std::vector<uint32_t> input) {
spirv_cross::CompilerMSL compiler(input);
int FuzzTask(const std::vector<uint32_t>& 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
spirv_cross::CompilerGLSL::Options options;
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;
}

View File

@ -22,12 +22,18 @@
namespace {
int FuzzTask(std::vector<uint32_t> input, spirv_cross::CompilerGLSL::Options options) {
spirv_cross::CompilerMSL compiler(input);
int FuzzTask(const std::vector<uint32_t>& input, spirv_cross::CompilerGLSL::Options options) {
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;
}