aboutsummaryrefslogtreecommitdiffstats
path: root/executor
diff options
context:
space:
mode:
Diffstat (limited to 'executor')
-rw-r--r--executor/common_usb.h110
1 files changed, 68 insertions, 42 deletions
diff --git a/executor/common_usb.h b/executor/common_usb.h
index e6d5e7b80..6da4e4e17 100644
--- a/executor/common_usb.h
+++ b/executor/common_usb.h
@@ -80,13 +80,14 @@ struct usb_fuzzer_ep_io {
#define USB_FUZZER_IOCTL_INIT _IOW('U', 0, struct usb_fuzzer_init)
#define USB_FUZZER_IOCTL_RUN _IO('U', 1)
-#define USB_FUZZER_IOCTL_EP0_READ _IOWR('U', 2, struct usb_fuzzer_event)
+#define USB_FUZZER_IOCTL_EVENT_FETCH _IOR('U', 2, struct usb_fuzzer_event)
#define USB_FUZZER_IOCTL_EP0_WRITE _IOW('U', 3, struct usb_fuzzer_ep_io)
-#define USB_FUZZER_IOCTL_EP_ENABLE _IOW('U', 4, struct usb_endpoint_descriptor)
-#define USB_FUZZER_IOCTL_EP_WRITE _IOW('U', 6, struct usb_fuzzer_ep_io)
-#define USB_FUZZER_IOCTL_EP_READ _IOWR('U', 7, struct usb_fuzzer_ep_io)
-#define USB_FUZZER_IOCTL_CONFIGURE _IO('U', 8)
-#define USB_FUZZER_IOCTL_VBUS_DRAW _IOW('U', 9, uint32)
+#define USB_FUZZER_IOCTL_EP0_READ _IOWR('U', 4, struct usb_fuzzer_ep_io)
+#define USB_FUZZER_IOCTL_EP_ENABLE _IOW('U', 5, struct usb_endpoint_descriptor)
+#define USB_FUZZER_IOCTL_EP_WRITE _IOW('U', 7, struct usb_fuzzer_ep_io)
+#define USB_FUZZER_IOCTL_EP_READ _IOWR('U', 8, struct usb_fuzzer_ep_io)
+#define USB_FUZZER_IOCTL_CONFIGURE _IO('U', 9)
+#define USB_FUZZER_IOCTL_VBUS_DRAW _IOW('U', 10, uint32)
int usb_fuzzer_open()
{
@@ -107,9 +108,9 @@ int usb_fuzzer_run(int fd)
return ioctl(fd, USB_FUZZER_IOCTL_RUN, 0);
}
-int usb_fuzzer_ep0_read(int fd, struct usb_fuzzer_event* event)
+int usb_fuzzer_event_fetch(int fd, struct usb_fuzzer_event* event)
{
- return ioctl(fd, USB_FUZZER_IOCTL_EP0_READ, event);
+ return ioctl(fd, USB_FUZZER_IOCTL_EVENT_FETCH, event);
}
int usb_fuzzer_ep0_write(int fd, struct usb_fuzzer_ep_io* io)
@@ -117,6 +118,11 @@ int usb_fuzzer_ep0_write(int fd, struct usb_fuzzer_ep_io* io)
return ioctl(fd, USB_FUZZER_IOCTL_EP0_WRITE, io);
}
+int usb_fuzzer_ep0_read(int fd, struct usb_fuzzer_ep_io* io)
+{
+ return ioctl(fd, USB_FUZZER_IOCTL_EP0_READ, io);
+}
+
int usb_fuzzer_ep_write(int fd, struct usb_fuzzer_ep_io* io)
{
return ioctl(fd, USB_FUZZER_IOCTL_EP_WRITE, io);
@@ -170,7 +176,7 @@ struct vusb_connect_descriptors {
} __attribute__((packed));
static bool lookup_connect_response(struct vusb_connect_descriptors* descs, struct usb_device_index* index,
- struct usb_ctrlrequest* ctrl, char** response_data, uint32* response_length, bool* done)
+ struct usb_ctrlrequest* ctrl, char** response_data, uint32* response_length)
{
uint8 str_idx;
@@ -209,11 +215,6 @@ static bool lookup_connect_response(struct vusb_connect_descriptors* descs, stru
return false;
}
break;
- case USB_REQ_SET_CONFIGURATION:
- *response_length = 0;
- *response_data = NULL;
- *done = true;
- return true;
default:
fail("syz_usb_connect: no response");
return false;
@@ -229,8 +230,8 @@ static bool lookup_connect_response(struct vusb_connect_descriptors* descs, stru
static volatile long syz_usb_connect(volatile long a0, volatile long a1, volatile long a2, volatile long a3)
{
- int64_t speed = a0;
- int64_t dev_len = a1;
+ uint64 speed = a0;
+ uint64 dev_len = a1;
char* dev = (char*)a2;
struct vusb_connect_descriptors* descs = (struct vusb_connect_descriptors*)a3;
@@ -281,9 +282,9 @@ static volatile long syz_usb_connect(volatile long a0, volatile long a1, volatil
struct usb_fuzzer_control_event event;
event.inner.type = 0;
event.inner.length = sizeof(event.ctrl);
- rv = usb_fuzzer_ep0_read(fd, (struct usb_fuzzer_event*)&event);
+ rv = usb_fuzzer_event_fetch(fd, (struct usb_fuzzer_event*)&event);
if (rv < 0) {
- debug("syz_usb_connect: usb_fuzzer_ep0_read failed with %d\n", rv);
+ debug("syz_usb_connect: usb_fuzzer_event_fetch failed with %d\n", rv);
return rv;
}
if (event.inner.type != USB_FUZZER_EVENT_CONTROL)
@@ -296,10 +297,20 @@ static volatile long syz_usb_connect(volatile long a0, volatile long a1, volatil
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) {
- debug("syz_usb_connect: no response found\n");
- return -1;
+
+ if (event.ctrl.bRequestType & USB_DIR_IN) {
+ NONFAILING(response_found = lookup_connect_response(descs, &index, &event.ctrl, &response_data, &response_length));
+ if (!response_found) {
+ debug("syz_usb_connect: unknown IN request\n");
+ return -1;
+ }
+ } else {
+ if ((event.ctrl.bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD ||
+ event.ctrl.bRequest != USB_REQ_SET_CONFIGURATION) {
+ fail("syz_usb_connect: unknown OUT request");
+ return -1;
+ }
+ done = true;
}
if (done) {
@@ -329,15 +340,21 @@ static volatile long syz_usb_connect(volatile long a0, volatile long a1, volatil
response.inner.flags = 0;
if (response_length > sizeof(response.data))
response_length = 0;
+ if (event.ctrl.wLength < response_length)
+ response_length = event.ctrl.wLength;
response.inner.length = response_length;
if (response_data)
memcpy(&response.data[0], response_data, response_length);
- if (event.ctrl.wLength < response.inner.length)
- response.inner.length = event.ctrl.wLength;
+ else
+ memset(&response.data[0], 0, response_length);
+
debug("syz_usb_connect: reply length = %d\n", response.inner.length);
- rv = usb_fuzzer_ep0_write(fd, (struct usb_fuzzer_ep_io*)&response);
+ if (event.ctrl.bRequestType & USB_DIR_IN)
+ rv = usb_fuzzer_ep0_write(fd, (struct usb_fuzzer_ep_io*)&response);
+ else
+ rv = usb_fuzzer_ep0_read(fd, (struct usb_fuzzer_ep_io*)&response);
if (rv < 0) {
- debug("syz_usb_connect: usb_fuzzer_ep0_write failed with %d\n", rv);
+ debug("syz_usb_connect: usb_fuzzer_ep0_read/write failed with %d\n", rv);
return rv;
}
}
@@ -444,7 +461,7 @@ 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 = USB_MAX_PACKET_SIZE;
- int rv = usb_fuzzer_ep0_read(fd, (struct usb_fuzzer_event*)&event);
+ int rv = usb_fuzzer_event_fetch(fd, (struct usb_fuzzer_event*)&event);
if (rv < 0) {
debug("syz_usb_control_io: usb_fuzzer_ep0_read failed with %d\n", rv);
return rv;
@@ -458,18 +475,18 @@ static volatile long syz_usb_control_io(volatile long a0, volatile long a1, vola
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) {
- debug("syz_usb_control_io: no response found\n");
- return -1;
+
+ if (event.ctrl.bRequestType & USB_DIR_IN) {
+ NONFAILING(response_found = lookup_control_io_response(descs, resps, &event.ctrl, &response_data, &response_length));
+ if (!response_found) {
+ debug("syz_usb_control_io: no response found\n");
+ return -1;
+ }
+ } else {
+ response_length = event.ctrl.wLength;
}
struct usb_fuzzer_ep_io_data response;
@@ -477,16 +494,25 @@ static volatile long syz_usb_control_io(volatile long a0, volatile long a1, vola
response.inner.flags = 0;
if (response_length > sizeof(response.data))
response_length = 0;
+ if (event.ctrl.wLength < response_length)
+ response_length = event.ctrl.wLength;
response.inner.length = response_length;
if (response_data)
memcpy(&response.data[0], response_data, response_length);
- 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);
- debug_dump_data(&response.data[0], response.inner.length);
- rv = usb_fuzzer_ep0_write(fd, (struct usb_fuzzer_ep_io*)&response);
+ else
+ memset(&response.data[0], 0, response_length);
+
+ if (event.ctrl.bRequestType & USB_DIR_IN) {
+ debug("syz_usb_control_io: IN, length = %d\n", response.inner.length);
+ debug_dump_data(&response.data[0], response.inner.length);
+ rv = usb_fuzzer_ep0_write(fd, (struct usb_fuzzer_ep_io*)&response);
+ } else {
+ rv = usb_fuzzer_ep0_read(fd, (struct usb_fuzzer_ep_io*)&response);
+ debug("syz_usb_control_io: OUT, length = %d\n", response.inner.length);
+ debug_dump_data(&event.data[0], response.inner.length);
+ }
if (rv < 0) {
- debug("syz_usb_control_io: usb_fuzzer_ep0_write failed with %d\n", rv);
+ debug("syz_usb_control_io: usb_fuzzer_ep0_read/write failed with %d\n", rv);
return rv;
}