aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2017-09-21 13:23:58 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-09-22 12:29:00 -0400
commit520b72fc64debf8a86c3853b8e486aa5982188f0 (patch)
tree5f6e13888a2b0ca298bf94c30d66cc994624e2ac
parent6e76c01e71551cb221c1f3deacb9dcd9a7346784 (diff)
USB: gadgetfs: Fix crash caused by inadequate synchronization
The gadgetfs driver (drivers/usb/gadget/legacy/inode.c) was written before the UDC and composite frameworks were adopted; it is a legacy driver. As such, it expects that once bound to a UDC controller, it will not be unbound until it unregisters itself. However, the UDC framework does unbind function drivers while they are still registered. When this happens, it can cause the gadgetfs driver to misbehave or crash. For example, userspace can cause a crash by opening the device file and doing an ioctl call before setting up a configuration (found by Andrey Konovalov using the syzkaller fuzzer). This patch adds checks and synchronization to prevent these bad behaviors. It adds a udc_usage counter that the driver increments at times when it is using a gadget interface without holding the private spinlock. The unbind routine waits for this counter to go to 0 before returning, thereby ensuring that the UDC is no longer in use. The patch also adds a check in the dev_ioctl() routine to make sure the driver is bound to a UDC before dereferencing the gadget pointer, and it makes destroy_ep_files() synchronize with the endpoint I/O routines, to prevent the user from accessing an endpoint data structure after it has been removed. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Reported-by: Andrey Konovalov <andreyknvl@google.com> Tested-by: Andrey Konovalov <andreyknvl@google.com> CC: <stable@vger.kernel.org> Acked-by: Felipe Balbi <felipe.balbi@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/gadget/legacy/inode.c41
1 files changed, 36 insertions, 5 deletions
diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c
index 956b3dc7c3a4..5c28bee327e1 100644
--- a/drivers/usb/gadget/legacy/inode.c
+++ b/drivers/usb/gadget/legacy/inode.c
@@ -28,7 +28,7 @@
28#include <linux/aio.h> 28#include <linux/aio.h>
29#include <linux/uio.h> 29#include <linux/uio.h>
30#include <linux/refcount.h> 30#include <linux/refcount.h>
31 31#include <linux/delay.h>
32#include <linux/device.h> 32#include <linux/device.h>
33#include <linux/moduleparam.h> 33#include <linux/moduleparam.h>
34 34
@@ -116,6 +116,7 @@ enum ep0_state {
116struct dev_data { 116struct dev_data {
117 spinlock_t lock; 117 spinlock_t lock;
118 refcount_t count; 118 refcount_t count;
119 int udc_usage;
119 enum ep0_state state; /* P: lock */ 120 enum ep0_state state; /* P: lock */
120 struct usb_gadgetfs_event event [N_EVENT]; 121 struct usb_gadgetfs_event event [N_EVENT];
121 unsigned ev_next; 122 unsigned ev_next;
@@ -513,9 +514,9 @@ static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req)
513 INIT_WORK(&priv->work, ep_user_copy_worker); 514 INIT_WORK(&priv->work, ep_user_copy_worker);
514 schedule_work(&priv->work); 515 schedule_work(&priv->work);
515 } 516 }
516 spin_unlock(&epdata->dev->lock);
517 517
518 usb_ep_free_request(ep, req); 518 usb_ep_free_request(ep, req);
519 spin_unlock(&epdata->dev->lock);
519 put_ep(epdata); 520 put_ep(epdata);
520} 521}
521 522
@@ -939,9 +940,11 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr)
939 struct usb_request *req = dev->req; 940 struct usb_request *req = dev->req;
940 941
941 if ((retval = setup_req (ep, req, 0)) == 0) { 942 if ((retval = setup_req (ep, req, 0)) == 0) {
943 ++dev->udc_usage;
942 spin_unlock_irq (&dev->lock); 944 spin_unlock_irq (&dev->lock);
943 retval = usb_ep_queue (ep, req, GFP_KERNEL); 945 retval = usb_ep_queue (ep, req, GFP_KERNEL);
944 spin_lock_irq (&dev->lock); 946 spin_lock_irq (&dev->lock);
947 --dev->udc_usage;
945 } 948 }
946 dev->state = STATE_DEV_CONNECTED; 949 dev->state = STATE_DEV_CONNECTED;
947 950
@@ -1134,6 +1137,7 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
1134 retval = setup_req (dev->gadget->ep0, dev->req, len); 1137 retval = setup_req (dev->gadget->ep0, dev->req, len);
1135 if (retval == 0) { 1138 if (retval == 0) {
1136 dev->state = STATE_DEV_CONNECTED; 1139 dev->state = STATE_DEV_CONNECTED;
1140 ++dev->udc_usage;
1137 spin_unlock_irq (&dev->lock); 1141 spin_unlock_irq (&dev->lock);
1138 if (copy_from_user (dev->req->buf, buf, len)) 1142 if (copy_from_user (dev->req->buf, buf, len))
1139 retval = -EFAULT; 1143 retval = -EFAULT;
@@ -1145,6 +1149,7 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
1145 GFP_KERNEL); 1149 GFP_KERNEL);
1146 } 1150 }
1147 spin_lock_irq(&dev->lock); 1151 spin_lock_irq(&dev->lock);
1152 --dev->udc_usage;
1148 if (retval < 0) { 1153 if (retval < 0) {
1149 clean_req (dev->gadget->ep0, dev->req); 1154 clean_req (dev->gadget->ep0, dev->req);
1150 } else 1155 } else
@@ -1246,9 +1251,21 @@ static long dev_ioctl (struct file *fd, unsigned code, unsigned long value)
1246 struct usb_gadget *gadget = dev->gadget; 1251 struct usb_gadget *gadget = dev->gadget;
1247 long ret = -ENOTTY; 1252 long ret = -ENOTTY;
1248 1253
1249 if (gadget->ops->ioctl) 1254 spin_lock_irq(&dev->lock);
1255 if (dev->state == STATE_DEV_OPENED ||
1256 dev->state == STATE_DEV_UNBOUND) {
1257 /* Not bound to a UDC */
1258 } else if (gadget->ops->ioctl) {
1259 ++dev->udc_usage;
1260 spin_unlock_irq(&dev->lock);
1261
1250 ret = gadget->ops->ioctl (gadget, code, value); 1262 ret = gadget->ops->ioctl (gadget, code, value);
1251 1263
1264 spin_lock_irq(&dev->lock);
1265 --dev->udc_usage;
1266 }
1267 spin_unlock_irq(&dev->lock);
1268
1252 return ret; 1269 return ret;
1253} 1270}
1254 1271
@@ -1466,10 +1483,12 @@ delegate:
1466 if (value < 0) 1483 if (value < 0)
1467 break; 1484 break;
1468 1485
1486 ++dev->udc_usage;
1469 spin_unlock (&dev->lock); 1487 spin_unlock (&dev->lock);
1470 value = usb_ep_queue (gadget->ep0, dev->req, 1488 value = usb_ep_queue (gadget->ep0, dev->req,
1471 GFP_KERNEL); 1489 GFP_KERNEL);
1472 spin_lock (&dev->lock); 1490 spin_lock (&dev->lock);
1491 --dev->udc_usage;
1473 if (value < 0) { 1492 if (value < 0) {
1474 clean_req (gadget->ep0, dev->req); 1493 clean_req (gadget->ep0, dev->req);
1475 break; 1494 break;
@@ -1493,8 +1512,12 @@ delegate:
1493 req->length = value; 1512 req->length = value;
1494 req->zero = value < w_length; 1513 req->zero = value < w_length;
1495 1514
1515 ++dev->udc_usage;
1496 spin_unlock (&dev->lock); 1516 spin_unlock (&dev->lock);
1497 value = usb_ep_queue (gadget->ep0, req, GFP_KERNEL); 1517 value = usb_ep_queue (gadget->ep0, req, GFP_KERNEL);
1518 spin_lock(&dev->lock);
1519 --dev->udc_usage;
1520 spin_unlock(&dev->lock);
1498 if (value < 0) { 1521 if (value < 0) {
1499 DBG (dev, "ep_queue --> %d\n", value); 1522 DBG (dev, "ep_queue --> %d\n", value);
1500 req->status = 0; 1523 req->status = 0;
@@ -1521,21 +1544,24 @@ static void destroy_ep_files (struct dev_data *dev)
1521 /* break link to FS */ 1544 /* break link to FS */
1522 ep = list_first_entry (&dev->epfiles, struct ep_data, epfiles); 1545 ep = list_first_entry (&dev->epfiles, struct ep_data, epfiles);
1523 list_del_init (&ep->epfiles); 1546 list_del_init (&ep->epfiles);
1547 spin_unlock_irq (&dev->lock);
1548
1524 dentry = ep->dentry; 1549 dentry = ep->dentry;
1525 ep->dentry = NULL; 1550 ep->dentry = NULL;
1526 parent = d_inode(dentry->d_parent); 1551 parent = d_inode(dentry->d_parent);
1527 1552
1528 /* break link to controller */ 1553 /* break link to controller */
1554 mutex_lock(&ep->lock);
1529 if (ep->state == STATE_EP_ENABLED) 1555 if (ep->state == STATE_EP_ENABLED)
1530 (void) usb_ep_disable (ep->ep); 1556 (void) usb_ep_disable (ep->ep);
1531 ep->state = STATE_EP_UNBOUND; 1557 ep->state = STATE_EP_UNBOUND;
1532 usb_ep_free_request (ep->ep, ep->req); 1558 usb_ep_free_request (ep->ep, ep->req);
1533 ep->ep = NULL; 1559 ep->ep = NULL;
1560 mutex_unlock(&ep->lock);
1561
1534 wake_up (&ep->wait); 1562 wake_up (&ep->wait);
1535 put_ep (ep); 1563 put_ep (ep);
1536 1564
1537 spin_unlock_irq (&dev->lock);
1538
1539 /* break link to dcache */ 1565 /* break link to dcache */
1540 inode_lock(parent); 1566 inode_lock(parent);
1541 d_delete (dentry); 1567 d_delete (dentry);
@@ -1606,6 +1632,11 @@ gadgetfs_unbind (struct usb_gadget *gadget)
1606 1632
1607 spin_lock_irq (&dev->lock); 1633 spin_lock_irq (&dev->lock);
1608 dev->state = STATE_DEV_UNBOUND; 1634 dev->state = STATE_DEV_UNBOUND;
1635 while (dev->udc_usage > 0) {
1636 spin_unlock_irq(&dev->lock);
1637 usleep_range(1000, 2000);
1638 spin_lock_irq(&dev->lock);
1639 }
1609 spin_unlock_irq (&dev->lock); 1640 spin_unlock_irq (&dev->lock);
1610 1641
1611 destroy_ep_files (dev); 1642 destroy_ep_files (dev);