···3}:
45let
6- afl-qemu = callPackage ./qemu.nix {};
7 qemu-exe-name = if stdenv.hostPlatform.system == "x86_64-linux" then "qemu-x86_64"
8 else if stdenv.hostPlatform.system == "i686-linux" then "qemu-i386"
9 else throw "afl: no support for ${stdenv.hostPlatform.system}!";
10-in
001112-stdenv.mkDerivation rec {
13- name = "afl-${version}";
14- version = "2.52b";
01516- src = fetchurl {
17- url = "http://lcamtuf.coredump.cx/afl/releases/${name}.tgz";
18- sha256 = "0ig0ij4n1pwry5dw1hk4q88801jzzy2cric6y2gd6560j55lnqa3";
19- };
2021- # Note: libcgroup isn't needed for building, just for the afl-cgroup
22- # script.
23- buildInputs = [ makeWrapper llvm which ];
0000002425- buildPhase = ''
26- make PREFIX=$out
27- cd llvm_mode
28- make PREFIX=$out
29- cd ..
30- '';
31- installPhase = ''
32- # Do the normal installation
33- make install PREFIX=$out
3435- # Install the custom QEMU emulator for binary blob fuzzing.
36- cp ${afl-qemu}/bin/${qemu-exe-name} $out/bin/afl-qemu-trace
000003738- # Install the cgroups wrapper for asan-based fuzzing.
39- cp experimental/asan_cgroups/limit_memory.sh $out/bin/afl-cgroup
40- chmod +x $out/bin/afl-cgroup
41- substituteInPlace $out/bin/afl-cgroup \
42- --replace "cgcreate" "${libcgroup}/bin/cgcreate" \
43- --replace "cgexec" "${libcgroup}/bin/cgexec" \
44- --replace "cgdelete" "${libcgroup}/bin/cgdelete"
4546- # Patch shebangs before wrapping
47- patchShebangs $out/bin
000000004849- # Wrap afl-clang-fast(++) with a *different* AFL_PATH, because it
50- # has totally different semantics in that case(?) - and also set a
51- # proper AFL_CC and AFL_CXX so we don't pick up the wrong one out
52- # of $PATH.
53- for x in $out/bin/afl-clang-fast $out/bin/afl-clang-fast++; do
54- wrapProgram $x \
55- --prefix AFL_PATH : "$out/lib/afl" \
56- --run 'export AFL_CC=''${AFL_CC:-${clang}/bin/clang} AFL_CXX=''${AFL_CXX:-${clang}/bin/clang++}'
57- done
58- '';
5960- passthru = {
61- qemu = afl-qemu;
00000000000000062 };
06364- meta = {
65- description = "Powerful fuzzer via genetic algorithms and instrumentation";
66- longDescription = ''
67- American fuzzy lop is a fuzzer that employs a novel type of
68- compile-time instrumentation and genetic algorithms to
69- automatically discover clean, interesting test cases that
70- trigger new internal states in the targeted binary. This
71- substantially improves the functional coverage for the fuzzed
72- code. The compact synthesized corpora produced by the tool are
73- also useful for seeding other, more labor or resource-intensive
74- testing regimes down the road.
75- '';
76- homepage = "http://lcamtuf.coredump.cx/afl/";
77- license = stdenv.lib.licenses.asl20;
78- platforms = ["x86_64-linux" "i686-linux"];
79- maintainers = [ stdenv.lib.maintainers.thoughtpolice ];
80- };
81-}
···3}:
45let
6+ afl-qemu = callPackage ./qemu.nix { inherit afl; };
7 qemu-exe-name = if stdenv.hostPlatform.system == "x86_64-linux" then "qemu-x86_64"
8 else if stdenv.hostPlatform.system == "i686-linux" then "qemu-i386"
9 else throw "afl: no support for ${stdenv.hostPlatform.system}!";
10+ afl = stdenv.mkDerivation rec {
11+ name = "afl-${version}";
12+ version = "2.52b";
1314+ src = fetchurl {
15+ url = "http://lcamtuf.coredump.cx/afl/releases/${name}.tgz";
16+ sha256 = "0ig0ij4n1pwry5dw1hk4q88801jzzy2cric6y2gd6560j55lnqa3";
17+ };
1819+ # Note: libcgroup isn't needed for building, just for the afl-cgroup
20+ # script.
21+ buildInputs = [ makeWrapper llvm which ];
02223+ buildPhase = ''
24+ make PREFIX=$out
25+ cd llvm_mode
26+ make PREFIX=$out
27+ cd ..
28+ '';
29+ installPhase = ''
30+ # Do the normal installation
31+ make install PREFIX=$out
3233+ # Install the custom QEMU emulator for binary blob fuzzing.
34+ cp ${afl-qemu}/bin/${qemu-exe-name} $out/bin/afl-qemu-trace
00000003536+ # Install the cgroups wrapper for asan-based fuzzing.
37+ cp experimental/asan_cgroups/limit_memory.sh $out/bin/afl-cgroup
38+ chmod +x $out/bin/afl-cgroup
39+ substituteInPlace $out/bin/afl-cgroup \
40+ --replace "cgcreate" "${libcgroup}/bin/cgcreate" \
41+ --replace "cgexec" "${libcgroup}/bin/cgexec" \
42+ --replace "cgdelete" "${libcgroup}/bin/cgdelete"
4344+ # Patch shebangs before wrapping
45+ patchShebangs $out/bin
000004647+ # Wrap afl-clang-fast(++) with a *different* AFL_PATH, because it
48+ # has totally different semantics in that case(?) - and also set a
49+ # proper AFL_CC and AFL_CXX so we don't pick up the wrong one out
50+ # of $PATH.
51+ for x in $out/bin/afl-clang-fast $out/bin/afl-clang-fast++; do
52+ wrapProgram $x \
53+ --prefix AFL_PATH : "$out/lib/afl" \
54+ --run 'export AFL_CC=''${AFL_CC:-${clang}/bin/clang} AFL_CXX=''${AFL_CXX:-${clang}/bin/clang++}'
55+ done
56+ '';
5758+ passthru = {
59+ qemu = afl-qemu;
60+ };
00000006162+ meta = {
63+ description = "Powerful fuzzer via genetic algorithms and instrumentation";
64+ longDescription = ''
65+ American fuzzy lop is a fuzzer that employs a novel type of
66+ compile-time instrumentation and genetic algorithms to
67+ automatically discover clean, interesting test cases that
68+ trigger new internal states in the targeted binary. This
69+ substantially improves the functional coverage for the fuzzed
70+ code. The compact synthesized corpora produced by the tool are
71+ also useful for seeding other, more labor or resource-intensive
72+ testing regimes down the road.
73+ '';
74+ homepage = "http://lcamtuf.coredump.cx/afl/";
75+ license = stdenv.lib.licenses.asl20;
76+ platforms = ["x86_64-linux" "i686-linux"];
77+ maintainers = [ stdenv.lib.maintainers.thoughtpolice ];
78+ };
79 };
80+in afl
8182+00000000000000000
-335
pkgs/tools/security/afl/qemu-patches/afl-config.h
···1-/*
2- american fuzzy lop - vaguely configurable bits
3- ----------------------------------------------
4-5- Written and maintained by Michal Zalewski <lcamtuf@google.com>
6-7- Copyright 2013, 2014, 2015 Google Inc. All rights reserved.
8-9- Licensed under the Apache License, Version 2.0 (the "License");
10- you may not use this file except in compliance with the License.
11- You may obtain a copy of the License at:
12-13- http://www.apache.org/licenses/LICENSE-2.0
14-15- */
16-17-#ifndef _HAVE_CONFIG_H
18-#define _HAVE_CONFIG_H
19-20-#include "afl-types.h"
21-22-/******************************************************
23- * *
24- * Settings that may be of interest to power users: *
25- * *
26- ******************************************************/
27-28-/* Comment out to disable terminal colors: */
29-30-#define USE_COLOR
31-32-/* Comment out to disable fancy ANSI boxes and use poor man's 7-bit UI: */
33-34-#define FANCY_BOXES
35-36-/* Default timeout for fuzzed code (milliseconds): */
37-38-#define EXEC_TIMEOUT 1000
39-40-/* Timeout rounding factor when auto-scaling (milliseconds): */
41-42-#define EXEC_TM_ROUND 20
43-44-/* Default memory limit for child process (MB): */
45-46-#ifndef __x86_64__
47-# define MEM_LIMIT 25
48-#else
49-# define MEM_LIMIT 50
50-#endif /* ^!__x86_64__ */
51-52-/* Default memory limit when running in QEMU mode (MB): */
53-54-#define MEM_LIMIT_QEMU 200
55-56-/* Number of calibration cycles per every new test case (and for test
57- cases that show variable behavior): */
58-59-#define CAL_CYCLES 10
60-#define CAL_CYCLES_LONG 40
61-62-/* The same, but when AFL_NO_VAR_CHECK is set in the environment: */
63-64-#define CAL_CYCLES_NO_VAR 4
65-66-/* Number of subsequent hangs before abandoning an input file: */
67-68-#define HANG_LIMIT 250
69-70-/* Maximum number of unique hangs or crashes to record: */
71-72-#define KEEP_UNIQUE_HANG 500
73-#define KEEP_UNIQUE_CRASH 5000
74-75-/* Baseline number of random tweaks during a single 'havoc' stage: */
76-77-#define HAVOC_CYCLES 5000
78-79-/* Maximum multiplier for the above (should be a power of two, beware
80- of 32-bit int overflows): */
81-82-#define HAVOC_MAX_MULT 16
83-84-/* Absolute minimum number of havoc cycles (after all adjustments): */
85-86-#define HAVOC_MIN 10
87-88-/* Maximum stacking for havoc-stage tweaks. The actual value is calculated
89- like this:
90-91- n = random between 1 and HAVOC_STACK_POW2
92- stacking = 2^n
93-94- In other words, the default (n = 7) produces 2, 4, 8, 16, 32, 64, or
95- 128 stacked tweaks: */
96-97-#define HAVOC_STACK_POW2 7
98-99-/* Caps on block sizes for cloning and deletion operations. Each of these
100- ranges has a 33% probability of getting picked, except for the first
101- two cycles where smaller blocks are favored: */
102-103-#define HAVOC_BLK_SMALL 32
104-#define HAVOC_BLK_MEDIUM 128
105-#define HAVOC_BLK_LARGE 1500
106-107-/* Probabilities of skipping non-favored entries in the queue, expressed as
108- percentages: */
109-110-#define SKIP_TO_NEW_PROB 99 /* ...when there are new, pending favorites */
111-#define SKIP_NFAV_OLD_PROB 95 /* ...no new favs, cur entry already fuzzed */
112-#define SKIP_NFAV_NEW_PROB 75 /* ...no new favs, cur entry not fuzzed yet */
113-114-/* Splicing cycle count: */
115-116-#define SPLICE_CYCLES 20
117-118-/* Nominal per-splice havoc cycle length: */
119-120-#define SPLICE_HAVOC 500
121-122-/* Maximum offset for integer addition / subtraction stages: */
123-124-#define ARITH_MAX 35
125-126-/* Limits for the test case trimmer. The absolute minimum chunk size; and
127- the starting and ending divisors for chopping up the input file: */
128-129-#define TRIM_MIN_BYTES 4
130-#define TRIM_START_STEPS 16
131-#define TRIM_END_STEPS 1024
132-133-/* Maximum size of input file, in bytes (keep under 100MB): */
134-135-#define MAX_FILE (1 * 1024 * 1024)
136-137-/* The same, for the test case minimizer: */
138-139-#define TMIN_MAX_FILE (10 * 1024 * 1024)
140-141-/* Block normalization steps for afl-tmin: */
142-143-#define TMIN_SET_MIN_SIZE 4
144-#define TMIN_SET_STEPS 128
145-146-/* Maximum dictionary token size (-x), in bytes: */
147-148-#define MAX_DICT_FILE 128
149-150-/* Length limits for auto-detected dictionary tokens: */
151-152-#define MIN_AUTO_EXTRA 3
153-#define MAX_AUTO_EXTRA 32
154-155-/* Maximum number of user-specified dictionary tokens to use in deterministic
156- steps; past this point, the "extras/user" step will be still carried out,
157- but with proportionally lower odds: */
158-159-#define MAX_DET_EXTRAS 200
160-161-/* Maximum number of auto-extracted dictionary tokens to actually use in fuzzing
162- (first value), and to keep in memory as candidates. The latter should be much
163- higher than the former. */
164-165-#define USE_AUTO_EXTRAS 50
166-#define MAX_AUTO_EXTRAS (USE_AUTO_EXTRAS * 10)
167-168-/* Scaling factor for the effector map used to skip some of the more
169- expensive deterministic steps. The actual divisor is set to
170- 2^EFF_MAP_SCALE2 bytes: */
171-172-#define EFF_MAP_SCALE2 3
173-174-/* Minimum input file length at which the effector logic kicks in: */
175-176-#define EFF_MIN_LEN 128
177-178-/* Maximum effector density past which everything is just fuzzed
179- unconditionally (%): */
180-181-#define EFF_MAX_PERC 90
182-183-/* UI refresh frequency (Hz): */
184-185-#define UI_TARGET_HZ 5
186-187-/* Fuzzer stats file and plot update intervals (sec): */
188-189-#define STATS_UPDATE_SEC 60
190-#define PLOT_UPDATE_SEC 5
191-192-/* Smoothing divisor for CPU load and exec speed stats (1 - no smoothing). */
193-194-#define AVG_SMOOTHING 16
195-196-/* Sync interval (every n havoc cycles): */
197-198-#define SYNC_INTERVAL 5
199-200-/* Output directory reuse grace period (minutes): */
201-202-#define OUTPUT_GRACE 25
203-204-/* Uncomment to use simple file names (id_NNNNNN): */
205-206-// #define SIMPLE_FILES
207-208-/* List of interesting values to use in fuzzing. */
209-210-#define INTERESTING_8 \
211- -128, /* Overflow signed 8-bit when decremented */ \
212- -1, /* */ \
213- 0, /* */ \
214- 1, /* */ \
215- 16, /* One-off with common buffer size */ \
216- 32, /* One-off with common buffer size */ \
217- 64, /* One-off with common buffer size */ \
218- 100, /* One-off with common buffer size */ \
219- 127 /* Overflow signed 8-bit when incremented */
220-221-#define INTERESTING_16 \
222- -32768, /* Overflow signed 16-bit when decremented */ \
223- -129, /* Overflow signed 8-bit */ \
224- 128, /* Overflow signed 8-bit */ \
225- 255, /* Overflow unsig 8-bit when incremented */ \
226- 256, /* Overflow unsig 8-bit */ \
227- 512, /* One-off with common buffer size */ \
228- 1000, /* One-off with common buffer size */ \
229- 1024, /* One-off with common buffer size */ \
230- 4096, /* One-off with common buffer size */ \
231- 32767 /* Overflow signed 16-bit when incremented */
232-233-#define INTERESTING_32 \
234- -2147483648LL, /* Overflow signed 32-bit when decremented */ \
235- -100663046, /* Large negative number (endian-agnostic) */ \
236- -32769, /* Overflow signed 16-bit */ \
237- 32768, /* Overflow signed 16-bit */ \
238- 65535, /* Overflow unsig 16-bit when incremented */ \
239- 65536, /* Overflow unsig 16 bit */ \
240- 100663045, /* Large positive number (endian-agnostic) */ \
241- 2147483647 /* Overflow signed 32-bit when incremented */
242-243-/***********************************************************
244- * *
245- * Really exotic stuff you probably don't want to touch: *
246- * *
247- ***********************************************************/
248-249-/* Call count interval between reseeding the libc PRNG from /dev/urandom: */
250-251-#define RESEED_RNG 10000
252-253-/* Maximum line length passed from GCC to 'as' and used for parsing
254- configuration files: */
255-256-#define MAX_LINE 8192
257-258-/* Environment variable used to pass SHM ID to the called program. */
259-260-#define SHM_ENV_VAR "__AFL_SHM_ID"
261-262-/* Other less interesting, internal-only variables. */
263-264-#define CLANG_ENV_VAR "__AFL_CLANG_MODE"
265-#define AS_LOOP_ENV_VAR "__AFL_AS_LOOPCHECK"
266-267-/* Distinctive bitmap signature used to indicate failed execution: */
268-269-#define EXEC_FAIL_SIG 0xfee1dead
270-271-/* Distinctive exit code used to indicate MSAN trip condition: */
272-273-#define MSAN_ERROR 86
274-275-/* Designated file descriptors for forkserver commands (the application will
276- use FORKSRV_FD and FORKSRV_FD + 1): */
277-278-#define FORKSRV_FD 198
279-280-/* Fork server init timeout multiplier: we'll wait the user-selected
281- timeout plus this much for the fork server to spin up. */
282-283-#define FORK_WAIT_MULT 10
284-285-/* Calibration timeout adjustments, to be a bit more generous when resuming
286- fuzzing sessions or trying to calibrate already-added internal finds.
287- The first value is a percentage, the other is in milliseconds: */
288-289-#define CAL_TMOUT_PERC 125
290-#define CAL_TMOUT_ADD 50
291-292-/* Number of chances to calibrate a case before giving up: */
293-294-#define CAL_CHANCES 3
295-296-/* Map size for the traced binary (2^MAP_SIZE_POW2). Must be greater than
297- 2; you probably want to keep it under 18 or so for performance reasons
298- (adjusting AFL_INST_RATIO when compiling is probably a better way to solve
299- problems with complex programs). You need to recompile the target binary
300- after changing this - otherwise, SEGVs may ensue. */
301-302-#define MAP_SIZE_POW2 16
303-#define MAP_SIZE (1 << MAP_SIZE_POW2)
304-305-/* Maximum allocator request size (keep well under INT_MAX): */
306-307-#define MAX_ALLOC 0x40000000
308-309-/* A made-up hashing seed: */
310-311-#define HASH_CONST 0xa5b35705
312-313-/* Constants for afl-gotcpu to control busy loop timing: */
314-315-#define CTEST_TARGET_MS 5000
316-#define CTEST_BUSY_CYCLES (10 * 1000 * 1000)
317-318-/* Uncomment this to use inferior block-coverage-based instrumentation. Note
319- that you need to recompile the target binary for this to have any effect: */
320-321-// #define COVERAGE_ONLY
322-323-/* Uncomment this to ignore hit counts and output just one bit per tuple.
324- As with the previous setting, you will need to recompile the target
325- binary: */
326-327-// #define SKIP_COUNTS
328-329-/* Uncomment this to use instrumentation data to record newly discovered paths,
330- but do not use them as seeds for fuzzing. This is useful for conveniently
331- measuring coverage that could be attained by a "dumb" fuzzing algorithm: */
332-333-// #define IGNORE_FINDS
334-335-#endif /* ! _HAVE_CONFIG_H */
···1-/*
2- american fuzzy lop - high-performance binary-only instrumentation
3- -----------------------------------------------------------------
4-5- Written by Andrew Griffiths <agriffiths@google.com> and
6- Michal Zalewski <lcamtuf@google.com>
7-8- Idea & design very much by Andrew Griffiths.
9-10- Copyright 2015 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 a shim patched into the separately-distributed source
19- code of QEMU 2.2.0. It leverages the built-in QEMU tracing functionality
20- to implement AFL-style instrumentation and to take care of the remaining
21- parts of the AFL fork server logic.
22-23- The resulting QEMU binary is essentially a standalone instrumentation
24- tool; for an example of how to leverage it for other purposes, you can
25- have a look at afl-showmap.c.
26-27- */
28-29-#include <sys/shm.h>
30-#include "afl-config.h"
31-32-/***************************
33- * VARIOUS AUXILIARY STUFF *
34- ***************************/
35-36-/* A snippet patched into tb_find_slow to inform the parent process that
37- we have hit a new block that hasn't been translated yet, and to tell
38- it to translate within its own context, too (this avoids translation
39- overhead in the next forked-off copy). */
40-41-#define AFL_QEMU_CPU_SNIPPET1 do { \
42- afl_request_tsl(pc, cs_base, flags); \
43- } while (0)
44-45-/* This snippet kicks in when the instruction pointer is positioned at
46- _start and does the usual forkserver stuff, not very different from
47- regular instrumentation injected via afl-as.h. */
48-49-#define AFL_QEMU_CPU_SNIPPET2 do { \
50- if(tb->pc == afl_entry_point) { \
51- afl_setup(); \
52- afl_forkserver(env); \
53- } \
54- afl_maybe_log(tb->pc); \
55- } while (0)
56-57-/* We use one additional file descriptor to relay "needs translation"
58- messages between the child and the fork server. */
59-60-#define TSL_FD (FORKSRV_FD - 1)
61-62-/* This is equivalent to afl-as.h: */
63-64-static unsigned char *afl_area_ptr;
65-66-/* Exported variables populated by the code patched into elfload.c: */
67-68-abi_ulong afl_entry_point, /* ELF entry point (_start) */
69- afl_start_code, /* .text start pointer */
70- afl_end_code; /* .text end pointer */
71-72-/* Set in the child process in forkserver mode: */
73-74-static unsigned char afl_fork_child;
75-unsigned int afl_forksrv_pid;
76-77-/* Instrumentation ratio: */
78-79-static unsigned int afl_inst_rms = MAP_SIZE;
80-81-/* Function declarations. */
82-83-static void afl_setup(void);
84-static void afl_forkserver(CPUArchState*);
85-static inline void afl_maybe_log(abi_ulong);
86-87-static void afl_wait_tsl(CPUArchState*, int);
88-static void afl_request_tsl(target_ulong, target_ulong, uint64_t);
89-90-static TranslationBlock *tb_find_slow(CPUArchState*, target_ulong,
91- target_ulong, uint64_t);
92-93-94-/* Data structure passed around by the translate handlers: */
95-96-struct afl_tsl {
97- target_ulong pc;
98- target_ulong cs_base;
99- uint64_t flags;
100-};
101-102-103-/*************************
104- * ACTUAL IMPLEMENTATION *
105- *************************/
106-107-108-/* Set up SHM region and initialize other stuff. */
109-110-static void afl_setup(void) {
111-112- char *id_str = getenv(SHM_ENV_VAR),
113- *inst_r = getenv("AFL_INST_RATIO");
114-115- int shm_id;
116-117- if (inst_r) {
118-119- unsigned int r;
120-121- r = atoi(inst_r);
122-123- if (r > 100) r = 100;
124- if (!r) r = 1;
125-126- afl_inst_rms = MAP_SIZE * r / 100;
127-128- }
129-130- if (id_str) {
131-132- shm_id = atoi(id_str);
133- afl_area_ptr = shmat(shm_id, NULL, 0);
134-135- if (afl_area_ptr == (void*)-1) exit(1);
136-137- /* With AFL_INST_RATIO set to a low value, we want to touch the bitmap
138- so that the parent doesn't give up on us. */
139-140- if (inst_r) afl_area_ptr[0] = 1;
141-142-143- }
144-145- if (getenv("AFL_INST_LIBS")) {
146-147- afl_start_code = 0;
148- afl_end_code = (abi_ulong)-1;
149-150- }
151-152-}
153-154-155-/* Fork server logic, invoked once we hit _start. */
156-157-static void afl_forkserver(CPUArchState *env) {
158-159- static unsigned char tmp[4];
160-161- if (!afl_area_ptr) return;
162-163- /* Tell the parent that we're alive. If the parent doesn't want
164- to talk, assume that we're not running in forkserver mode. */
165-166- if (write(FORKSRV_FD + 1, tmp, 4) != 4) return;
167-168- afl_forksrv_pid = getpid();
169-170- /* All right, let's await orders... */
171-172- while (1) {
173-174- pid_t child_pid;
175- int status, t_fd[2];
176-177- /* Whoops, parent dead? */
178-179- if (read(FORKSRV_FD, tmp, 4) != 4) exit(2);
180-181- /* Establish a channel with child to grab translation commands. We'll
182- read from t_fd[0], child will write to TSL_FD. */
183-184- if (pipe(t_fd) || dup2(t_fd[1], TSL_FD) < 0) exit(3);
185- close(t_fd[1]);
186-187- child_pid = fork();
188- if (child_pid < 0) exit(4);
189-190- if (!child_pid) {
191-192- /* Child process. Close descriptors and run free. */
193-194- afl_fork_child = 1;
195- close(FORKSRV_FD);
196- close(FORKSRV_FD + 1);
197- close(t_fd[0]);
198- return;
199-200- }
201-202- /* Parent. */
203-204- close(TSL_FD);
205-206- if (write(FORKSRV_FD + 1, &child_pid, 4) != 4) exit(5);
207-208- /* Collect translation requests until child dies and closes the pipe. */
209-210- afl_wait_tsl(env, t_fd[0]);
211-212- /* Get and relay exit status to parent. */
213-214- if (waitpid(child_pid, &status, WUNTRACED) < 0) exit(6);
215- if (write(FORKSRV_FD + 1, &status, 4) != 4) exit(7);
216-217- }
218-219-}
220-221-222-/* The equivalent of the tuple logging routine from afl-as.h. */
223-224-static inline void afl_maybe_log(abi_ulong cur_loc) {
225-226- static abi_ulong prev_loc;
227-228- /* Optimize for cur_loc > afl_end_code, which is the most likely case on
229- Linux systems. */
230-231- if (cur_loc > afl_end_code || cur_loc < afl_start_code || !afl_area_ptr)
232- return;
233-234- /* Looks like QEMU always maps to fixed locations, so we can skip this:
235- cur_loc -= afl_start_code; */
236-237- /* Instruction addresses may be aligned. Let's mangle the value to get
238- something quasi-uniform. */
239-240- cur_loc = (cur_loc >> 4) ^ (cur_loc << 8);
241- cur_loc &= MAP_SIZE - 1;
242-243- /* Implement probabilistic instrumentation by looking at scrambled block
244- address. This keeps the instrumented locations stable across runs. */
245-246- if (cur_loc >= afl_inst_rms) return;
247-248- afl_area_ptr[cur_loc ^ prev_loc]++;
249- prev_loc = cur_loc >> 1;
250-251-}
252-253-254-/* This code is invoked whenever QEMU decides that it doesn't have a
255- translation of a particular block and needs to compute it. When this happens,
256- we tell the parent to mirror the operation, so that the next fork() has a
257- cached copy. */
258-259-static void afl_request_tsl(target_ulong pc, target_ulong cb, uint64_t flags) {
260-261- struct afl_tsl t;
262-263- if (!afl_fork_child) return;
264-265- t.pc = pc;
266- t.cs_base = cb;
267- t.flags = flags;
268-269- if (write(TSL_FD, &t, sizeof(struct afl_tsl)) != sizeof(struct afl_tsl))
270- return;
271-272-}
273-274-275-/* This is the other side of the same channel. Since timeouts are handled by
276- afl-fuzz simply killing the child, we can just wait until the pipe breaks. */
277-278-static void afl_wait_tsl(CPUArchState *env, int fd) {
279-280- struct afl_tsl t;
281-282- while (1) {
283-284- /* Broken pipe means it's time to return to the fork server routine. */
285-286- if (read(fd, &t, sizeof(struct afl_tsl)) != sizeof(struct afl_tsl))
287- break;
288-289- tb_find_slow(env, t.pc, t.cs_base, t.flags);
290-291- }
292-293- close(fd);
294-295-}
296-
···1-/*
2- american fuzzy lop - type definitions and minor macros
3- ------------------------------------------------------
4-5- Written and maintained by Michal Zalewski <lcamtuf@google.com>
6-7- Copyright 2013, 2014, 2015 Google Inc. All rights reserved.
8-9- Licensed under the Apache License, Version 2.0 (the "License");
10- you may not use this file except in compliance with the License.
11- You may obtain a copy of the License at:
12-13- http://www.apache.org/licenses/LICENSE-2.0
14-15- */
16-17-#ifndef _HAVE_TYPES_H
18-#define _HAVE_TYPES_H
19-20-#include <stdint.h>
21-#include <stdlib.h>
22-23-typedef uint8_t u8;
24-typedef uint16_t u16;
25-typedef uint32_t u32;
26-27-/*
28-29- Ugh. There is an unintended compiler / glibc #include glitch caused by
30- combining the u64 type an %llu in format strings, necessitating a workaround.
31-32- In essence, the compiler is always looking for 'unsigned long long' for %llu.
33- On 32-bit systems, the u64 type (aliased to uint64_t) is expanded to
34- 'unsigned long long' in <bits/types.h>, so everything checks out.
35-36- But on 64-bit systems, it is #ifdef'ed in the same file as 'unsigned long'.
37- Now, it only happens in circumstances where the type happens to have the
38- expected bit width, *but* the compiler does not know that... and complains
39- about 'unsigned long' being unsafe to pass to %llu.
40-41- */
42-43-#ifdef __x86_64__
44-typedef unsigned long long u64;
45-#else
46-typedef uint64_t u64;
47-#endif /* ^sizeof(...) */
48-49-typedef int8_t s8;
50-typedef int16_t s16;
51-typedef int32_t s32;
52-typedef int64_t s64;
53-54-#ifndef MIN
55-# define MIN(_a,_b) ((_a) > (_b) ? (_b) : (_a))
56-# define MAX(_a,_b) ((_a) > (_b) ? (_a) : (_b))
57-#endif /* !MIN */
58-59-#define SWAP16(_x) ({ \
60- u16 _ret = (_x); \
61- (u16)((_ret << 8) | (_ret >> 8)); \
62- })
63-64-#define SWAP32(_x) ({ \
65- u32 _ret = (_x); \
66- (u32)((_ret << 24) | (_ret >> 24) | \
67- ((_ret << 8) & 0x00FF0000) | \
68- ((_ret >> 8) & 0x0000FF00)); \
69- })
70-71-#define R(x) (random() % (x))
72-73-#define STRINGIFY_INTERNAL(x) #x
74-#define STRINGIFY(x) STRINGIFY_INTERNAL(x)
75-76-#define MEM_BARRIER() \
77- asm volatile("" ::: "memory")
78-79-#endif /* ! _HAVE_TYPES_H */