| From 069dfbfc82f0744c377029e0d9c0993c6cb1090a Mon Sep 17 00:00:00 2001 |
| From: Johan Hovold <johan@kernel.org> |
| Date: Tue, 14 Mar 2017 17:55:45 +0100 |
| Subject: [PATCH] USB: usbtmc: add missing endpoint sanity check |
| |
| commit 687e0687f71ec00e0132a21fef802dee88c2f1ad upstream. |
| |
| USBTMC devices are required to have a bulk-in and a bulk-out endpoint, |
| but the driver failed to verify this, something which could lead to the |
| endpoint addresses being taken from uninitialised memory. |
| |
| Make sure to zero all private data as part of allocation, and add the |
| missing endpoint sanity check. |
| |
| Note that this also addresses a more recently introduced issue, where |
| the interrupt-in-presence flag would also be uninitialised whenever the |
| optional interrupt-in endpoint is not present. This in turn could lead |
| to an interrupt urb being allocated, initialised and submitted based on |
| uninitialised values. |
| |
| Fixes: dbf3e7f654c0 ("Implement an ioctl to support the USMTMC-USB488 READ_STATUS_BYTE operation.") |
| Fixes: 5b775f672cc9 ("USB: add USB test and measurement class driver") |
| Cc: stable <stable@vger.kernel.org> # 2.6.28 |
| Signed-off-by: Johan Hovold <johan@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c |
| index ffe9f8875311..e228b52303cd 100644 |
| --- a/drivers/usb/class/usbtmc.c |
| +++ b/drivers/usb/class/usbtmc.c |
| @@ -1380,7 +1380,7 @@ static int usbtmc_probe(struct usb_interface *intf, |
| |
| dev_dbg(&intf->dev, "%s called\n", __func__); |
| |
| - data = kmalloc(sizeof(*data), GFP_KERNEL); |
| + data = kzalloc(sizeof(*data), GFP_KERNEL); |
| if (!data) |
| return -ENOMEM; |
| |
| @@ -1443,6 +1443,13 @@ static int usbtmc_probe(struct usb_interface *intf, |
| break; |
| } |
| } |
| + |
| + if (!data->bulk_out || !data->bulk_in) { |
| + dev_err(&intf->dev, "bulk endpoints not found\n"); |
| + retcode = -ENODEV; |
| + goto err_put; |
| + } |
| + |
| /* Find int endpoint */ |
| for (n = 0; n < iface_desc->desc.bNumEndpoints; n++) { |
| endpoint = &iface_desc->endpoint[n].desc; |
| @@ -1515,6 +1522,7 @@ error_register: |
| sysfs_remove_group(&intf->dev.kobj, &capability_attr_grp); |
| sysfs_remove_group(&intf->dev.kobj, &data_attr_grp); |
| usbtmc_free_int(data); |
| +err_put: |
| kref_put(&data->kref, usbtmc_delete); |
| return retcode; |
| } |
| -- |
| 2.12.0 |
| |