diff options
Diffstat (limited to 'drivers/usb/gadget/legacy/inode.c')
| -rw-r--r-- | drivers/usb/gadget/legacy/inode.c | 16 | 
1 files changed, 15 insertions, 1 deletions
| diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index 78be94750232..3b58f4fc0a80 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -110,6 +110,8 @@ enum ep0_state {  /* enough for the whole queue: most events invalidate others */  #define	N_EVENT			5 +#define RBUF_SIZE		256 +  struct dev_data {  	spinlock_t			lock;  	refcount_t			count; @@ -144,7 +146,7 @@ struct dev_data {  	struct dentry			*dentry;  	/* except this scratch i/o buffer for ep0 */ -	u8				rbuf [256]; +	u8				rbuf[RBUF_SIZE];  };  static inline void get_dev (struct dev_data *data) @@ -1331,6 +1333,18 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)  	u16				w_value = le16_to_cpu(ctrl->wValue);  	u16				w_length = le16_to_cpu(ctrl->wLength); +	if (w_length > RBUF_SIZE) { +		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(RBUF_SIZE); +			w_length = RBUF_SIZE; +		} else { +			return value; +		} +	} +  	spin_lock (&dev->lock);  	dev->setup_abort = 0;  	if (dev->state == STATE_DEV_UNCONNECTED) { |