aboutsummaryrefslogtreecommitdiffstats
path: root/executor/executor.cc
diff options
context:
space:
mode:
authorAndrey Konovalov <andreyknvl@google.com>2019-04-11 15:44:07 +0200
committerDmitry Vyukov <dvyukov@google.com>2019-04-11 16:24:45 +0200
commitf4a3dc91283f5ab016f166ffec32f9c08e0ba174 (patch)
tree322e6242062367a881530c527e84da5b4cc265e3 /executor/executor.cc
parent10e721ba9292fd30750d4c38e11a15d2fbab8f23 (diff)
all: add basic USB fuzzing support
This commits implements 4 syzcalls: syz_usb_connect, syz_usb_io_control, syz_usb_ep_write and syz_usb_disconnect. Those syzcalls are used to emit USB packets through a custom GadgetFS-like interface (currently exposed at /sys/kernel/debug/usb-fuzzer), which requires special kernel patches. USB fuzzing support is quite basic, as it mostly covers only the USB device enumeration process. Even though the syz_usb_ep_write syzcall does allow to communicate with USB endpoints after the device has been enumerated, no coverage is collected from that code yet.
Diffstat (limited to 'executor/executor.cc')
-rw-r--r--executor/executor.cc15
1 files changed, 14 insertions, 1 deletions
diff --git a/executor/executor.cc b/executor/executor.cc
index bbbb2da31..1c9d857c8 100644
--- a/executor/executor.cc
+++ b/executor/executor.cc
@@ -572,10 +572,16 @@ retry:
}
int call_index = 0;
+ bool usb_prog = false;
for (;;) {
uint64 call_num = read_input(&input_pos);
if (call_num == instr_eof)
break;
+ bool usb_call = false;
+ if (strcmp(syscalls[call_num].name, "syz_usb_connect") == 0) {
+ usb_prog = true;
+ usb_call = true;
+ }
if (call_num == instr_copyin) {
char* addr = (char*)read_input(&input_pos);
uint64 typ = read_input(&input_pos);
@@ -684,7 +690,7 @@ retry:
} else if (flag_threaded) {
// Wait for call completion.
// Note: sys knows about this 25ms timeout when it generates timespec/timeval values.
- const uint64 timeout_ms = flag_debug ? 1000 : 45;
+ const uint64 timeout_ms = usb_call ? 2000 : (flag_debug ? 1000 : 45);
if (event_timedwait(&th->done, timeout_ms))
handle_completion(th);
// Check if any of previous calls have completed.
@@ -712,6 +718,8 @@ retry:
uint64 wait_end = wait_start + wait;
if (wait_end < start + 800)
wait_end = start + 800;
+ if (usb_prog)
+ wait_end += 2000;
while (running > 0 && current_time_ms() <= wait_end) {
sleep_ms(1);
for (int i = 0; i < kMaxThreads; i++) {
@@ -738,6 +746,11 @@ retry:
close_fds();
#endif
+ if (!colliding && !collide && usb_prog) {
+ sleep_ms(500);
+ write_extra_output();
+ }
+
if (flag_collide && !flag_inject_fault && !colliding && !collide) {
debug("enabling collider\n");
collide = colliding = true;