diff options
| author | Igor Laevsky <igmyrj@gmail.com> | 2018-02-05 11:05:47 +0000 |
|---|---|---|
| committer | Igor Laevsky <igmyrj@gmail.com> | 2018-02-05 11:05:47 +0000 |
| commit | 14c979da329daf35ebc99a0bd11581b0b081d813 (patch) | |
| tree | 4a3c50fbcfd39f0be4401291f983596053ca6b71 /llvm/tools/llvm-opt-fuzzer | |
| parent | 401df580641bd6be73d37a0dbb65e7348263fd8a (diff) | |
| download | bcm5719-llvm-14c979da329daf35ebc99a0bd11581b0b081d813.tar.gz bcm5719-llvm-14c979da329daf35ebc99a0bd11581b0b081d813.zip | |
[llvm-opt-fuzzer] Avoid adding incorrect inputs to the fuzzer corpus
Differential Revision: https://reviews.llvm.org/D42414
llvm-svn: 324225
Diffstat (limited to 'llvm/tools/llvm-opt-fuzzer')
| -rw-r--r-- | llvm/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp | 38 |
1 files changed, 30 insertions, 8 deletions
diff --git a/llvm/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp b/llvm/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp index 8187bbcea66..39909ecd4e0 100644 --- a/llvm/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp +++ b/llvm/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp @@ -57,23 +57,45 @@ extern "C" LLVM_ATTRIBUTE_USED size_t LLVMFuzzerCustomMutator( "IR mutator should have been created during fuzzer initialization"); LLVMContext Context; - auto M = parseModule(Data, Size, Context); - if (!M || verifyModule(*M, &errs())) { + auto M = parseAndVerify(Data, Size, Context); + if (!M) { errs() << "error: mutator input module is broken!\n"; return 0; } Mutator->mutateModule(*M, Seed, Size, MaxSize); -#ifndef NDEBUG if (verifyModule(*M, &errs())) { errs() << "mutation result doesn't pass verification\n"; M->dump(); - abort(); + // Avoid adding incorrect test cases to the corpus. + return 0; + } + + std::string Buf; + { + raw_string_ostream OS(Buf); + WriteBitcodeToFile(M.get(), OS); + } + if (Buf.size() > MaxSize) + return 0; + + // There are some invariants which are not checked by the verifier in favor + // of having them checked by the parser. They may be considered as bugs in the + // verifier and should be fixed there. However until all of those are covered + // we want to check for them explicitly. Otherwise we will add incorrect input + // to the corpus and this is going to confuse the fuzzer which will start + // exploration of the bitcode reader error handling code. + auto NewM = parseAndVerify( + reinterpret_cast<const uint8_t*>(Buf.data()), Buf.size(), Context); + if (!NewM) { + errs() << "mutator failed to re-read the module\n"; + M->dump(); + return 0; } -#endif - return writeModule(*M, Data, MaxSize); + memcpy(Data, Buf.data(), Buf.size()); + return Buf.size(); } extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { @@ -87,8 +109,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { // LLVMContext Context; - auto M = parseModule(Data, Size, Context); - if (!M || verifyModule(*M, &errs())) { + auto M = parseAndVerify(Data, Size, Context); + if (!M) { errs() << "error: input module is broken!\n"; return 0; } |

