| From c175e82be256b1ff9a13d8ec432cd2188d99c93b Mon Sep 17 00:00:00 2001 |
| From: Lee Jones <joneslee@google.com> |
| Date: Wed, 18 Jan 2023 15:49:24 +0000 |
| Subject: [PATCH] FROMGIT: 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> |
| Signed-off-by: Lee Jones <joneslee@google.com> |
| (cherry picked from commit 9a8dcea6abcf74b5f463e0d2cb9ffc0d739a6a0d |
| https://android.googlesource.com/kernel/common android13-5.15) |
| |
| BUG=b:271919375 |
| TEST=CQ |
| |
| Change-Id: I263b69453069541cf3a0c19a9e7d786f37a58a17 |
| Disallow-Recycled-Builds: test-failures |
| Signed-off-by: Guenter Roeck <groeck@chromium.org> |
| Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/4313625 |
| Reviewed-by: Sean Paul <sean@poorly.run> |
| Reviewed-by: Zubin Mithra <zsm@chromium.org> |
| |
| [rebase66(tzungbi): |
| Squashed: |
| FIXUP: FROMGIT: ANDROID: usb: f_accessory: Check buffer size when initialised via composite |
| (https://crrev.com/c/4805766) |
| ] |
| Signed-off-by: Tzung-Bi Shih <tzungbi@chromium.org> |
| --- |
| drivers/usb/gadget/configfs.c | 6 +++--- |
| drivers/usb/gadget/function/f_accessory.c | 22 +++++++++++++++++++++- |
| 2 files changed, 24 insertions(+), 4 deletions(-) |
| |
| diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c |
| index cd18217bc29b0c56f39d3e7ecebb99ba11b4e3a9..505f85924a20ba828329d446f5cdcff88ae51488 100644 |
| --- a/drivers/usb/gadget/configfs.c |
| +++ b/drivers/usb/gadget/configfs.c |
| @@ -18,8 +18,8 @@ |
| #include <linux/usb/ch9.h> |
| |
| #ifdef CONFIG_USB_CONFIGFS_F_ACC |
| -extern int acc_ctrlrequest(struct usb_composite_dev *cdev, |
| - const struct usb_ctrlrequest *ctrl); |
| +extern int acc_ctrlrequest_composite(struct usb_composite_dev *cdev, |
| + const struct usb_ctrlrequest *ctrl); |
| void acc_disconnect(void); |
| #endif |
| static struct class *android_class; |
| @@ -1958,7 +1958,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 a9bd9061298603f9fa269d3030d9ef6c25006fe2..32fa3480c765ca8931295e2d1831221ae26454fd 100644 |
| --- a/drivers/usb/gadget/function/f_accessory.c |
| +++ b/drivers/usb/gadget/function/f_accessory.c |
| @@ -1075,6 +1075,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) |
| @@ -1501,7 +1521,7 @@ static void acc_free(struct usb_function *f) |
| put_acc_dev(dev); |
| } |
| |
| -int acc_ctrlrequest_configfs(struct usb_function *f, |
| +static int acc_ctrlrequest_configfs(struct usb_function *f, |
| const struct usb_ctrlrequest *ctrl) { |
| if (f->config != NULL && f->config->cdev != NULL) |
| return acc_ctrlrequest(f->config->cdev, ctrl); |
| -- |
| 2.47.0.277.g8800431eea-goog |
| |