[llvm] r324225 - [llvm-opt-fuzzer] Avoid adding incorrect inputs to the fuzzer corpus
Igor Laevsky via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 5 03:05:47 PST 2018
Author: igor.laevsky
Date: Mon Feb 5 03:05:47 2018
New Revision: 324225
URL: http://llvm.org/viewvc/llvm-project?rev=324225&view=rev
Log:
[llvm-opt-fuzzer] Avoid adding incorrect inputs to the fuzzer corpus
Differential Revision: https://reviews.llvm.org/D42414
Modified:
llvm/trunk/include/llvm/FuzzMutate/FuzzerCLI.h
llvm/trunk/lib/FuzzMutate/FuzzerCLI.cpp
llvm/trunk/tools/llvm-isel-fuzzer/llvm-isel-fuzzer.cpp
llvm/trunk/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp
Modified: llvm/trunk/include/llvm/FuzzMutate/FuzzerCLI.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/FuzzMutate/FuzzerCLI.h?rev=324225&r1=324224&r2=324225&view=diff
==============================================================================
--- llvm/trunk/include/llvm/FuzzMutate/FuzzerCLI.h (original)
+++ llvm/trunk/include/llvm/FuzzMutate/FuzzerCLI.h Mon Feb 5 03:05:47 2018
@@ -68,6 +68,12 @@ std::unique_ptr<Module> parseModule(cons
/// returns 0 and leaves Dest unchanged.
size_t writeModule(const Module &M, uint8_t *Dest, size_t MaxSize);
+/// Try to parse module and verify it. May output verification errors to the
+/// errs().
+/// \return New module or nullptr in case of error.
+std::unique_ptr<Module> parseAndVerify(const uint8_t *Data, size_t Size,
+ LLVMContext &Context);
+
} // end llvm namespace
#endif // LLVM_FUZZMUTATE_FUZZER_CLI_H
Modified: llvm/trunk/lib/FuzzMutate/FuzzerCLI.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/FuzzMutate/FuzzerCLI.cpp?rev=324225&r1=324224&r2=324225&view=diff
==============================================================================
--- llvm/trunk/lib/FuzzMutate/FuzzerCLI.cpp (original)
+++ llvm/trunk/lib/FuzzMutate/FuzzerCLI.cpp Mon Feb 5 03:05:47 2018
@@ -18,6 +18,7 @@
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/IR/Verifier.h"
using namespace llvm;
@@ -175,3 +176,12 @@ size_t llvm::writeModule(const Module &M
memcpy(Dest, Buf.data(), Buf.size());
return Buf.size();
}
+
+std::unique_ptr<Module> llvm::parseAndVerify(const uint8_t *Data, size_t Size,
+ LLVMContext &Context) {
+ auto M = parseModule(Data, Size, Context);
+ if (!M || verifyModule(*M, &errs()))
+ return nullptr;
+
+ return M;
+}
Modified: llvm/trunk/tools/llvm-isel-fuzzer/llvm-isel-fuzzer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-isel-fuzzer/llvm-isel-fuzzer.cpp?rev=324225&r1=324224&r2=324225&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-isel-fuzzer/llvm-isel-fuzzer.cpp (original)
+++ llvm/trunk/tools/llvm-isel-fuzzer/llvm-isel-fuzzer.cpp Mon Feb 5 03:05:47 2018
@@ -84,8 +84,8 @@ extern "C" int LLVMFuzzerTestOneInput(co
return 0;
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;
}
Modified: llvm/trunk/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp?rev=324225&r1=324224&r2=324225&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp (original)
+++ llvm/trunk/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp Mon Feb 5 03:05:47 2018
@@ -57,23 +57,45 @@ extern "C" LLVM_ATTRIBUTE_USED size_t LL
"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(co
//
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;
}
More information about the llvm-commits
mailing list