blob: 2cdbd052258871722349e9d0f7d97901d8aec624 [file] [log] [blame]
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