github.com/prysmaticlabs/prysm@v1.4.4/third_party/afl/llvm_mode/afl-llvm-rt.o.c (about) 1 /* 2 american fuzzy lop - LLVM instrumentation bootstrap 3 --------------------------------------------------- 4 5 Written by Laszlo Szekeres <lszekeres@google.com> and 6 Michal Zalewski <lcamtuf@google.com> 7 8 LLVM integration design comes from Laszlo Szekeres. 9 10 Copyright 2015, 2016 Google Inc. All rights reserved. 11 12 Licensed under the Apache License, Version 2.0 (the "License"); 13 you may not use this file except in compliance with the License. 14 You may obtain a copy of the License at: 15 16 http://www.apache.org/licenses/LICENSE-2.0 17 18 This code is the rewrite of afl-as.h's main_payload. 19 20 */ 21 22 #include "../config.h" 23 #include "../types.h" 24 25 #include <stdio.h> 26 #include <stdlib.h> 27 #include <signal.h> 28 #include <unistd.h> 29 #include <string.h> 30 #include <assert.h> 31 32 #include <sys/mman.h> 33 #include <sys/shm.h> 34 #include <sys/wait.h> 35 #include <sys/types.h> 36 37 /* This is a somewhat ugly hack for the experimental 'trace-pc-guard' mode. 38 Basically, we need to make sure that the forkserver is initialized after 39 the LLVM-generated runtime initialization pass, not before. */ 40 41 #ifdef USE_TRACE_PC 42 # define CONST_PRIO 5 43 #else 44 # define CONST_PRIO 0 45 #endif /* ^USE_TRACE_PC */ 46 47 48 /* Globals needed by the injected instrumentation. The __afl_area_initial region 49 is used for instrumentation output before __afl_map_shm() has a chance to run. 50 It will end up as .comm, so it shouldn't be too wasteful. */ 51 52 u8 __afl_area_initial[MAP_SIZE]; 53 u8* __afl_area_ptr = __afl_area_initial; 54 55 __thread u32 __afl_prev_loc; 56 57 58 /* Running in persistent mode? */ 59 60 static u8 is_persistent; 61 62 63 /* SHM setup. */ 64 65 static void __afl_map_shm(void) { 66 67 u8 *id_str = getenv(SHM_ENV_VAR); 68 69 /* If we're running under AFL, attach to the appropriate region, replacing the 70 early-stage __afl_area_initial region that is needed to allow some really 71 hacky .init code to work correctly in projects such as OpenSSL. */ 72 73 if (id_str) { 74 75 u32 shm_id = atoi(id_str); 76 77 __afl_area_ptr = shmat(shm_id, NULL, 0); 78 79 /* Whooooops. */ 80 81 if (__afl_area_ptr == (void *)-1) _exit(1); 82 83 /* Write something into the bitmap so that even with low AFL_INST_RATIO, 84 our parent doesn't give up on us. */ 85 86 __afl_area_ptr[0] = 1; 87 88 } 89 90 } 91 92 93 /* Fork server logic. */ 94 95 static void __afl_start_forkserver(void) { 96 97 static u8 tmp[4]; 98 s32 child_pid; 99 100 u8 child_stopped = 0; 101 102 /* Phone home and tell the parent that we're OK. If parent isn't there, 103 assume we're not running in forkserver mode and just execute program. */ 104 105 if (write(FORKSRV_FD + 1, tmp, 4) != 4) return; 106 107 while (1) { 108 109 u32 was_killed; 110 int status; 111 112 /* Wait for parent by reading from the pipe. Abort if read fails. */ 113 114 if (read(FORKSRV_FD, &was_killed, 4) != 4) _exit(1); 115 116 /* If we stopped the child in persistent mode, but there was a race 117 condition and afl-fuzz already issued SIGKILL, write off the old 118 process. */ 119 120 if (child_stopped && was_killed) { 121 child_stopped = 0; 122 if (waitpid(child_pid, &status, 0) < 0) _exit(1); 123 } 124 125 if (!child_stopped) { 126 127 /* Once woken up, create a clone of our process. */ 128 129 child_pid = fork(); 130 if (child_pid < 0) _exit(1); 131 132 /* In child process: close fds, resume execution. */ 133 134 if (!child_pid) { 135 136 close(FORKSRV_FD); 137 close(FORKSRV_FD + 1); 138 return; 139 140 } 141 142 } else { 143 144 /* Special handling for persistent mode: if the child is alive but 145 currently stopped, simply restart it with SIGCONT. */ 146 147 kill(child_pid, SIGCONT); 148 child_stopped = 0; 149 150 } 151 152 /* In parent process: write PID to pipe, then wait for child. */ 153 154 if (write(FORKSRV_FD + 1, &child_pid, 4) != 4) _exit(1); 155 156 if (waitpid(child_pid, &status, is_persistent ? WUNTRACED : 0) < 0) 157 _exit(1); 158 159 /* In persistent mode, the child stops itself with SIGSTOP to indicate 160 a successful run. In this case, we want to wake it up without forking 161 again. */ 162 163 if (WIFSTOPPED(status)) child_stopped = 1; 164 165 /* Relay wait status to pipe, then loop back. */ 166 167 if (write(FORKSRV_FD + 1, &status, 4) != 4) _exit(1); 168 169 } 170 171 } 172 173 174 /* A simplified persistent mode handler, used as explained in README.llvm. */ 175 176 int __afl_persistent_loop(unsigned int max_cnt) { 177 178 static u8 first_pass = 1; 179 static u32 cycle_cnt; 180 181 if (first_pass) { 182 183 /* Make sure that every iteration of __AFL_LOOP() starts with a clean slate. 184 On subsequent calls, the parent will take care of that, but on the first 185 iteration, it's our job to erase any trace of whatever happened 186 before the loop. */ 187 188 if (is_persistent) { 189 190 memset(__afl_area_ptr, 0, MAP_SIZE); 191 __afl_area_ptr[0] = 1; 192 __afl_prev_loc = 0; 193 } 194 195 cycle_cnt = max_cnt; 196 first_pass = 0; 197 return 1; 198 199 } 200 201 if (is_persistent) { 202 203 if (--cycle_cnt) { 204 205 raise(SIGSTOP); 206 207 __afl_area_ptr[0] = 1; 208 __afl_prev_loc = 0; 209 210 return 1; 211 212 } else { 213 214 /* When exiting __AFL_LOOP(), make sure that the subsequent code that 215 follows the loop is not traced. We do that by pivoting back to the 216 dummy output region. */ 217 218 __afl_area_ptr = __afl_area_initial; 219 220 } 221 222 } 223 224 return 0; 225 226 } 227 228 229 /* This one can be called from user code when deferred forkserver mode 230 is enabled. */ 231 232 void __afl_manual_init(void) { 233 234 static u8 init_done; 235 236 if (!init_done) { 237 238 __afl_map_shm(); 239 __afl_start_forkserver(); 240 init_done = 1; 241 242 } 243 244 } 245 246 247 /* Proper initialization routine. */ 248 249 __attribute__((constructor(CONST_PRIO))) void __afl_auto_init(void) { 250 251 is_persistent = !!getenv(PERSIST_ENV_VAR); 252 253 if (getenv(DEFER_ENV_VAR)) return; 254 255 __afl_manual_init(); 256 257 } 258 259 260 /* The following stuff deals with supporting -fsanitize-coverage=trace-pc-guard. 261 It remains non-operational in the traditional, plugin-backed LLVM mode. 262 For more info about 'trace-pc-guard', see README.llvm. 263 264 The first function (__sanitizer_cov_trace_pc_guard) is called back on every 265 edge (as opposed to every basic block). */ 266 267 void __sanitizer_cov_trace_pc_guard(uint32_t* guard) { 268 __afl_area_ptr[*guard]++; 269 } 270 271 272 /* Init callback. Populates instrumentation IDs. Note that we're using 273 ID of 0 as a special value to indicate non-instrumented bits. That may 274 still touch the bitmap, but in a fairly harmless way. */ 275 276 void __sanitizer_cov_trace_pc_guard_init(uint32_t* start, uint32_t* stop) { 277 278 u32 inst_ratio = 100; 279 u8* x; 280 281 if (start == stop || *start) return; 282 283 x = getenv("AFL_INST_RATIO"); 284 if (x) inst_ratio = atoi(x); 285 286 if (!inst_ratio || inst_ratio > 100) { 287 fprintf(stderr, "[-] ERROR: Invalid AFL_INST_RATIO (must be 1-100).\n"); 288 abort(); 289 } 290 291 /* Make sure that the first element in the range is always set - we use that 292 to avoid duplicate calls (which can happen as an artifact of the underlying 293 implementation in LLVM). */ 294 295 *(start++) = R(MAP_SIZE - 1) + 1; 296 297 while (start < stop) { 298 299 if (R(100) < inst_ratio) *start = R(MAP_SIZE - 1) + 1; 300 else *start = 0; 301 302 start++; 303 304 } 305 306 }