Skip to content

Commit

Permalink
ANDROID: usb: f_accessory: Check buffer size when initialised via com…
Browse files Browse the repository at this point in the history
…posite

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
Signed-off-by: Lee Jones <joneslee@google.com>
  • Loading branch information
lag-google committed Jan 23, 2023
1 parent f95873c commit f632042
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 2 deletions.
4 changes: 2 additions & 2 deletions drivers/usb/gadget/configfs.c
Expand Up @@ -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
Expand Down Expand Up @@ -1562,7 +1562,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)
Expand Down
20 changes: 20 additions & 0 deletions drivers/usb/gadget/function/f_accessory.c
Expand Up @@ -1076,6 +1076,26 @@ int acc_ctrlrequest(struct usb_composite_dev *cdev,
}
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)
Expand Down

0 comments on commit f632042

Please sign in to comment.