Skip to content
This repository was archived by the owner on Mar 22, 2024. It is now read-only.

Commit 63eb62a

Browse files
committed
Hot-path acceleration: introduce has_new_bits_unclassified
1 parent ec22876 commit 63eb62a

File tree

1 file changed

+36
-4
lines changed

1 file changed

+36
-4
lines changed

afl-fuzz.c

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,6 +1085,22 @@ static inline u8 has_new_bits(u8* virgin_map) {
10851085
}
10861086

10871087

1088+
/* A combination of classify_counts and has_new_bits. If 0 is returned, then the
1089+
* trace bits are kept as-is. Otherwise, the trace bits are overwritten with
1090+
* classified values.
1091+
*
1092+
* This accelerates the processing: in most cases, no interesting behavior
1093+
* happen, and the trace bits will be discarded soon. This function optimizes
1094+
* for such cases: one-pass scan on trace bits without modifying anything. Only
1095+
* on rare cases it fall backs to the slow path: classify_counts() first, then
1096+
* return has_new_bits(). */
1097+
1098+
static inline u8 has_new_bits_unclassified(u8* virgin_map) {
1099+
classify_counts(trace_bits); // TODO
1100+
return has_new_bits(virgin_map);
1101+
}
1102+
1103+
10881104
/* Get rid of shared memory (atexit handler). */
10891105

10901106
static void remove_shm(void) {
@@ -2318,7 +2334,6 @@ static u8 run_target(char** argv, u32 timeout) {
23182334
MEM_BARRIER();
23192335

23202336
tb4 = *(u32*)trace_bits;
2321-
classify_counts(trace_bits);
23222337

23232338
prev_timed_out = child_timed_out;
23242339

@@ -2475,6 +2490,7 @@ static u8 calibrate_case(char** argv, struct queue_entry* q, u8* use_mem,
24752490
write_to_testcase(use_mem, q->len);
24762491

24772492
fault = run_target(argv, use_tmout);
2493+
classify_counts(trace_bits);
24782494

24792495
/* stop_soon is set by the handler for Ctrl+C. When it's pressed,
24802496
we want to bail out quickly. */
@@ -3013,24 +3029,26 @@ static void write_crash_readme(void) {
30133029

30143030
/* Check if the result of an execve() during routine fuzzing is interesting,
30153031
save or queue the input test case for further analysis if so. Returns 1 if
3016-
entry is saved, 0 otherwise. */
3032+
entry is saved, 0 otherwise. When invoking this function, trace bits should
3033+
not be classified. */
30173034

30183035
static u8 save_if_interesting(char** argv, void* mem, u32 len, u8 fault) {
30193036

30203037
u8 *fn = "";
30213038
u8 hnb;
30223039
s32 fd;
3023-
u8 keeping = 0, res;
3040+
u8 keeping = 0, res, classified = 0;
30243041

30253042
if (fault == crash_mode) {
30263043

30273044
/* Keep only if there are new bits in the map, add to queue for
30283045
future fuzzing, etc. */
30293046

3030-
if (!(hnb = has_new_bits(virgin_bits))) {
3047+
if (!(hnb = has_new_bits_unclassified(virgin_bits))) {
30313048
if (crash_mode) total_crashes++;
30323049
return 0;
30333050
}
3051+
classified = hnb;
30343052

30353053
#ifndef SIMPLE_FILES
30363054

@@ -3084,6 +3102,11 @@ static u8 save_if_interesting(char** argv, void* mem, u32 len, u8 fault) {
30843102

30853103
if (!dumb_mode) {
30863104

3105+
if (!classified) {
3106+
classify_counts(trace_bits);
3107+
classified = 1;
3108+
}
3109+
30873110
simplify_trace(trace_bits);
30883111
if (!has_new_bits(virgin_tmout)) return keeping;
30893112

@@ -3100,6 +3123,7 @@ static u8 save_if_interesting(char** argv, void* mem, u32 len, u8 fault) {
31003123
u8 new_fault;
31013124
write_to_testcase(mem, len);
31023125
new_fault = run_target(argv, hang_tmout);
3126+
classify_counts(trace_bits);
31033127

31043128
/* A corner case that one user reported bumping into: increasing the
31053129
timeout actually uncovers a crash. Make sure we don't discard it if
@@ -3143,6 +3167,11 @@ static u8 save_if_interesting(char** argv, void* mem, u32 len, u8 fault) {
31433167

31443168
if (!dumb_mode) {
31453169

3170+
if (!classified) {
3171+
classify_counts(trace_bits);
3172+
classified = 1;
3173+
}
3174+
31463175
simplify_trace(trace_bits);
31473176
if (!has_new_bits(virgin_crash)) return keeping;
31483177

@@ -4413,6 +4442,7 @@ static u8 trim_case(char** argv, struct queue_entry* q, u8* in_buf) {
44134442
write_with_gap(in_buf, q->len, remove_pos, trim_avail);
44144443

44154444
fault = run_target(argv, exec_tmout);
4445+
classify_counts(trace_bits);
44164446
trim_execs++;
44174447

44184448
if (stop_soon || fault == FAULT_ERROR) goto abort_trimming;
@@ -4505,6 +4535,7 @@ EXP_ST u8 common_fuzz_stuff(char** argv, u8* out_buf, u32 len) {
45054535

45064536
write_to_testcase(out_buf, len);
45074537

4538+
/* Don't classify counts, leave the job to save_if_interesting. */
45084539
fault = run_target(argv, exec_tmout);
45094540

45104541
if (stop_soon) return 1;
@@ -6641,6 +6672,7 @@ static void sync_fuzzers(char** argv) {
66416672
write_to_testcase(mem, st.st_size);
66426673

66436674
fault = run_target(argv, exec_tmout);
6675+
/* Don't classify counts, leave the job to save_if_interesting. */
66446676

66456677
if (stop_soon) return;
66466678

0 commit comments

Comments
 (0)