Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(648)

Side by Side Diff: tools/pnacl-bcfuzz/pnacl-bcfuzz.cpp

Issue 1156103003: Initial implementation of a record-level bitcode fuzzer. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-llvm.git@fuzz
Patch Set: Fix issues in last patch Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 //===-- pnacl-bcfuzz.cpp - Record fuzzer for PNaCl bitcode ----------------===//
2 //
jvoung (off chromium) 2015/06/02 16:14:03 // The LLVM Compiler Infrastru
Karl 2015/06/02 16:40:23 Done.
3 //===----------------------------------------------------------------------===//
4 //
5 // Generates (record-level) fuzzed PNaCl bitcode files from an input
6 // PNaCl bitcode file.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "llvm/Bitcode/NaCl/NaClFuzz.h"
11 #include "llvm/Support/CommandLine.h"
12 #include "llvm/Support/FileSystem.h"
13 #include "llvm/Support/ManagedStatic.h"
14 #include "llvm/Support/MemoryBuffer.h"
15 #include "llvm/Support/PrettyStackTrace.h"
16 #include "llvm/Support/Signals.h"
17 #include "llvm/Support/ToolOutputFile.h"
18
19 using namespace llvm;
20 using namespace naclfuzz;
21
22 static cl::opt<std::string>
23 InputFilename(cl::Positional, cl::desc("<frozen file>"), cl::init("-"));
24
25 static cl::opt<std::string>
26 OutputPrefix("output", cl::desc("<output prefix>"), cl::init(""));
27
28 static cl::opt<unsigned>
29 FuzzCount("count", cl::desc("Number of fuzz results to generate"),
30 cl::init(1));
31
32 static cl::opt<std::string>
33 RandomSeed("random-seed",
34 cl::desc("Use this value for seed of random number generator "
35 "(rather than input)"),
36 cl::init(""));
37
38 static cl::opt<bool>
39 ShowFuzzRecordDistribution(
40 "record-distribution",
41 cl::desc("Show distribution of record edits while fuzzing"),
42 cl::init(false));
43
44 static cl::opt<bool>
45 ShowFuzzEditDistribution(
46 "edit-distribution",
47 cl::desc("Show distribution of editing actions while fuzzing"),
48 cl::init(false));
49
50 static cl::opt<unsigned>
51 PercentageToEdit(
52 "edit-percentage",
53 cl::desc("Percentage of records to edit during fuzz (between 1 and"
54 " '-percentage-base')"),
55 cl::init(1));
56
57 static cl::opt<unsigned>
58 PercentageBase(
59 "percentage-base",
60 cl::desc("Base that '-edit-precentage' is defined on (defaults to 100)"),
61 cl::init(100));
62
63 static cl::opt<bool>
64 Verbose("verbose",
65 cl::desc("Show details of fuzzing/writing of bitcode files"),
66 cl::init(false));
67
68 static void WriteOutputFile(SmallVectorImpl<char> &Buffer,
69 StringRef OutputFilename) {
70 std::error_code EC;
71 std::unique_ptr<tool_output_file> Out(
72 new tool_output_file(OutputFilename, EC, sys::fs::F_None));
73 if (EC) {
74 errs() << EC.message() << '\n';
75 exit(1);
76 }
77
78 for (SmallVectorImpl<char>::const_iterator
79 Iter = Buffer.begin(), IterEnd = Buffer.end();
80 Iter != IterEnd; ++Iter) {
81 Out->os() << *Iter;
82 }
83
84 // Declare success.
85 Out->keep();
86 }
87
88 int main(int argc, char **argv) {
89 // Print a stack trace if we signal out.
90 sys::PrintStackTraceOnErrorSignal();
91 PrettyStackTraceProgram X(argc, argv);
92
93 cl::ParseCommandLineOptions(argc, argv, "Fuzz a PNaCl bitcode file\n");
94
95 if (PercentageToEdit > PercentageBase) {
96 errs() << "Edit percentage " << PercentageToEdit
97 << " must not exceed percentage to edit: "
98 << PercentageToEdit << "\n";
jvoung (off chromium) 2015/06/02 16:14:03 "... must not exceed: " << PercentageBase or some
Karl 2015/06/02 16:40:23 Done.
99 return 1;
100 }
101
102 if (OutputPrefix.empty()) {
103 errs() << "Output prefix not specified!\n";
104 return 1;
105 }
106
107 ErrorOr<std::unique_ptr<MemoryBuffer>>
108 MemBuf(MemoryBuffer::getFile(InputFilename));
109 if (!MemBuf) {
110 errs() << MemBuf.getError().message() << "\n";
111 return 1;
112 }
113
114 // Stream to dump bitcode write errors to if not verbose.
115 raw_null_ostream NullStrm;
116
117 NaClMungedBitcode Bitcode(std::move(MemBuf.get()));
118
119 std::string RandSeed(RandomSeed);
120 if (RandomSeed.empty())
121 RandSeed = InputFilename;
122
123 DefaultRandomNumberGenerator Generator(RandSeed);
124 std::unique_ptr<RecordFuzzer> Fuzzer(
125 RecordFuzzer::createSimpleRecordFuzzer(Bitcode, Generator));
126
127 for (size_t i = 1; i <= FuzzCount; ++i) {
128 Generator.saltSeed(i);
129 std::string OutputFile;
130 {
131 raw_string_ostream StrBuf(OutputFile);
132 StrBuf << OutputPrefix << "-" << i;
133 StrBuf.flush();
134 }
135
136 if (Verbose)
137 errs() << "Generating " << OutputFile << "\n";
138
139 if (!Fuzzer->fuzz(PercentageToEdit, PercentageBase)) {
140 errs() << "Error: Fuzzing failed: " << OutputFile << "\n";
141 continue;
142 }
143
144 if (Verbose) {
145 errs() << "Records:\n";
146 for (const auto &Record : Bitcode) {
147 errs() << " " << Record << "\n";
148 }
149 }
150
151 SmallVector<char, 100> Buffer;
152 NaClMungedBitcode::WriteFlags WriteFlags;
153 WriteFlags.setTryToRecover(true);
154 if (!Verbose) {
155 WriteFlags.setErrStream(NullStrm);
156 }
157 if (!Bitcode.write(Buffer, true, WriteFlags)) {
158 errs() << "Error: Failed to write fuzzed code: "
159 << OutputFile << "\n";
160 continue;
161 }
162 WriteOutputFile(Buffer, OutputFile);
163 }
164
165
166 if (ShowFuzzRecordDistribution)
167 Fuzzer->showRecordDistribution(outs());
168 if (ShowFuzzEditDistribution)
169 Fuzzer->showEditDistribution(outs());
170
171 return 0;
172 }
OLDNEW
« tools/pnacl-bcfuzz/LLVMBuild.txt ('K') | « tools/pnacl-bcfuzz/Makefile ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698