diff options
author | Lee Jones <joneslee@google.com> | 2023-01-18 15:49:24 +0000 |
---|---|---|
committer | Treehugger Robot <treehugger-gerrit@google.com> | 2023-02-22 13:32:47 +0000 |
commit | 4f395d027c56724ad1b52d63ecb6cee2ea0b77cb (patch) | |
tree | 14eb99f9071e8410a7fb4f0ccbc5b945c9af3c67 | |
parent | 94580fe8ee700a835c13a86ad0f6d3b874296022 (diff) | |
download | common-4f395d027c56724ad1b52d63ecb6cee2ea0b77cb.tar.gz |
ANDROID: usb: f_accessory: Check buffer size when initialised via composite
When communicating with accessory devices via USBFS, the initialisation
call-stack looks like:
ConfigFS > Gadget ConfigFS > UDC > Gadget ConfigFS > Composite
Eventually ending up in composite_dev_prepare() where memory for the
data buffer is allocated and initialised. The default size used for the
allocation is USB_COMP_EP0_BUFSIZ (4k). When handling bulk transfers,
acc_ctrlrequest() needs to be able to handle buffers up to
BULK_BUFFER_SIZE (16k). Instead of adding new generic attributes to
'struct usb_request' to track the size of the allocated buffer, we can
simply split off the affected thread of execution to travel via a
knowledgeable abstracted function acc_ctrlrequest_composite() where we
can complete the necessary specific checks.
Bug: 264029575
Signed-off-by: Lee Jones <joneslee@google.com>
Change-Id: Ia1280f85499621d3fa57f7262b4a2c80f4be7773
-rw-r--r-- | drivers/usb/gadget/configfs.c | 4 | ||||
-rw-r--r-- | drivers/usb/gadget/function/f_accessory.c | 20 |
2 files changed, 22 insertions, 2 deletions
diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index 21dd268175c6..b6f86463a26e 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -16,7 +16,7 @@ #include <linux/usb/ch9.h> #ifdef CONFIG_USB_CONFIGFS_F_ACC -extern int acc_ctrlrequest(struct usb_composite_dev *cdev, +extern int acc_ctrlrequest_composite(struct usb_composite_dev *cdev, const struct usb_ctrlrequest *ctrl); void acc_disconnect(void); #endif @@ -1572,7 +1572,7 @@ static int android_setup(struct usb_gadget *gadget, #ifdef CONFIG_USB_CONFIGFS_F_ACC if (value < 0) - value = acc_ctrlrequest(cdev, c); + value = acc_ctrlrequest_composite(cdev, c); #endif if (value < 0) diff --git a/drivers/usb/gadget/function/f_accessory.c b/drivers/usb/gadget/function/f_accessory.c index 3510f6d39f0c..7d35d6c58e47 100644 --- a/drivers/usb/gadget/function/f_accessory.c +++ b/drivers/usb/gadget/function/f_accessory.c @@ -1085,6 +1085,26 @@ err: } EXPORT_SYMBOL_GPL(acc_ctrlrequest); +int acc_ctrlrequest_composite(struct usb_composite_dev *cdev, + const struct usb_ctrlrequest *ctrl) +{ + u16 w_length = le16_to_cpu(ctrl->wLength); + + if (w_length > USB_COMP_EP0_BUFSIZ) { + if (ctrl->bRequestType & USB_DIR_IN) { + /* Cast away the const, we are going to overwrite on purpose. */ + __le16 *temp = (__le16 *)&ctrl->wLength; + + *temp = cpu_to_le16(USB_COMP_EP0_BUFSIZ); + w_length = USB_COMP_EP0_BUFSIZ; + } else { + return -EINVAL; + } + } + return acc_ctrlrequest(cdev, ctrl); +} +EXPORT_SYMBOL_GPL(acc_ctrlrequest_composite); + static int __acc_function_bind(struct usb_configuration *c, struct usb_function *f, bool configfs) |