-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathcov.cc
148 lines (123 loc) · 4.21 KB
/
cov.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include "fuzz.h"
#include "time.h"
#include "conveyor.h"
#include <tsl/robin_map.h>
#include <tsl/robin_set.h>
tsl::robin_map<bx_address, bool> ignore_edges;
tsl::robin_set<bx_address> seen_edges;
tsl::robin_map<bx_address, uint64_t> all_edges;
tsl::robin_map<bx_address, uint64_t> edge_to_idx;
tsl::robin_set<bx_address> cur_input;
std::vector<std::pair<size_t, size_t>> pc_ranges;
std::vector<std::pair<size_t, size_t>> our_stacktrace;
__attribute__((section(
"__libfuzzer_extra_counters"))) unsigned char libfuzzer_coverage[32 << 10];
uint32_t status = 0;
void add_pc_range(size_t base, size_t len) {
printf("Will treat: %lx +%lx as coverage\n", base, len);
pc_ranges.push_back(std::make_pair(base, len));
}
bool ignore_pc(bx_address pc) {
if (pc_ranges.size() == 0) // No ranges = fuzz everthing
return false;
if (ignore_edges.find(pc) == ignore_edges.end()) {
bool ignore = true;
for (auto &r : pc_ranges) {
if (pc >= r.first && pc <= r.first + r.second) {
ignore = false;
break;
}
}
ignore_edges[pc] = ignore;
}
return ignore_edges[pc];
}
static size_t last_new = 0;
void print_stacktrace(){
printf("Stacktrace:\n");
if(our_stacktrace.empty())
return;
for (auto r = our_stacktrace.rbegin(); r != our_stacktrace.rend(); ++r)
{
printf("%016lx -> %016lx\n", r->first, r->second);
}
fflush(stdout);
fflush(stderr);
}
void add_edge(bx_address prev_rip, bx_address new_rip) {
time_t t;
symbolize(new_rip);
if(fuzzing) {
if(cur_input.emplace(new_rip).second)
last_new = 0;
if(last_new++ > 100000 && !master_fuzzer ){
printf("No new edges for over %d..\n", last_new);
fuzz_emu_stop_unhealthy();
}
if(last_new > 300000 && master_fuzzer ){
printf("No new edges for over %d..\n", last_new);
fuzz_stacktrace();
fuzz_emu_stop_unhealthy();
}
}
if (ignore_pc(new_rip))
return;
libfuzzer_coverage[new_rip % sizeof(libfuzzer_coverage)]++;
if (seen_edges.emplace(new_rip).second) {
time(&t);
auto s = addr_to_sym(new_rip);
printf("[%d] NEW_PC: %lx %s (%s)\n", t, new_rip, s.second.c_str(), s.first.c_str());
status |= (1 << 1); // new pc
}
}
void reset_op_cov() {
last_new = 0;
}
void reset_cur_cov() {
our_stacktrace.clear();
cur_input.clear();
last_new = 0;
libfuzzer_coverage[0] = 1;
}
void fuzz_instr_cnear_branch_taken(bx_address branch_rip, bx_address new_rip) {
add_edge(branch_rip, new_rip);
}
void fuzz_instr_cnear_branch_not_taken(bx_address branch_rip) {}
uint32_t get_sysret_status() { return status; }
void reset_sysret_status() { status = 0; }
void fuzz_stacktrace(){
/* if(master_fuzzer) */
if(fuzzing)
ic_dump();
static void *log_crashes = getenv("LOG_CRASHES");
if(!log_crashes)
return;
print_stacktrace();
}
void fuzz_instr_ucnear_branch(unsigned what, bx_address branch_rip,
bx_address new_rip) {
if (what == BX_INSTR_IS_SYSRET)
status |= 1; // sysret
if((what == BX_INSTR_IS_CALL || what == BX_INSTR_IS_CALL_INDIRECT) && BX_CPU(0)->user_pl ) {
our_stacktrace.push_back(std::make_pair(branch_rip, new_rip));
/* fuzz_stacktrace(); */
} else if (what == BX_INSTR_IS_RET && BX_CPU(0)->user_pl&& !our_stacktrace.empty()) {
our_stacktrace.pop_back();
/* fuzz_stacktrace(); */
}
add_edge(branch_rip, new_rip);
}
void fuzz_instr_far_branch(unsigned what, Bit16u prev_cs, bx_address prev_rip,
Bit16u new_cs, bx_address new_rip) {
if (what == BX_INSTR_IS_SYSRET)
status |= 1; // sysret
if((what == BX_INSTR_IS_CALL || what == BX_INSTR_IS_CALL_INDIRECT) && BX_CPU(0)->user_pl) {
our_stacktrace.push_back(std::make_pair(prev_rip, new_rip));
/* fuzz_stacktrace(); */
} else if (what == BX_INSTR_IS_RET && BX_CPU(0)->user_pl && !our_stacktrace.empty()) {
our_stacktrace.pop_back();
/* fuzz_stacktrace(); */
}
if (what == BX_INSTR_IS_IRET && (new_rip >> 63) == 0)
add_edge(prev_rip, new_rip);
}