aboutsummaryrefslogtreecommitdiffstats
path: root/executor/executor.cc
diff options
context:
space:
mode:
authorAleksandr Nogikh <nogikh@google.com>2021-09-03 16:20:07 +0000
committerAleksandr Nogikh <wp32pw@gmail.com>2021-09-22 15:40:02 +0200
commit1c202847db0380015a8920bfd21375c2d9f28ddb (patch)
tree6693da3a936398a9ac6678842ac181c5f0e3e429 /executor/executor.cc
parenta7ce77be27d8e3728b97122a005bc5b23298cfc3 (diff)
all: refactor fault injection into call props
Now that call properties mechanism is implemented, we can refactor fault injection. Unfortunately, it is impossible to remove all traces of the previous apprach. In reprolist and while performing syz-ci jobs, syzkaller still needs to parse the old format. Remove the old prog options-based approach whenever possible and replace it with the use of call properties.
Diffstat (limited to 'executor/executor.cc')
-rw-r--r--executor/executor.cc45
1 files changed, 21 insertions, 24 deletions
diff --git a/executor/executor.cc b/executor/executor.cc
index 950f37cba..1aea79898 100644
--- a/executor/executor.cc
+++ b/executor/executor.cc
@@ -151,11 +151,6 @@ static bool flag_coverage_filter;
// If true, then executor should write the comparisons data to fuzzer.
static bool flag_comparisons;
-// Inject fault into flag_fault_nth-th operation in flag_fault_call-th syscall.
-static bool flag_fault;
-static int flag_fault_call;
-static int flag_fault_nth;
-
// Tunable timeouts, received with execute_req.
static uint64 syscall_timeout_ms;
static uint64 program_timeout_ms;
@@ -170,6 +165,7 @@ const int kMaxCommands = 1000; // prog package knows about this constant (prog.e
const uint64 instr_eof = -1;
const uint64 instr_copyin = -2;
const uint64 instr_copyout = -3;
+const uint64 instr_setprops = -4;
const uint64 arg_const = 0;
const uint64 arg_result = 1;
@@ -281,8 +277,6 @@ struct execute_req {
uint64 env_flags;
uint64 exec_flags;
uint64 pid;
- uint64 fault_call;
- uint64 fault_nth;
uint64 syscall_timeout_ms;
uint64 program_timeout_ms;
uint64 slowdown_scale;
@@ -589,21 +583,17 @@ void receive_execute()
slowdown_scale = req.slowdown_scale;
flag_collect_cover = req.exec_flags & (1 << 0);
flag_dedup_cover = req.exec_flags & (1 << 1);
- flag_fault = req.exec_flags & (1 << 2);
- flag_comparisons = req.exec_flags & (1 << 3);
- flag_threaded = req.exec_flags & (1 << 4);
- flag_collide = req.exec_flags & (1 << 5);
- flag_coverage_filter = req.exec_flags & (1 << 6);
- flag_fault_call = req.fault_call;
- flag_fault_nth = req.fault_nth;
+ flag_comparisons = req.exec_flags & (1 << 2);
+ flag_threaded = req.exec_flags & (1 << 3);
+ flag_collide = req.exec_flags & (1 << 4);
+ flag_coverage_filter = req.exec_flags & (1 << 5);
if (!flag_threaded)
flag_collide = false;
- debug("[%llums] exec opts: procid=%llu threaded=%d collide=%d cover=%d comps=%d dedup=%d fault=%d/%d/%d"
+ debug("[%llums] exec opts: procid=%llu threaded=%d collide=%d cover=%d comps=%d dedup=%d"
" timeouts=%llu/%llu/%llu prog=%llu filter=%d\n",
current_time_ms() - start_time_ms, procid, flag_threaded, flag_collide,
- flag_collect_cover, flag_comparisons, flag_dedup_cover, flag_fault,
- flag_fault_call, flag_fault_nth, syscall_timeout_ms, program_timeout_ms, slowdown_scale,
- req.prog_size, flag_coverage_filter);
+ flag_collect_cover, flag_comparisons, flag_dedup_cover, syscall_timeout_ms,
+ program_timeout_ms, slowdown_scale, req.prog_size, flag_coverage_filter);
if (syscall_timeout_ms == 0 || program_timeout_ms <= syscall_timeout_ms || slowdown_scale == 0)
failmsg("bad timeouts", "syscall=%llu, program=%llu, scale=%llu",
syscall_timeout_ms, program_timeout_ms, slowdown_scale);
@@ -674,7 +664,9 @@ retry:
int call_index = 0;
uint64 prog_extra_timeout = 0;
uint64 prog_extra_cover_timeout = 0;
+ bool has_fault_injection = false;
call_props_t call_props;
+ memset(&call_props, 0, sizeof(call_props));
for (;;) {
uint64 call_num = read_input(&input_pos);
@@ -765,11 +757,14 @@ retry:
// The copyout will happen when/if the call completes.
continue;
}
+ if (call_num == instr_setprops) {
+ read_call_props_t(call_props, read_input(&input_pos, false));
+ continue;
+ }
// Normal syscall.
if (call_num >= ARRAY_SIZE(syscalls))
failmsg("invalid syscall number", "call_num=%llu", call_num);
- read_call_props_t(call_props, read_input(&input_pos, false));
const call_t* call = &syscalls[call_num];
if (call->attrs.disabled)
failmsg("executing disabled syscall", "syscall=%s", call->name);
@@ -779,6 +774,7 @@ retry:
prog_extra_cover_timeout = std::max(prog_extra_cover_timeout, 500 * slowdown_scale);
if (strncmp(syscalls[call_num].name, "syz_80211_inject_frame", strlen("syz_80211_inject_frame")) == 0)
prog_extra_cover_timeout = std::max(prog_extra_cover_timeout, 300 * slowdown_scale);
+ has_fault_injection |= (call_props.fail_nth > 0);
uint64 copyout_index = read_input(&input_pos);
uint64 num_args = read_input(&input_pos);
if (num_args > kMaxArgs)
@@ -819,6 +815,7 @@ retry:
event_set(&th->done);
handle_completion(th);
}
+ memset(&call_props, 0, sizeof(call_props));
}
if (!colliding && !collide && running > 0) {
@@ -865,7 +862,7 @@ retry:
}
}
- if (flag_collide && !flag_fault && !colliding && !collide) {
+ if (flag_collide && !colliding && !has_fault_injection && !collide) {
debug("enabling collider\n");
collide = colliding = true;
goto retry;
@@ -1154,10 +1151,10 @@ void execute_call(thread_t* th)
int fail_fd = -1;
th->soft_fail_state = false;
- if (flag_fault && th->call_index == flag_fault_call) {
+ if (th->call_props.fail_nth > 0) {
if (collide)
fail("both collide and fault injection are enabled");
- fail_fd = inject_fault(flag_fault_nth);
+ fail_fd = inject_fault(th->call_props.fail_nth);
th->soft_fail_state = true;
}
@@ -1182,7 +1179,7 @@ void execute_call(thread_t* th)
}
th->fault_injected = false;
- if (flag_fault && th->call_index == flag_fault_call) {
+ if (th->call_props.fail_nth > 0) {
th->fault_injected = fault_injected(fail_fd);
}
@@ -1190,7 +1187,7 @@ void execute_call(thread_t* th)
th->id, current_time_ms() - start_time_ms, call->name, (uint64)th->res, th->reserrno);
if (flag_coverage)
debug("cover=%u ", th->cov.size);
- if (flag_fault && th->call_index == flag_fault_call)
+ if (th->call_props.fail_nth > 0)
debug("fault=%d ", th->fault_injected);
debug("\n");
}