aboutsummaryrefslogtreecommitdiffstats
path: root/executor
diff options
context:
space:
mode:
authorOvidiu Panait <ovpanait@gmail.com>2022-06-13 17:02:42 +0300
committerDmitry Vyukov <dvyukov@google.com>2022-06-14 10:19:39 +0200
commit9ce2c85a5c7104829269b904836201ccab6949f1 (patch)
tree166ce971b37e506e5b484296f7097693cb320811 /executor
parenta3bc5d68bc6cf57c55d4370027c295e367205c86 (diff)
executor: fix out of bounds write in lookup_connect_response_in()
gcc 12.1 reports the following -Werror=array-bounds error: /// In function 'bool lookup_connect_response_in(...)' executor/common_usb.h:632:66: error: array subscript 'usb_qualifier_descriptor[0]' is partly outside array bounds of 'char [8]' [-Werror=array-bounds] | 632 | qual->bNumConfigurations = index->dev->bNumConfigurations; | ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In function 'volatile long int syz_usb_connect_impl(...)': executor/common_usb_linux.h:332:23: note: object 'response_data' of size 8 | 332 | char* response_data = NULL; | ^~~~~~~~~~~~~ ... In function 'bool lookup_connect_response_in(...)', executor/common_usb.h:633:57: error: array subscript 'usb_qualifier_descriptor[0]' is partly outside array bounds of 'char [8]' [-Werror=array-bounds] | 633 | qual->bRESERVED = 0; | ~~~~~~~~~~~~~~~~^~~ In function 'volatile long int syz_usb_connect_impl(...)': executor/common_usb_linux.h:332:23: note: object 'response_data' of size 8 332 | char* response_data = NULL; | ^~~~~~~~~~~~~ /// Current code in USB_DT_DEVICE_QUALIFIER case treats respose_data as a buffer, but in reality it is just a pointer, as detailed in the error trace above. In order to allow passing a usb_qualifier_descriptor struct back to the caller (via response_data), add a new parameter to lookup_connect_response_in(). Build tested only. Fixes: 0c00210ff32 ("executor: always provide DEVICE_QUALIFIER USB descriptor") Signed-off-by: Ovidiu Panait <ovpanait@gmail.com>
Diffstat (limited to 'executor')
-rw-r--r--executor/common_usb.h4
-rw-r--r--executor/common_usb_linux.h3
-rw-r--r--executor/common_usb_netbsd.h3
3 files changed, 6 insertions, 4 deletions
diff --git a/executor/common_usb.h b/executor/common_usb.h
index 361605b0e..1cc4be980 100644
--- a/executor/common_usb.h
+++ b/executor/common_usb.h
@@ -577,6 +577,7 @@ static const char default_lang_id[] = {
static bool lookup_connect_response_in(int fd, const struct vusb_connect_descriptors* descs,
const struct usb_ctrlrequest* ctrl,
+ struct usb_qualifier_descriptor* qual,
char** response_data, uint32* response_length)
{
struct usb_device_index* index = lookup_usb_index(fd);
@@ -620,8 +621,6 @@ static bool lookup_connect_response_in(int fd, const struct vusb_connect_descrip
case USB_DT_DEVICE_QUALIFIER:
if (!descs->qual) {
// Fill in DEVICE_QUALIFIER based on DEVICE if not provided.
- struct usb_qualifier_descriptor* qual =
- (struct usb_qualifier_descriptor*)response_data;
qual->bLength = sizeof(*qual);
qual->bDescriptorType = USB_DT_DEVICE_QUALIFIER;
qual->bcdUSB = index->dev->bcdUSB;
@@ -631,6 +630,7 @@ static bool lookup_connect_response_in(int fd, const struct vusb_connect_descrip
qual->bMaxPacketSize0 = index->dev->bMaxPacketSize0;
qual->bNumConfigurations = index->dev->bNumConfigurations;
qual->bRESERVED = 0;
+ *response_data = (char*)qual;
*response_length = sizeof(*qual);
return true;
}
diff --git a/executor/common_usb_linux.h b/executor/common_usb_linux.h
index 451b2a7b1..82dcbade2 100644
--- a/executor/common_usb_linux.h
+++ b/executor/common_usb_linux.h
@@ -331,9 +331,10 @@ static volatile long syz_usb_connect_impl(uint64 speed, uint64 dev_len, const ch
char* response_data = NULL;
uint32 response_length = 0;
+ struct usb_qualifier_descriptor qual;
if (event.ctrl.bRequestType & USB_DIR_IN) {
- if (!lookup_connect_response_in(fd, descs, &event.ctrl, &response_data, &response_length)) {
+ if (!lookup_connect_response_in(fd, descs, &event.ctrl, &qual, &response_data, &response_length)) {
debug("syz_usb_connect: unknown request, stalling\n");
usb_raw_ep0_stall(fd);
continue;
diff --git a/executor/common_usb_netbsd.h b/executor/common_usb_netbsd.h
index 986555321..8705856d9 100644
--- a/executor/common_usb_netbsd.h
+++ b/executor/common_usb_netbsd.h
@@ -250,10 +250,11 @@ static volatile long syz_usb_connect_impl(int fd, uint64 speed, uint64 dev_len,
char* response_data = NULL;
uint32 response_length = 0;
+ struct usb_qualifier_descriptor qual;
char data[4096];
if (req.u.ctrl.bmRequestType & UE_DIR_IN) {
- if (!lookup_connect_response_in(fd, descs, (const struct usb_ctrlrequest*)&req.u.ctrl, &response_data, &response_length)) {
+ if (!lookup_connect_response_in(fd, descs, (const struct usb_ctrlrequest*)&req.u.ctrl, &qual, &response_data, &response_length)) {
debug("syz_usb_connect: unknown control IN request\n");
return -1;
}