Skip to content

Commit

Permalink
usb: gadget: android: Save/restore ep0 completion function
Browse files Browse the repository at this point in the history
The android_setup() function currently gives the f_accessory
setup function first opportunity to handle control requests
in order to support Android Open Accessory (AOA) hosts. That
function makes use of cdev->req and overrides its completion
function, but not in all cases. Thus, if a later request uses
the same request pointer but doesn't (re)set req->complete it
could result in the wrong completion function being called and
causing invalid memory access.

One way to fix this would be to explicitly set req->complete in
all cases but that might require auditing all function drivers
that have ep0 handling. Instead, note that the composite device
had already initially set cdev->req->complete and simply cache
and restore that pointer at the start of android_setup().

Change-Id: I33bcd17bd20687a349d537d1013b52a2afef6996
Signed-off-by: Jack Pham <[email protected]>
  • Loading branch information
Jack Pham authored and Badhri Jagan Sridharan committed Jan 23, 2015
1 parent b3df6b1 commit ea262b4
Showing 1 changed file with 7 additions and 0 deletions.
7 changes: 7 additions & 0 deletions drivers/usb/gadget/android.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ struct android_dev {
struct usb_composite_dev *cdev;
struct device *dev;

void (*setup_complete)(struct usb_ep *ep,
struct usb_request *req);

bool enabled;
int disable_depth;
struct mutex mutex;
Expand Down Expand Up @@ -1312,6 +1315,9 @@ static int android_bind(struct usb_composite_dev *cdev)
struct usb_gadget *gadget = cdev->gadget;
int id, ret;

/* Save the default handler */
dev->setup_complete = cdev->req->complete;

/*
* Start disconnected. Userspace will connect the gadget once
* it is done configuring the functions.
Expand Down Expand Up @@ -1378,6 +1384,7 @@ android_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *c)

req->zero = 0;
req->length = 0;
req->complete = dev->setup_complete;
gadget->ep0->driver_data = cdev;

list_for_each_entry(f, &dev->enabled_functions, enabled_list) {
Expand Down

0 comments on commit ea262b4

Please sign in to comment.