1*08b48e0bSAndroid Build Coastguard Worker #define AFL_LLVM_PASS
2*08b48e0bSAndroid Build Coastguard Worker
3*08b48e0bSAndroid Build Coastguard Worker #include "config.h"
4*08b48e0bSAndroid Build Coastguard Worker #include "debug.h"
5*08b48e0bSAndroid Build Coastguard Worker
6*08b48e0bSAndroid Build Coastguard Worker #include <stdio.h>
7*08b48e0bSAndroid Build Coastguard Worker #include <stdlib.h>
8*08b48e0bSAndroid Build Coastguard Worker #include <unistd.h>
9*08b48e0bSAndroid Build Coastguard Worker #include <sys/time.h>
10*08b48e0bSAndroid Build Coastguard Worker #include <fnmatch.h>
11*08b48e0bSAndroid Build Coastguard Worker
12*08b48e0bSAndroid Build Coastguard Worker #include <list>
13*08b48e0bSAndroid Build Coastguard Worker #include <string>
14*08b48e0bSAndroid Build Coastguard Worker #include <fstream>
15*08b48e0bSAndroid Build Coastguard Worker #include <cmath>
16*08b48e0bSAndroid Build Coastguard Worker
17*08b48e0bSAndroid Build Coastguard Worker #include <llvm/Support/raw_ostream.h>
18*08b48e0bSAndroid Build Coastguard Worker
19*08b48e0bSAndroid Build Coastguard Worker #define IS_EXTERN extern
20*08b48e0bSAndroid Build Coastguard Worker #include "afl-llvm-common.h"
21*08b48e0bSAndroid Build Coastguard Worker
22*08b48e0bSAndroid Build Coastguard Worker using namespace llvm;
23*08b48e0bSAndroid Build Coastguard Worker
24*08b48e0bSAndroid Build Coastguard Worker static std::list<std::string> allowListFiles;
25*08b48e0bSAndroid Build Coastguard Worker static std::list<std::string> allowListFunctions;
26*08b48e0bSAndroid Build Coastguard Worker static std::list<std::string> denyListFiles;
27*08b48e0bSAndroid Build Coastguard Worker static std::list<std::string> denyListFunctions;
28*08b48e0bSAndroid Build Coastguard Worker
getBBName(const llvm::BasicBlock * BB)29*08b48e0bSAndroid Build Coastguard Worker char *getBBName(const llvm::BasicBlock *BB) {
30*08b48e0bSAndroid Build Coastguard Worker
31*08b48e0bSAndroid Build Coastguard Worker static char *name;
32*08b48e0bSAndroid Build Coastguard Worker
33*08b48e0bSAndroid Build Coastguard Worker if (!BB->getName().empty()) {
34*08b48e0bSAndroid Build Coastguard Worker
35*08b48e0bSAndroid Build Coastguard Worker name = strdup(BB->getName().str().c_str());
36*08b48e0bSAndroid Build Coastguard Worker return name;
37*08b48e0bSAndroid Build Coastguard Worker
38*08b48e0bSAndroid Build Coastguard Worker }
39*08b48e0bSAndroid Build Coastguard Worker
40*08b48e0bSAndroid Build Coastguard Worker std::string Str;
41*08b48e0bSAndroid Build Coastguard Worker raw_string_ostream OS(Str);
42*08b48e0bSAndroid Build Coastguard Worker
43*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 4 || \
44*08b48e0bSAndroid Build Coastguard Worker (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 7)
45*08b48e0bSAndroid Build Coastguard Worker BB->printAsOperand(OS, false);
46*08b48e0bSAndroid Build Coastguard Worker #endif
47*08b48e0bSAndroid Build Coastguard Worker name = strdup(OS.str().c_str());
48*08b48e0bSAndroid Build Coastguard Worker return name;
49*08b48e0bSAndroid Build Coastguard Worker
50*08b48e0bSAndroid Build Coastguard Worker }
51*08b48e0bSAndroid Build Coastguard Worker
52*08b48e0bSAndroid Build Coastguard Worker /* Function that we never instrument or analyze */
53*08b48e0bSAndroid Build Coastguard Worker /* Note: this ignore check is also called in isInInstrumentList() */
isIgnoreFunction(const llvm::Function * F)54*08b48e0bSAndroid Build Coastguard Worker bool isIgnoreFunction(const llvm::Function *F) {
55*08b48e0bSAndroid Build Coastguard Worker
56*08b48e0bSAndroid Build Coastguard Worker // Starting from "LLVMFuzzer" these are functions used in libfuzzer based
57*08b48e0bSAndroid Build Coastguard Worker // fuzzing campaign installations, e.g. oss-fuzz
58*08b48e0bSAndroid Build Coastguard Worker
59*08b48e0bSAndroid Build Coastguard Worker static constexpr const char *ignoreList[] = {
60*08b48e0bSAndroid Build Coastguard Worker
61*08b48e0bSAndroid Build Coastguard Worker "asan.",
62*08b48e0bSAndroid Build Coastguard Worker "llvm.",
63*08b48e0bSAndroid Build Coastguard Worker "sancov.",
64*08b48e0bSAndroid Build Coastguard Worker "__ubsan",
65*08b48e0bSAndroid Build Coastguard Worker "ign.",
66*08b48e0bSAndroid Build Coastguard Worker "__afl",
67*08b48e0bSAndroid Build Coastguard Worker "_fini",
68*08b48e0bSAndroid Build Coastguard Worker "__libc_",
69*08b48e0bSAndroid Build Coastguard Worker "__asan",
70*08b48e0bSAndroid Build Coastguard Worker "__msan",
71*08b48e0bSAndroid Build Coastguard Worker "__cmplog",
72*08b48e0bSAndroid Build Coastguard Worker "__sancov",
73*08b48e0bSAndroid Build Coastguard Worker "__san",
74*08b48e0bSAndroid Build Coastguard Worker "__cxx_",
75*08b48e0bSAndroid Build Coastguard Worker "__decide_deferred",
76*08b48e0bSAndroid Build Coastguard Worker "_GLOBAL",
77*08b48e0bSAndroid Build Coastguard Worker "_ZZN6__asan",
78*08b48e0bSAndroid Build Coastguard Worker "_ZZN6__lsan",
79*08b48e0bSAndroid Build Coastguard Worker "msan.",
80*08b48e0bSAndroid Build Coastguard Worker "LLVMFuzzerM",
81*08b48e0bSAndroid Build Coastguard Worker "LLVMFuzzerC",
82*08b48e0bSAndroid Build Coastguard Worker "LLVMFuzzerI",
83*08b48e0bSAndroid Build Coastguard Worker "maybe_duplicate_stderr",
84*08b48e0bSAndroid Build Coastguard Worker "discard_output",
85*08b48e0bSAndroid Build Coastguard Worker "close_stdout",
86*08b48e0bSAndroid Build Coastguard Worker "dup_and_close_stderr",
87*08b48e0bSAndroid Build Coastguard Worker "maybe_close_fd_mask",
88*08b48e0bSAndroid Build Coastguard Worker "ExecuteFilesOnyByOne"
89*08b48e0bSAndroid Build Coastguard Worker
90*08b48e0bSAndroid Build Coastguard Worker };
91*08b48e0bSAndroid Build Coastguard Worker
92*08b48e0bSAndroid Build Coastguard Worker for (auto const &ignoreListFunc : ignoreList) {
93*08b48e0bSAndroid Build Coastguard Worker
94*08b48e0bSAndroid Build Coastguard Worker if (F->getName().startswith(ignoreListFunc)) { return true; }
95*08b48e0bSAndroid Build Coastguard Worker
96*08b48e0bSAndroid Build Coastguard Worker }
97*08b48e0bSAndroid Build Coastguard Worker
98*08b48e0bSAndroid Build Coastguard Worker static constexpr const char *ignoreSubstringList[] = {
99*08b48e0bSAndroid Build Coastguard Worker
100*08b48e0bSAndroid Build Coastguard Worker "__asan", "__msan", "__ubsan", "__lsan", "__san",
101*08b48e0bSAndroid Build Coastguard Worker "__sanitize", "DebugCounter", "DwarfDebug", "DebugLoc"
102*08b48e0bSAndroid Build Coastguard Worker
103*08b48e0bSAndroid Build Coastguard Worker };
104*08b48e0bSAndroid Build Coastguard Worker
105*08b48e0bSAndroid Build Coastguard Worker // This check is very sensitive, we must be sure to not include patterns
106*08b48e0bSAndroid Build Coastguard Worker // that are part of user-written C++ functions like the ones including
107*08b48e0bSAndroid Build Coastguard Worker // std::string as parameter (see #1927) as the mangled type is inserted in the
108*08b48e0bSAndroid Build Coastguard Worker // mangled name of the user-written function
109*08b48e0bSAndroid Build Coastguard Worker for (auto const &ignoreListFunc : ignoreSubstringList) {
110*08b48e0bSAndroid Build Coastguard Worker
111*08b48e0bSAndroid Build Coastguard Worker // hexcoder: F->getName().contains() not avaiilable in llvm 3.8.0
112*08b48e0bSAndroid Build Coastguard Worker if (StringRef::npos != F->getName().find(ignoreListFunc)) { return true; }
113*08b48e0bSAndroid Build Coastguard Worker
114*08b48e0bSAndroid Build Coastguard Worker }
115*08b48e0bSAndroid Build Coastguard Worker
116*08b48e0bSAndroid Build Coastguard Worker return false;
117*08b48e0bSAndroid Build Coastguard Worker
118*08b48e0bSAndroid Build Coastguard Worker }
119*08b48e0bSAndroid Build Coastguard Worker
initInstrumentList()120*08b48e0bSAndroid Build Coastguard Worker void initInstrumentList() {
121*08b48e0bSAndroid Build Coastguard Worker
122*08b48e0bSAndroid Build Coastguard Worker char *allowlist = getenv("AFL_LLVM_ALLOWLIST");
123*08b48e0bSAndroid Build Coastguard Worker if (!allowlist) allowlist = getenv("AFL_LLVM_INSTRUMENT_FILE");
124*08b48e0bSAndroid Build Coastguard Worker if (!allowlist) allowlist = getenv("AFL_LLVM_WHITELIST");
125*08b48e0bSAndroid Build Coastguard Worker char *denylist = getenv("AFL_LLVM_DENYLIST");
126*08b48e0bSAndroid Build Coastguard Worker if (!denylist) denylist = getenv("AFL_LLVM_BLOCKLIST");
127*08b48e0bSAndroid Build Coastguard Worker
128*08b48e0bSAndroid Build Coastguard Worker if (allowlist && denylist)
129*08b48e0bSAndroid Build Coastguard Worker FATAL(
130*08b48e0bSAndroid Build Coastguard Worker "You can only specify either AFL_LLVM_ALLOWLIST or AFL_LLVM_DENYLIST "
131*08b48e0bSAndroid Build Coastguard Worker "but not both!");
132*08b48e0bSAndroid Build Coastguard Worker
133*08b48e0bSAndroid Build Coastguard Worker if (allowlist) {
134*08b48e0bSAndroid Build Coastguard Worker
135*08b48e0bSAndroid Build Coastguard Worker std::string line;
136*08b48e0bSAndroid Build Coastguard Worker std::ifstream fileStream;
137*08b48e0bSAndroid Build Coastguard Worker fileStream.open(allowlist);
138*08b48e0bSAndroid Build Coastguard Worker if (!fileStream) report_fatal_error("Unable to open AFL_LLVM_ALLOWLIST");
139*08b48e0bSAndroid Build Coastguard Worker getline(fileStream, line);
140*08b48e0bSAndroid Build Coastguard Worker
141*08b48e0bSAndroid Build Coastguard Worker while (fileStream) {
142*08b48e0bSAndroid Build Coastguard Worker
143*08b48e0bSAndroid Build Coastguard Worker int is_file = -1;
144*08b48e0bSAndroid Build Coastguard Worker std::size_t npos;
145*08b48e0bSAndroid Build Coastguard Worker std::string original_line = line;
146*08b48e0bSAndroid Build Coastguard Worker
147*08b48e0bSAndroid Build Coastguard Worker line.erase(std::remove_if(line.begin(), line.end(), ::isspace),
148*08b48e0bSAndroid Build Coastguard Worker line.end());
149*08b48e0bSAndroid Build Coastguard Worker
150*08b48e0bSAndroid Build Coastguard Worker // remove # and following
151*08b48e0bSAndroid Build Coastguard Worker if ((npos = line.find("#")) != std::string::npos)
152*08b48e0bSAndroid Build Coastguard Worker line = line.substr(0, npos);
153*08b48e0bSAndroid Build Coastguard Worker
154*08b48e0bSAndroid Build Coastguard Worker if (line.compare(0, 4, "fun:") == 0) {
155*08b48e0bSAndroid Build Coastguard Worker
156*08b48e0bSAndroid Build Coastguard Worker is_file = 0;
157*08b48e0bSAndroid Build Coastguard Worker line = line.substr(4);
158*08b48e0bSAndroid Build Coastguard Worker
159*08b48e0bSAndroid Build Coastguard Worker } else if (line.compare(0, 9, "function:") == 0) {
160*08b48e0bSAndroid Build Coastguard Worker
161*08b48e0bSAndroid Build Coastguard Worker is_file = 0;
162*08b48e0bSAndroid Build Coastguard Worker line = line.substr(9);
163*08b48e0bSAndroid Build Coastguard Worker
164*08b48e0bSAndroid Build Coastguard Worker } else if (line.compare(0, 4, "src:") == 0) {
165*08b48e0bSAndroid Build Coastguard Worker
166*08b48e0bSAndroid Build Coastguard Worker is_file = 1;
167*08b48e0bSAndroid Build Coastguard Worker line = line.substr(4);
168*08b48e0bSAndroid Build Coastguard Worker
169*08b48e0bSAndroid Build Coastguard Worker } else if (line.compare(0, 7, "source:") == 0) {
170*08b48e0bSAndroid Build Coastguard Worker
171*08b48e0bSAndroid Build Coastguard Worker is_file = 1;
172*08b48e0bSAndroid Build Coastguard Worker line = line.substr(7);
173*08b48e0bSAndroid Build Coastguard Worker
174*08b48e0bSAndroid Build Coastguard Worker }
175*08b48e0bSAndroid Build Coastguard Worker
176*08b48e0bSAndroid Build Coastguard Worker if (line.find(":") != std::string::npos) {
177*08b48e0bSAndroid Build Coastguard Worker
178*08b48e0bSAndroid Build Coastguard Worker FATAL("invalid line in AFL_LLVM_ALLOWLIST: %s", original_line.c_str());
179*08b48e0bSAndroid Build Coastguard Worker
180*08b48e0bSAndroid Build Coastguard Worker }
181*08b48e0bSAndroid Build Coastguard Worker
182*08b48e0bSAndroid Build Coastguard Worker if (line.length() > 0) {
183*08b48e0bSAndroid Build Coastguard Worker
184*08b48e0bSAndroid Build Coastguard Worker // if the entry contains / or . it must be a file
185*08b48e0bSAndroid Build Coastguard Worker if (is_file == -1)
186*08b48e0bSAndroid Build Coastguard Worker if (line.find("/") != std::string::npos ||
187*08b48e0bSAndroid Build Coastguard Worker line.find(".") != std::string::npos)
188*08b48e0bSAndroid Build Coastguard Worker is_file = 1;
189*08b48e0bSAndroid Build Coastguard Worker // otherwise it is a function
190*08b48e0bSAndroid Build Coastguard Worker
191*08b48e0bSAndroid Build Coastguard Worker if (is_file == 1)
192*08b48e0bSAndroid Build Coastguard Worker allowListFiles.push_back(line);
193*08b48e0bSAndroid Build Coastguard Worker else
194*08b48e0bSAndroid Build Coastguard Worker allowListFunctions.push_back(line);
195*08b48e0bSAndroid Build Coastguard Worker
196*08b48e0bSAndroid Build Coastguard Worker }
197*08b48e0bSAndroid Build Coastguard Worker
198*08b48e0bSAndroid Build Coastguard Worker getline(fileStream, line);
199*08b48e0bSAndroid Build Coastguard Worker
200*08b48e0bSAndroid Build Coastguard Worker }
201*08b48e0bSAndroid Build Coastguard Worker
202*08b48e0bSAndroid Build Coastguard Worker if (debug)
203*08b48e0bSAndroid Build Coastguard Worker DEBUGF("loaded allowlist with %zu file and %zu function entries\n",
204*08b48e0bSAndroid Build Coastguard Worker allowListFiles.size() / 4, allowListFunctions.size() / 4);
205*08b48e0bSAndroid Build Coastguard Worker
206*08b48e0bSAndroid Build Coastguard Worker }
207*08b48e0bSAndroid Build Coastguard Worker
208*08b48e0bSAndroid Build Coastguard Worker if (denylist) {
209*08b48e0bSAndroid Build Coastguard Worker
210*08b48e0bSAndroid Build Coastguard Worker std::string line;
211*08b48e0bSAndroid Build Coastguard Worker std::ifstream fileStream;
212*08b48e0bSAndroid Build Coastguard Worker fileStream.open(denylist);
213*08b48e0bSAndroid Build Coastguard Worker if (!fileStream) report_fatal_error("Unable to open AFL_LLVM_DENYLIST");
214*08b48e0bSAndroid Build Coastguard Worker getline(fileStream, line);
215*08b48e0bSAndroid Build Coastguard Worker
216*08b48e0bSAndroid Build Coastguard Worker while (fileStream) {
217*08b48e0bSAndroid Build Coastguard Worker
218*08b48e0bSAndroid Build Coastguard Worker int is_file = -1;
219*08b48e0bSAndroid Build Coastguard Worker std::size_t npos;
220*08b48e0bSAndroid Build Coastguard Worker std::string original_line = line;
221*08b48e0bSAndroid Build Coastguard Worker
222*08b48e0bSAndroid Build Coastguard Worker line.erase(std::remove_if(line.begin(), line.end(), ::isspace),
223*08b48e0bSAndroid Build Coastguard Worker line.end());
224*08b48e0bSAndroid Build Coastguard Worker
225*08b48e0bSAndroid Build Coastguard Worker // remove # and following
226*08b48e0bSAndroid Build Coastguard Worker if ((npos = line.find("#")) != std::string::npos)
227*08b48e0bSAndroid Build Coastguard Worker line = line.substr(0, npos);
228*08b48e0bSAndroid Build Coastguard Worker
229*08b48e0bSAndroid Build Coastguard Worker if (line.compare(0, 4, "fun:") == 0) {
230*08b48e0bSAndroid Build Coastguard Worker
231*08b48e0bSAndroid Build Coastguard Worker is_file = 0;
232*08b48e0bSAndroid Build Coastguard Worker line = line.substr(4);
233*08b48e0bSAndroid Build Coastguard Worker
234*08b48e0bSAndroid Build Coastguard Worker } else if (line.compare(0, 9, "function:") == 0) {
235*08b48e0bSAndroid Build Coastguard Worker
236*08b48e0bSAndroid Build Coastguard Worker is_file = 0;
237*08b48e0bSAndroid Build Coastguard Worker line = line.substr(9);
238*08b48e0bSAndroid Build Coastguard Worker
239*08b48e0bSAndroid Build Coastguard Worker } else if (line.compare(0, 4, "src:") == 0) {
240*08b48e0bSAndroid Build Coastguard Worker
241*08b48e0bSAndroid Build Coastguard Worker is_file = 1;
242*08b48e0bSAndroid Build Coastguard Worker line = line.substr(4);
243*08b48e0bSAndroid Build Coastguard Worker
244*08b48e0bSAndroid Build Coastguard Worker } else if (line.compare(0, 7, "source:") == 0) {
245*08b48e0bSAndroid Build Coastguard Worker
246*08b48e0bSAndroid Build Coastguard Worker is_file = 1;
247*08b48e0bSAndroid Build Coastguard Worker line = line.substr(7);
248*08b48e0bSAndroid Build Coastguard Worker
249*08b48e0bSAndroid Build Coastguard Worker }
250*08b48e0bSAndroid Build Coastguard Worker
251*08b48e0bSAndroid Build Coastguard Worker if (line.find(":") != std::string::npos) {
252*08b48e0bSAndroid Build Coastguard Worker
253*08b48e0bSAndroid Build Coastguard Worker FATAL("invalid line in AFL_LLVM_DENYLIST: %s", original_line.c_str());
254*08b48e0bSAndroid Build Coastguard Worker
255*08b48e0bSAndroid Build Coastguard Worker }
256*08b48e0bSAndroid Build Coastguard Worker
257*08b48e0bSAndroid Build Coastguard Worker if (line.length() > 0) {
258*08b48e0bSAndroid Build Coastguard Worker
259*08b48e0bSAndroid Build Coastguard Worker // if the entry contains / or . it must be a file
260*08b48e0bSAndroid Build Coastguard Worker if (is_file == -1)
261*08b48e0bSAndroid Build Coastguard Worker if (line.find("/") != std::string::npos ||
262*08b48e0bSAndroid Build Coastguard Worker line.find(".") != std::string::npos)
263*08b48e0bSAndroid Build Coastguard Worker is_file = 1;
264*08b48e0bSAndroid Build Coastguard Worker // otherwise it is a function
265*08b48e0bSAndroid Build Coastguard Worker
266*08b48e0bSAndroid Build Coastguard Worker if (is_file == 1)
267*08b48e0bSAndroid Build Coastguard Worker denyListFiles.push_back(line);
268*08b48e0bSAndroid Build Coastguard Worker else
269*08b48e0bSAndroid Build Coastguard Worker denyListFunctions.push_back(line);
270*08b48e0bSAndroid Build Coastguard Worker
271*08b48e0bSAndroid Build Coastguard Worker }
272*08b48e0bSAndroid Build Coastguard Worker
273*08b48e0bSAndroid Build Coastguard Worker getline(fileStream, line);
274*08b48e0bSAndroid Build Coastguard Worker
275*08b48e0bSAndroid Build Coastguard Worker }
276*08b48e0bSAndroid Build Coastguard Worker
277*08b48e0bSAndroid Build Coastguard Worker if (debug)
278*08b48e0bSAndroid Build Coastguard Worker DEBUGF("loaded denylist with %zu file and %zu function entries\n",
279*08b48e0bSAndroid Build Coastguard Worker denyListFiles.size() / 4, denyListFunctions.size() / 4);
280*08b48e0bSAndroid Build Coastguard Worker
281*08b48e0bSAndroid Build Coastguard Worker }
282*08b48e0bSAndroid Build Coastguard Worker
283*08b48e0bSAndroid Build Coastguard Worker }
284*08b48e0bSAndroid Build Coastguard Worker
scanForDangerousFunctions(llvm::Module * M)285*08b48e0bSAndroid Build Coastguard Worker void scanForDangerousFunctions(llvm::Module *M) {
286*08b48e0bSAndroid Build Coastguard Worker
287*08b48e0bSAndroid Build Coastguard Worker if (!M) return;
288*08b48e0bSAndroid Build Coastguard Worker
289*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 4 || \
290*08b48e0bSAndroid Build Coastguard Worker (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 9)
291*08b48e0bSAndroid Build Coastguard Worker
292*08b48e0bSAndroid Build Coastguard Worker for (GlobalIFunc &IF : M->ifuncs()) {
293*08b48e0bSAndroid Build Coastguard Worker
294*08b48e0bSAndroid Build Coastguard Worker StringRef ifunc_name = IF.getName();
295*08b48e0bSAndroid Build Coastguard Worker Constant *r = IF.getResolver();
296*08b48e0bSAndroid Build Coastguard Worker if (r->getNumOperands() == 0) { continue; }
297*08b48e0bSAndroid Build Coastguard Worker StringRef r_name = cast<Function>(r->getOperand(0))->getName();
298*08b48e0bSAndroid Build Coastguard Worker if (!be_quiet)
299*08b48e0bSAndroid Build Coastguard Worker fprintf(stderr,
300*08b48e0bSAndroid Build Coastguard Worker "Note: Found an ifunc with name %s that points to resolver "
301*08b48e0bSAndroid Build Coastguard Worker "function %s, we will not instrument this, putting it into the "
302*08b48e0bSAndroid Build Coastguard Worker "block list.\n",
303*08b48e0bSAndroid Build Coastguard Worker ifunc_name.str().c_str(), r_name.str().c_str());
304*08b48e0bSAndroid Build Coastguard Worker denyListFunctions.push_back(r_name.str());
305*08b48e0bSAndroid Build Coastguard Worker
306*08b48e0bSAndroid Build Coastguard Worker }
307*08b48e0bSAndroid Build Coastguard Worker
308*08b48e0bSAndroid Build Coastguard Worker GlobalVariable *GV = M->getNamedGlobal("llvm.global_ctors");
309*08b48e0bSAndroid Build Coastguard Worker if (GV && !GV->isDeclaration() && !GV->hasLocalLinkage()) {
310*08b48e0bSAndroid Build Coastguard Worker
311*08b48e0bSAndroid Build Coastguard Worker ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer());
312*08b48e0bSAndroid Build Coastguard Worker
313*08b48e0bSAndroid Build Coastguard Worker if (InitList) {
314*08b48e0bSAndroid Build Coastguard Worker
315*08b48e0bSAndroid Build Coastguard Worker for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
316*08b48e0bSAndroid Build Coastguard Worker
317*08b48e0bSAndroid Build Coastguard Worker if (ConstantStruct *CS =
318*08b48e0bSAndroid Build Coastguard Worker dyn_cast<ConstantStruct>(InitList->getOperand(i))) {
319*08b48e0bSAndroid Build Coastguard Worker
320*08b48e0bSAndroid Build Coastguard Worker if (CS->getNumOperands() >= 2) {
321*08b48e0bSAndroid Build Coastguard Worker
322*08b48e0bSAndroid Build Coastguard Worker if (CS->getOperand(1)->isNullValue())
323*08b48e0bSAndroid Build Coastguard Worker break; // Found a null terminator, stop here.
324*08b48e0bSAndroid Build Coastguard Worker
325*08b48e0bSAndroid Build Coastguard Worker ConstantInt *CI = dyn_cast<ConstantInt>(CS->getOperand(0));
326*08b48e0bSAndroid Build Coastguard Worker int Priority = CI ? CI->getSExtValue() : 0;
327*08b48e0bSAndroid Build Coastguard Worker
328*08b48e0bSAndroid Build Coastguard Worker Constant *FP = CS->getOperand(1);
329*08b48e0bSAndroid Build Coastguard Worker if (ConstantExpr *CE = dyn_cast<ConstantExpr>(FP))
330*08b48e0bSAndroid Build Coastguard Worker if (CE->isCast()) FP = CE->getOperand(0);
331*08b48e0bSAndroid Build Coastguard Worker if (Function *F = dyn_cast<Function>(FP)) {
332*08b48e0bSAndroid Build Coastguard Worker
333*08b48e0bSAndroid Build Coastguard Worker if (!F->isDeclaration() &&
334*08b48e0bSAndroid Build Coastguard Worker strncmp(F->getName().str().c_str(), "__afl", 5) != 0) {
335*08b48e0bSAndroid Build Coastguard Worker
336*08b48e0bSAndroid Build Coastguard Worker if (!be_quiet)
337*08b48e0bSAndroid Build Coastguard Worker fprintf(stderr,
338*08b48e0bSAndroid Build Coastguard Worker "Note: Found constructor function %s with prio "
339*08b48e0bSAndroid Build Coastguard Worker "%u, we will not instrument this, putting it into a "
340*08b48e0bSAndroid Build Coastguard Worker "block list.\n",
341*08b48e0bSAndroid Build Coastguard Worker F->getName().str().c_str(), Priority);
342*08b48e0bSAndroid Build Coastguard Worker denyListFunctions.push_back(F->getName().str());
343*08b48e0bSAndroid Build Coastguard Worker
344*08b48e0bSAndroid Build Coastguard Worker }
345*08b48e0bSAndroid Build Coastguard Worker
346*08b48e0bSAndroid Build Coastguard Worker }
347*08b48e0bSAndroid Build Coastguard Worker
348*08b48e0bSAndroid Build Coastguard Worker }
349*08b48e0bSAndroid Build Coastguard Worker
350*08b48e0bSAndroid Build Coastguard Worker }
351*08b48e0bSAndroid Build Coastguard Worker
352*08b48e0bSAndroid Build Coastguard Worker }
353*08b48e0bSAndroid Build Coastguard Worker
354*08b48e0bSAndroid Build Coastguard Worker }
355*08b48e0bSAndroid Build Coastguard Worker
356*08b48e0bSAndroid Build Coastguard Worker }
357*08b48e0bSAndroid Build Coastguard Worker
358*08b48e0bSAndroid Build Coastguard Worker #endif
359*08b48e0bSAndroid Build Coastguard Worker
360*08b48e0bSAndroid Build Coastguard Worker }
361*08b48e0bSAndroid Build Coastguard Worker
getSourceName(llvm::Function * F)362*08b48e0bSAndroid Build Coastguard Worker static std::string getSourceName(llvm::Function *F) {
363*08b48e0bSAndroid Build Coastguard Worker
364*08b48e0bSAndroid Build Coastguard Worker // let's try to get the filename for the function
365*08b48e0bSAndroid Build Coastguard Worker auto bb = &F->getEntryBlock();
366*08b48e0bSAndroid Build Coastguard Worker BasicBlock::iterator IP = bb->getFirstInsertionPt();
367*08b48e0bSAndroid Build Coastguard Worker IRBuilder<> IRB(&(*IP));
368*08b48e0bSAndroid Build Coastguard Worker DebugLoc Loc = IP->getDebugLoc();
369*08b48e0bSAndroid Build Coastguard Worker
370*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 4 || \
371*08b48e0bSAndroid Build Coastguard Worker (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 7)
372*08b48e0bSAndroid Build Coastguard Worker if (Loc) {
373*08b48e0bSAndroid Build Coastguard Worker
374*08b48e0bSAndroid Build Coastguard Worker StringRef instFilename;
375*08b48e0bSAndroid Build Coastguard Worker DILocation *cDILoc = dyn_cast<DILocation>(Loc.getAsMDNode());
376*08b48e0bSAndroid Build Coastguard Worker
377*08b48e0bSAndroid Build Coastguard Worker if (cDILoc) { instFilename = cDILoc->getFilename(); }
378*08b48e0bSAndroid Build Coastguard Worker
379*08b48e0bSAndroid Build Coastguard Worker if (instFilename.str().empty() && cDILoc) {
380*08b48e0bSAndroid Build Coastguard Worker
381*08b48e0bSAndroid Build Coastguard Worker /* If the original location is empty, try using the inlined location
382*08b48e0bSAndroid Build Coastguard Worker */
383*08b48e0bSAndroid Build Coastguard Worker DILocation *oDILoc = cDILoc->getInlinedAt();
384*08b48e0bSAndroid Build Coastguard Worker if (oDILoc) { instFilename = oDILoc->getFilename(); }
385*08b48e0bSAndroid Build Coastguard Worker
386*08b48e0bSAndroid Build Coastguard Worker }
387*08b48e0bSAndroid Build Coastguard Worker
388*08b48e0bSAndroid Build Coastguard Worker return instFilename.str();
389*08b48e0bSAndroid Build Coastguard Worker
390*08b48e0bSAndroid Build Coastguard Worker }
391*08b48e0bSAndroid Build Coastguard Worker
392*08b48e0bSAndroid Build Coastguard Worker #else
393*08b48e0bSAndroid Build Coastguard Worker if (!Loc.isUnknown()) {
394*08b48e0bSAndroid Build Coastguard Worker
395*08b48e0bSAndroid Build Coastguard Worker DILocation cDILoc(Loc.getAsMDNode(F->getContext()));
396*08b48e0bSAndroid Build Coastguard Worker
397*08b48e0bSAndroid Build Coastguard Worker StringRef instFilename = cDILoc.getFilename();
398*08b48e0bSAndroid Build Coastguard Worker
399*08b48e0bSAndroid Build Coastguard Worker /* Continue only if we know where we actually are */
400*08b48e0bSAndroid Build Coastguard Worker return instFilename.str();
401*08b48e0bSAndroid Build Coastguard Worker
402*08b48e0bSAndroid Build Coastguard Worker }
403*08b48e0bSAndroid Build Coastguard Worker
404*08b48e0bSAndroid Build Coastguard Worker #endif
405*08b48e0bSAndroid Build Coastguard Worker
406*08b48e0bSAndroid Build Coastguard Worker return std::string("");
407*08b48e0bSAndroid Build Coastguard Worker
408*08b48e0bSAndroid Build Coastguard Worker }
409*08b48e0bSAndroid Build Coastguard Worker
isInInstrumentList(llvm::Function * F,std::string Filename)410*08b48e0bSAndroid Build Coastguard Worker bool isInInstrumentList(llvm::Function *F, std::string Filename) {
411*08b48e0bSAndroid Build Coastguard Worker
412*08b48e0bSAndroid Build Coastguard Worker bool return_default = true;
413*08b48e0bSAndroid Build Coastguard Worker
414*08b48e0bSAndroid Build Coastguard Worker // is this a function with code? If it is external we don't instrument it
415*08b48e0bSAndroid Build Coastguard Worker // anyway and it can't be in the instrument file list. Or if it is it is
416*08b48e0bSAndroid Build Coastguard Worker // ignored.
417*08b48e0bSAndroid Build Coastguard Worker if (!F->size() || isIgnoreFunction(F)) return false;
418*08b48e0bSAndroid Build Coastguard Worker
419*08b48e0bSAndroid Build Coastguard Worker if (!denyListFiles.empty() || !denyListFunctions.empty()) {
420*08b48e0bSAndroid Build Coastguard Worker
421*08b48e0bSAndroid Build Coastguard Worker if (!denyListFunctions.empty()) {
422*08b48e0bSAndroid Build Coastguard Worker
423*08b48e0bSAndroid Build Coastguard Worker std::string instFunction = F->getName().str();
424*08b48e0bSAndroid Build Coastguard Worker
425*08b48e0bSAndroid Build Coastguard Worker for (std::list<std::string>::iterator it = denyListFunctions.begin();
426*08b48e0bSAndroid Build Coastguard Worker it != denyListFunctions.end(); ++it) {
427*08b48e0bSAndroid Build Coastguard Worker
428*08b48e0bSAndroid Build Coastguard Worker /* We don't check for filename equality here because
429*08b48e0bSAndroid Build Coastguard Worker * filenames might actually be full paths. Instead we
430*08b48e0bSAndroid Build Coastguard Worker * check that the actual filename ends in the filename
431*08b48e0bSAndroid Build Coastguard Worker * specified in the list. We also allow UNIX-style pattern
432*08b48e0bSAndroid Build Coastguard Worker * matching */
433*08b48e0bSAndroid Build Coastguard Worker
434*08b48e0bSAndroid Build Coastguard Worker if (instFunction.length() >= it->length()) {
435*08b48e0bSAndroid Build Coastguard Worker
436*08b48e0bSAndroid Build Coastguard Worker if (fnmatch(("*" + *it).c_str(), instFunction.c_str(), 0) == 0) {
437*08b48e0bSAndroid Build Coastguard Worker
438*08b48e0bSAndroid Build Coastguard Worker if (debug)
439*08b48e0bSAndroid Build Coastguard Worker DEBUGF(
440*08b48e0bSAndroid Build Coastguard Worker "Function %s is in the deny function list, not instrumenting "
441*08b48e0bSAndroid Build Coastguard Worker "... \n",
442*08b48e0bSAndroid Build Coastguard Worker instFunction.c_str());
443*08b48e0bSAndroid Build Coastguard Worker return false;
444*08b48e0bSAndroid Build Coastguard Worker
445*08b48e0bSAndroid Build Coastguard Worker }
446*08b48e0bSAndroid Build Coastguard Worker
447*08b48e0bSAndroid Build Coastguard Worker }
448*08b48e0bSAndroid Build Coastguard Worker
449*08b48e0bSAndroid Build Coastguard Worker }
450*08b48e0bSAndroid Build Coastguard Worker
451*08b48e0bSAndroid Build Coastguard Worker }
452*08b48e0bSAndroid Build Coastguard Worker
453*08b48e0bSAndroid Build Coastguard Worker if (!denyListFiles.empty()) {
454*08b48e0bSAndroid Build Coastguard Worker
455*08b48e0bSAndroid Build Coastguard Worker std::string source_file = getSourceName(F);
456*08b48e0bSAndroid Build Coastguard Worker
457*08b48e0bSAndroid Build Coastguard Worker if (source_file.empty()) { source_file = Filename; }
458*08b48e0bSAndroid Build Coastguard Worker
459*08b48e0bSAndroid Build Coastguard Worker if (!source_file.empty()) {
460*08b48e0bSAndroid Build Coastguard Worker
461*08b48e0bSAndroid Build Coastguard Worker for (std::list<std::string>::iterator it = denyListFiles.begin();
462*08b48e0bSAndroid Build Coastguard Worker it != denyListFiles.end(); ++it) {
463*08b48e0bSAndroid Build Coastguard Worker
464*08b48e0bSAndroid Build Coastguard Worker /* We don't check for filename equality here because
465*08b48e0bSAndroid Build Coastguard Worker * filenames might actually be full paths. Instead we
466*08b48e0bSAndroid Build Coastguard Worker * check that the actual filename ends in the filename
467*08b48e0bSAndroid Build Coastguard Worker * specified in the list. We also allow UNIX-style pattern
468*08b48e0bSAndroid Build Coastguard Worker * matching */
469*08b48e0bSAndroid Build Coastguard Worker
470*08b48e0bSAndroid Build Coastguard Worker if (source_file.length() >= it->length()) {
471*08b48e0bSAndroid Build Coastguard Worker
472*08b48e0bSAndroid Build Coastguard Worker if (fnmatch(("*" + *it).c_str(), source_file.c_str(), 0) == 0) {
473*08b48e0bSAndroid Build Coastguard Worker
474*08b48e0bSAndroid Build Coastguard Worker return false;
475*08b48e0bSAndroid Build Coastguard Worker
476*08b48e0bSAndroid Build Coastguard Worker }
477*08b48e0bSAndroid Build Coastguard Worker
478*08b48e0bSAndroid Build Coastguard Worker }
479*08b48e0bSAndroid Build Coastguard Worker
480*08b48e0bSAndroid Build Coastguard Worker }
481*08b48e0bSAndroid Build Coastguard Worker
482*08b48e0bSAndroid Build Coastguard Worker } else {
483*08b48e0bSAndroid Build Coastguard Worker
484*08b48e0bSAndroid Build Coastguard Worker // we could not find out the location. in this case we say it is not
485*08b48e0bSAndroid Build Coastguard Worker // in the instrument file list
486*08b48e0bSAndroid Build Coastguard Worker if (!be_quiet)
487*08b48e0bSAndroid Build Coastguard Worker WARNF(
488*08b48e0bSAndroid Build Coastguard Worker "No debug information found for function %s, will be "
489*08b48e0bSAndroid Build Coastguard Worker "instrumented (recompile with -g -O[1-3] and use a modern llvm).",
490*08b48e0bSAndroid Build Coastguard Worker F->getName().str().c_str());
491*08b48e0bSAndroid Build Coastguard Worker
492*08b48e0bSAndroid Build Coastguard Worker }
493*08b48e0bSAndroid Build Coastguard Worker
494*08b48e0bSAndroid Build Coastguard Worker }
495*08b48e0bSAndroid Build Coastguard Worker
496*08b48e0bSAndroid Build Coastguard Worker }
497*08b48e0bSAndroid Build Coastguard Worker
498*08b48e0bSAndroid Build Coastguard Worker // if we do not have a instrument file list return true
499*08b48e0bSAndroid Build Coastguard Worker if (!allowListFiles.empty() || !allowListFunctions.empty()) {
500*08b48e0bSAndroid Build Coastguard Worker
501*08b48e0bSAndroid Build Coastguard Worker return_default = false;
502*08b48e0bSAndroid Build Coastguard Worker
503*08b48e0bSAndroid Build Coastguard Worker if (!allowListFunctions.empty()) {
504*08b48e0bSAndroid Build Coastguard Worker
505*08b48e0bSAndroid Build Coastguard Worker std::string instFunction = F->getName().str();
506*08b48e0bSAndroid Build Coastguard Worker
507*08b48e0bSAndroid Build Coastguard Worker for (std::list<std::string>::iterator it = allowListFunctions.begin();
508*08b48e0bSAndroid Build Coastguard Worker it != allowListFunctions.end(); ++it) {
509*08b48e0bSAndroid Build Coastguard Worker
510*08b48e0bSAndroid Build Coastguard Worker /* We don't check for filename equality here because
511*08b48e0bSAndroid Build Coastguard Worker * filenames might actually be full paths. Instead we
512*08b48e0bSAndroid Build Coastguard Worker * check that the actual filename ends in the filename
513*08b48e0bSAndroid Build Coastguard Worker * specified in the list. We also allow UNIX-style pattern
514*08b48e0bSAndroid Build Coastguard Worker * matching */
515*08b48e0bSAndroid Build Coastguard Worker
516*08b48e0bSAndroid Build Coastguard Worker if (instFunction.length() >= it->length()) {
517*08b48e0bSAndroid Build Coastguard Worker
518*08b48e0bSAndroid Build Coastguard Worker if (fnmatch(("*" + *it).c_str(), instFunction.c_str(), 0) == 0) {
519*08b48e0bSAndroid Build Coastguard Worker
520*08b48e0bSAndroid Build Coastguard Worker if (debug)
521*08b48e0bSAndroid Build Coastguard Worker DEBUGF(
522*08b48e0bSAndroid Build Coastguard Worker "Function %s is in the allow function list, instrumenting "
523*08b48e0bSAndroid Build Coastguard Worker "... \n",
524*08b48e0bSAndroid Build Coastguard Worker instFunction.c_str());
525*08b48e0bSAndroid Build Coastguard Worker return true;
526*08b48e0bSAndroid Build Coastguard Worker
527*08b48e0bSAndroid Build Coastguard Worker }
528*08b48e0bSAndroid Build Coastguard Worker
529*08b48e0bSAndroid Build Coastguard Worker }
530*08b48e0bSAndroid Build Coastguard Worker
531*08b48e0bSAndroid Build Coastguard Worker }
532*08b48e0bSAndroid Build Coastguard Worker
533*08b48e0bSAndroid Build Coastguard Worker }
534*08b48e0bSAndroid Build Coastguard Worker
535*08b48e0bSAndroid Build Coastguard Worker if (!allowListFiles.empty()) {
536*08b48e0bSAndroid Build Coastguard Worker
537*08b48e0bSAndroid Build Coastguard Worker std::string source_file = getSourceName(F);
538*08b48e0bSAndroid Build Coastguard Worker
539*08b48e0bSAndroid Build Coastguard Worker if (source_file.empty()) { source_file = Filename; }
540*08b48e0bSAndroid Build Coastguard Worker
541*08b48e0bSAndroid Build Coastguard Worker if (!source_file.empty()) {
542*08b48e0bSAndroid Build Coastguard Worker
543*08b48e0bSAndroid Build Coastguard Worker for (std::list<std::string>::iterator it = allowListFiles.begin();
544*08b48e0bSAndroid Build Coastguard Worker it != allowListFiles.end(); ++it) {
545*08b48e0bSAndroid Build Coastguard Worker
546*08b48e0bSAndroid Build Coastguard Worker /* We don't check for filename equality here because
547*08b48e0bSAndroid Build Coastguard Worker * filenames might actually be full paths. Instead we
548*08b48e0bSAndroid Build Coastguard Worker * check that the actual filename ends in the filename
549*08b48e0bSAndroid Build Coastguard Worker * specified in the list. We also allow UNIX-style pattern
550*08b48e0bSAndroid Build Coastguard Worker * matching */
551*08b48e0bSAndroid Build Coastguard Worker
552*08b48e0bSAndroid Build Coastguard Worker if (source_file.length() >= it->length()) {
553*08b48e0bSAndroid Build Coastguard Worker
554*08b48e0bSAndroid Build Coastguard Worker if (fnmatch(("*" + *it).c_str(), source_file.c_str(), 0) == 0) {
555*08b48e0bSAndroid Build Coastguard Worker
556*08b48e0bSAndroid Build Coastguard Worker if (debug)
557*08b48e0bSAndroid Build Coastguard Worker DEBUGF(
558*08b48e0bSAndroid Build Coastguard Worker "Function %s is in the allowlist (%s), instrumenting ... "
559*08b48e0bSAndroid Build Coastguard Worker "\n",
560*08b48e0bSAndroid Build Coastguard Worker F->getName().str().c_str(), source_file.c_str());
561*08b48e0bSAndroid Build Coastguard Worker return true;
562*08b48e0bSAndroid Build Coastguard Worker
563*08b48e0bSAndroid Build Coastguard Worker }
564*08b48e0bSAndroid Build Coastguard Worker
565*08b48e0bSAndroid Build Coastguard Worker }
566*08b48e0bSAndroid Build Coastguard Worker
567*08b48e0bSAndroid Build Coastguard Worker }
568*08b48e0bSAndroid Build Coastguard Worker
569*08b48e0bSAndroid Build Coastguard Worker } else {
570*08b48e0bSAndroid Build Coastguard Worker
571*08b48e0bSAndroid Build Coastguard Worker // we could not find out the location. In this case we say it is not
572*08b48e0bSAndroid Build Coastguard Worker // in the instrument file list
573*08b48e0bSAndroid Build Coastguard Worker if (!be_quiet)
574*08b48e0bSAndroid Build Coastguard Worker WARNF(
575*08b48e0bSAndroid Build Coastguard Worker "No debug information found for function %s, will not be "
576*08b48e0bSAndroid Build Coastguard Worker "instrumented (recompile with -g -O[1-3] and use a modern llvm).",
577*08b48e0bSAndroid Build Coastguard Worker F->getName().str().c_str());
578*08b48e0bSAndroid Build Coastguard Worker return false;
579*08b48e0bSAndroid Build Coastguard Worker
580*08b48e0bSAndroid Build Coastguard Worker }
581*08b48e0bSAndroid Build Coastguard Worker
582*08b48e0bSAndroid Build Coastguard Worker }
583*08b48e0bSAndroid Build Coastguard Worker
584*08b48e0bSAndroid Build Coastguard Worker }
585*08b48e0bSAndroid Build Coastguard Worker
586*08b48e0bSAndroid Build Coastguard Worker return return_default;
587*08b48e0bSAndroid Build Coastguard Worker
588*08b48e0bSAndroid Build Coastguard Worker }
589*08b48e0bSAndroid Build Coastguard Worker
590*08b48e0bSAndroid Build Coastguard Worker // Calculate the number of average collisions that would occur if all
591*08b48e0bSAndroid Build Coastguard Worker // location IDs would be assigned randomly (like normal afl/AFL++).
592*08b48e0bSAndroid Build Coastguard Worker // This uses the "balls in bins" algorithm.
calculateCollisions(uint32_t edges)593*08b48e0bSAndroid Build Coastguard Worker unsigned long long int calculateCollisions(uint32_t edges) {
594*08b48e0bSAndroid Build Coastguard Worker
595*08b48e0bSAndroid Build Coastguard Worker double bins = MAP_SIZE;
596*08b48e0bSAndroid Build Coastguard Worker double balls = edges;
597*08b48e0bSAndroid Build Coastguard Worker double step1 = 1 - (1 / bins);
598*08b48e0bSAndroid Build Coastguard Worker double step2 = pow(step1, balls);
599*08b48e0bSAndroid Build Coastguard Worker double step3 = bins * step2;
600*08b48e0bSAndroid Build Coastguard Worker double step4 = round(step3);
601*08b48e0bSAndroid Build Coastguard Worker unsigned long long int empty = step4;
602*08b48e0bSAndroid Build Coastguard Worker unsigned long long int collisions = edges - (MAP_SIZE - empty);
603*08b48e0bSAndroid Build Coastguard Worker return collisions;
604*08b48e0bSAndroid Build Coastguard Worker
605*08b48e0bSAndroid Build Coastguard Worker }
606*08b48e0bSAndroid Build Coastguard Worker
607