aboutsummaryrefslogtreecommitdiffstats
path: root/executor
diff options
context:
space:
mode:
Diffstat (limited to 'executor')
-rw-r--r--executor/common_usb.h103
-rw-r--r--executor/executor.cc20
2 files changed, 87 insertions, 36 deletions
diff --git a/executor/common_usb.h b/executor/common_usb.h
index 31071fd8c..8fe2b641b 100644
--- a/executor/common_usb.h
+++ b/executor/common_usb.h
@@ -139,6 +139,7 @@ int usb_fuzzer_vbus_draw(int fd, uint32 power)
struct usb_fuzzer_control_event {
struct usb_fuzzer_event inner;
struct usb_ctrlrequest ctrl;
+ char data[USB_MAX_PACKET_SIZE];
};
struct usb_fuzzer_ep_io_data {
@@ -180,8 +181,10 @@ static bool lookup_connect_response(struct vusb_connect_descriptors* descs, stru
return true;
case USB_DT_STRING:
str_idx = (uint8)ctrl->wValue;
- if (str_idx >= descs->strs_len)
- return false;
+ if (str_idx >= descs->strs_len && descs->strs_len > 0) {
+ // Use the last string if we ran out.
+ str_idx = descs->strs_len - 1;
+ }
*response_data = descs->strs[str_idx].str;
*response_length = descs->strs[str_idx].len;
return true;
@@ -232,27 +235,35 @@ static volatile long syz_usb_connect(volatile long a0, volatile long a1, volatil
struct usb_device_index index;
memset(&index, 0, sizeof(index));
- int rv = false;
+ int rv = 0;
NONFAILING(rv = parse_usb_descriptor(dev, dev_len, &index));
- if (!rv)
- return -1;
+ if (!rv) {
+ debug("syz_usb_connect: parse_usb_descriptor failed with %d\n", rv);
+ return rv;
+ }
debug("syz_usb_connect: parsed usb descriptor\n");
int fd = usb_fuzzer_open();
- if (fd < 0)
- return -1;
+ if (fd < 0) {
+ debug("syz_usb_connect: usb_fuzzer_open failed with %d\n", rv);
+ return fd;
+ }
debug("syz_usb_connect: usb_fuzzer_open success\n");
char device[32];
sprintf(&device[0], "dummy_udc.%llu", procid);
rv = usb_fuzzer_init(fd, speed, "dummy_udc", &device[0]);
- if (rv < 0)
- return -1;
+ if (rv < 0) {
+ debug("syz_usb_connect: usb_fuzzer_init failed with %d\n", rv);
+ return rv;
+ }
debug("syz_usb_connect: usb_fuzzer_init success\n");
rv = usb_fuzzer_run(fd);
- if (rv < 0)
- return -1;
+ if (rv < 0) {
+ debug("syz_usb_connect: usb_fuzzer_run failed with %d\n", rv);
+ return rv;
+ }
debug("syz_usb_connect: usb_fuzzer_run success\n");
bool done = false;
@@ -261,28 +272,37 @@ static volatile long syz_usb_connect(volatile long a0, volatile long a1, volatil
event.inner.type = 0;
event.inner.length = sizeof(event.ctrl);
rv = usb_fuzzer_ep0_read(fd, (struct usb_fuzzer_event*)&event);
- if (rv < 0)
- return -1;
+ if (rv < 0) {
+ debug("syz_usb_connect: usb_fuzzer_ep0_read failed with %d\n", rv);
+ return rv;
+ }
if (event.inner.type != USB_FUZZER_EVENT_CONTROL)
continue;
- debug("syz_usb_connect: bRequestType: 0x%x, bRequest: 0x%x, wValue: 0x%x, wIndex: 0x%x, wLength: %d\n",
- event.ctrl.bRequestType, event.ctrl.bRequest, event.ctrl.wValue, event.ctrl.wIndex, event.ctrl.wLength);
+ debug("syz_usb_connect: bRequestType: 0x%x (%s), bRequest: 0x%x, wValue: 0x%x, wIndex: 0x%x, wLength: %d\n",
+ event.ctrl.bRequestType, (event.ctrl.bRequestType & USB_DIR_IN) ? "IN" : "OUT",
+ event.ctrl.bRequest, event.ctrl.wValue, event.ctrl.wIndex, event.ctrl.wLength);
bool response_found = false;
char* response_data = NULL;
uint32 response_length = 0;
NONFAILING(response_found = lookup_connect_response(descs, &index, &event.ctrl, &response_data, &response_length, &done));
- if (!response_found)
+ if (!response_found) {
+ debug("syz_usb_connect: no response found\n");
return -1;
+ }
if (done) {
- int rv = usb_fuzzer_vbus_draw(fd, index.config->bMaxPower);
- if (rv < 0)
- return -1;
+ rv = usb_fuzzer_vbus_draw(fd, index.config->bMaxPower);
+ if (rv < 0) {
+ debug("syz_usb_connect: usb_fuzzer_vbus_draw failed with %d\n", rv);
+ return rv;
+ }
rv = usb_fuzzer_configure(fd);
- if (rv < 0)
- return -1;
+ if (rv < 0) {
+ debug("syz_usb_connect: usb_fuzzer_configure failed with %d\n", rv);
+ return rv;
+ }
unsigned ep;
for (ep = 0; ep < index.eps_num; ep++) {
rv = usb_fuzzer_ep_enable(fd, index.eps[ep]);
@@ -302,7 +322,11 @@ static volatile long syz_usb_connect(volatile long a0, volatile long a1, volatil
if (event.ctrl.wLength < response.inner.length)
response.inner.length = event.ctrl.wLength;
debug("syz_usb_connect: reply length = %d\n", response.inner.length);
- usb_fuzzer_ep0_write(fd, (struct usb_fuzzer_ep_io*)&response);
+ rv = usb_fuzzer_ep0_write(fd, (struct usb_fuzzer_ep_io*)&response);
+ if (rv < 0) {
+ debug("syz_usb_connect: usb_fuzzer_ep0_write failed with %d\n", rv);
+ return rv;
+ }
}
sleep_ms(200);
@@ -406,22 +430,34 @@ static volatile long syz_usb_control_io(volatile long a0, volatile long a1, vola
struct usb_fuzzer_control_event event;
event.inner.type = 0;
- event.inner.length = sizeof(event.ctrl);
+ event.inner.length = USB_MAX_PACKET_SIZE;
int rv = usb_fuzzer_ep0_read(fd, (struct usb_fuzzer_event*)&event);
- if (rv < 0)
- return -1;
- if (event.inner.type != USB_FUZZER_EVENT_CONTROL)
+ if (rv < 0) {
+ debug("syz_usb_control_io: usb_fuzzer_ep0_read failed with %d\n", rv);
+ return rv;
+ }
+ if (event.inner.type != USB_FUZZER_EVENT_CONTROL) {
+ debug("syz_usb_control_io: wrong event type: %d\n", (int)event.inner.type);
return -1;
+ }
- debug("syz_usb_control_io: bRequestType: 0x%x, bRequest: 0x%x, wValue: 0x%x, wIndex: 0x%x, wLength: %d\n",
- event.ctrl.bRequestType, event.ctrl.bRequest, event.ctrl.wValue, event.ctrl.wIndex, event.ctrl.wLength);
+ debug("syz_usb_control_io: bRequestType: 0x%x (%s), bRequest: 0x%x, wValue: 0x%x, wIndex: 0x%x, wLength: %d\n",
+ event.ctrl.bRequestType, (event.ctrl.bRequestType & USB_DIR_IN) ? "IN" : "OUT",
+ event.ctrl.bRequest, event.ctrl.wValue, event.ctrl.wIndex, event.ctrl.wLength);
+
+ if (!(event.ctrl.bRequestType & USB_DIR_IN) && event.ctrl.wLength != 0) {
+ debug("syz_usb_control_io: OUT data:\n");
+ debug_dump_data(&event.data[0], event.ctrl.wLength);
+ }
bool response_found = false;
char* response_data = NULL;
uint32 response_length = 0;
NONFAILING(response_found = lookup_control_io_response(descs, resps, &event.ctrl, &response_data, &response_length));
- if (!response_found)
+ if (!response_found) {
+ debug("syz_usb_control_io: no response found\n");
return -1;
+ }
struct usb_fuzzer_ep_io_data response;
response.inner.ep = 0;
@@ -434,7 +470,14 @@ static volatile long syz_usb_control_io(volatile long a0, volatile long a1, vola
if (event.ctrl.wLength < response.inner.length)
response.inner.length = event.ctrl.wLength;
debug("syz_usb_control_io: response length = %d\n", response.inner.length);
- usb_fuzzer_ep0_write(fd, (struct usb_fuzzer_ep_io*)&response);
+ debug_dump_data(&response.data[0], response.inner.length);
+ rv = usb_fuzzer_ep0_write(fd, (struct usb_fuzzer_ep_io*)&response);
+ if (rv < 0) {
+ debug("syz_usb_control_io: usb_fuzzer_ep0_write failed with %d\n", rv);
+ return rv;
+ }
+
+ sleep_ms(200);
return 0;
}
diff --git a/executor/executor.cc b/executor/executor.cc
index 2ea588b72..597f6d656 100644
--- a/executor/executor.cc
+++ b/executor/executor.cc
@@ -601,12 +601,16 @@ retry:
prog_extra_cover = true;
call_extra_cover = true;
}
- if (strcmp(syscalls[call_num].name, "syz_usb_connect") == 0) {
+ if (strncmp(syscalls[call_num].name, "syz_usb_connect", strlen("syz_usb_connect")) == 0) {
prog_extra_timeout = 2000;
// Must match timeout in pkg/csource/csource.go.
call_extra_timeout = 2000;
}
- if (strcmp(syscalls[call_num].name, "syz_usb_disconnect") == 0) {
+ if (strncmp(syscalls[call_num].name, "syz_usb_control_io", strlen("syz_usb_control_io")) == 0) {
+ // Must match timeout in pkg/csource/csource.go.
+ call_extra_timeout = 200;
+ }
+ if (strncmp(syscalls[call_num].name, "syz_usb_disconnect", strlen("syz_usb_disconnect")) == 0) {
// Must match timeout in pkg/csource/csource.go.
call_extra_timeout = 200;
}
@@ -723,6 +727,7 @@ retry:
timeout_ms = 1000;
if (event_timedwait(&th->done, timeout_ms))
handle_completion(th);
+
// Check if any of previous calls have completed.
for (int i = 0; i < kMaxThreads; i++) {
th = &threads[i];
@@ -776,9 +781,10 @@ retry:
close_fds();
#endif
- if (!colliding && !collide && prog_extra_cover) {
+ if (prog_extra_cover) {
sleep_ms(500);
- write_extra_output();
+ if (!colliding && !collide)
+ write_extra_output();
}
if (flag_collide && !flag_inject_fault && !colliding && !collide) {
@@ -1446,10 +1452,12 @@ void debug_dump_data(const char* data, int length)
{
if (!flag_debug)
return;
- for (int i = 0; i < length; i++) {
+ int i;
+ for (i = 0; i < length; i++) {
debug("%02x ", data[i] & 0xff);
if (i % 16 == 15)
debug("\n");
}
- debug("\n");
+ if (i % 16 != 0)
+ debug("\n");
}