aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/devio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/core/devio.c')
-rw-r--r--drivers/usb/core/devio.c169
1 files changed, 140 insertions, 29 deletions
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index e0f107948eba..ebb8a9de8b5f 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -47,6 +47,7 @@
47#include <linux/notifier.h> 47#include <linux/notifier.h>
48#include <linux/security.h> 48#include <linux/security.h>
49#include <linux/user_namespace.h> 49#include <linux/user_namespace.h>
50#include <linux/scatterlist.h>
50#include <asm/uaccess.h> 51#include <asm/uaccess.h>
51#include <asm/byteorder.h> 52#include <asm/byteorder.h>
52#include <linux/moduleparam.h> 53#include <linux/moduleparam.h>
@@ -55,6 +56,7 @@
55 56
56#define USB_MAXBUS 64 57#define USB_MAXBUS 64
57#define USB_DEVICE_MAX USB_MAXBUS * 128 58#define USB_DEVICE_MAX USB_MAXBUS * 128
59#define USB_SG_SIZE 16384 /* split-size for large txs */
58 60
59/* Mutual exclusion for removal, open, and release */ 61/* Mutual exclusion for removal, open, and release */
60DEFINE_MUTEX(usbfs_mutex); 62DEFINE_MUTEX(usbfs_mutex);
@@ -285,9 +287,16 @@ static struct async *alloc_async(unsigned int numisoframes)
285 287
286static void free_async(struct async *as) 288static void free_async(struct async *as)
287{ 289{
290 int i;
291
288 put_pid(as->pid); 292 put_pid(as->pid);
289 if (as->cred) 293 if (as->cred)
290 put_cred(as->cred); 294 put_cred(as->cred);
295 for (i = 0; i < as->urb->num_sgs; i++) {
296 if (sg_page(&as->urb->sg[i]))
297 kfree(sg_virt(&as->urb->sg[i]));
298 }
299 kfree(as->urb->sg);
291 kfree(as->urb->transfer_buffer); 300 kfree(as->urb->transfer_buffer);
292 kfree(as->urb->setup_packet); 301 kfree(as->urb->setup_packet);
293 usb_free_urb(as->urb); 302 usb_free_urb(as->urb);
@@ -388,6 +397,53 @@ static void snoop_urb(struct usb_device *udev,
388 } 397 }
389} 398}
390 399
400static void snoop_urb_data(struct urb *urb, unsigned len)
401{
402 int i, size;
403
404 if (!usbfs_snoop)
405 return;
406
407 if (urb->num_sgs == 0) {
408 print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_NONE, 32, 1,
409 urb->transfer_buffer, len, 1);
410 return;
411 }
412
413 for (i = 0; i < urb->num_sgs && len; i++) {
414 size = (len > USB_SG_SIZE) ? USB_SG_SIZE : len;
415 print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_NONE, 32, 1,
416 sg_virt(&urb->sg[i]), size, 1);
417 len -= size;
418 }
419}
420
421static int copy_urb_data_to_user(u8 __user *userbuffer, struct urb *urb)
422{
423 unsigned i, len, size;
424
425 if (urb->number_of_packets > 0) /* Isochronous */
426 len = urb->transfer_buffer_length;
427 else /* Non-Isoc */
428 len = urb->actual_length;
429
430 if (urb->num_sgs == 0) {
431 if (copy_to_user(userbuffer, urb->transfer_buffer, len))
432 return -EFAULT;
433 return 0;
434 }
435
436 for (i = 0; i < urb->num_sgs && len; i++) {
437 size = (len > USB_SG_SIZE) ? USB_SG_SIZE : len;
438 if (copy_to_user(userbuffer, sg_virt(&urb->sg[i]), size))
439 return -EFAULT;
440 userbuffer += size;
441 len -= size;
442 }
443
444 return 0;
445}
446
391#define AS_CONTINUATION 1 447#define AS_CONTINUATION 1
392#define AS_UNLINK 2 448#define AS_UNLINK 2
393 449
@@ -454,9 +510,10 @@ static void async_completed(struct urb *urb)
454 } 510 }
455 snoop(&urb->dev->dev, "urb complete\n"); 511 snoop(&urb->dev->dev, "urb complete\n");
456 snoop_urb(urb->dev, as->userurb, urb->pipe, urb->actual_length, 512 snoop_urb(urb->dev, as->userurb, urb->pipe, urb->actual_length,
457 as->status, COMPLETE, 513 as->status, COMPLETE, NULL, 0);
458 ((urb->transfer_flags & URB_DIR_MASK) == USB_DIR_OUT) ? 514 if ((urb->transfer_flags & URB_DIR_MASK) == USB_DIR_IN)
459 NULL : urb->transfer_buffer, urb->actual_length); 515 snoop_urb_data(urb, urb->actual_length);
516
460 if (as->status < 0 && as->bulk_addr && as->status != -ECONNRESET && 517 if (as->status < 0 && as->bulk_addr && as->status != -ECONNRESET &&
461 as->status != -ENOENT) 518 as->status != -ENOENT)
462 cancel_bulk_urbs(ps, as->bulk_addr); 519 cancel_bulk_urbs(ps, as->bulk_addr);
@@ -1114,8 +1171,8 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
1114 struct async *as = NULL; 1171 struct async *as = NULL;
1115 struct usb_ctrlrequest *dr = NULL; 1172 struct usb_ctrlrequest *dr = NULL;
1116 unsigned int u, totlen, isofrmlen; 1173 unsigned int u, totlen, isofrmlen;
1117 int ret, ifnum = -1; 1174 int i, ret, is_in, num_sgs = 0, ifnum = -1;
1118 int is_in; 1175 void *buf;
1119 1176
1120 if (uurb->flags & ~(USBDEVFS_URB_ISO_ASAP | 1177 if (uurb->flags & ~(USBDEVFS_URB_ISO_ASAP |
1121 USBDEVFS_URB_SHORT_NOT_OK | 1178 USBDEVFS_URB_SHORT_NOT_OK |
@@ -1199,6 +1256,9 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
1199 goto interrupt_urb; 1256 goto interrupt_urb;
1200 } 1257 }
1201 uurb->number_of_packets = 0; 1258 uurb->number_of_packets = 0;
1259 num_sgs = DIV_ROUND_UP(uurb->buffer_length, USB_SG_SIZE);
1260 if (num_sgs == 1 || num_sgs > ps->dev->bus->sg_tablesize)
1261 num_sgs = 0;
1202 break; 1262 break;
1203 1263
1204 case USBDEVFS_URB_TYPE_INTERRUPT: 1264 case USBDEVFS_URB_TYPE_INTERRUPT:
@@ -1255,26 +1315,67 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
1255 ret = -ENOMEM; 1315 ret = -ENOMEM;
1256 goto error; 1316 goto error;
1257 } 1317 }
1258 u += sizeof(struct async) + sizeof(struct urb) + uurb->buffer_length; 1318
1319 u += sizeof(struct async) + sizeof(struct urb) + uurb->buffer_length +
1320 num_sgs * sizeof(struct scatterlist);
1259 ret = usbfs_increase_memory_usage(u); 1321 ret = usbfs_increase_memory_usage(u);
1260 if (ret) 1322 if (ret)
1261 goto error; 1323 goto error;
1262 as->mem_usage = u; 1324 as->mem_usage = u;
1263 1325
1264 if (uurb->buffer_length > 0) { 1326 if (num_sgs) {
1327 as->urb->sg = kmalloc(num_sgs * sizeof(struct scatterlist),
1328 GFP_KERNEL);
1329 if (!as->urb->sg) {
1330 ret = -ENOMEM;
1331 goto error;
1332 }
1333 as->urb->num_sgs = num_sgs;
1334 sg_init_table(as->urb->sg, as->urb->num_sgs);
1335
1336 totlen = uurb->buffer_length;
1337 for (i = 0; i < as->urb->num_sgs; i++) {
1338 u = (totlen > USB_SG_SIZE) ? USB_SG_SIZE : totlen;
1339 buf = kmalloc(u, GFP_KERNEL);
1340 if (!buf) {
1341 ret = -ENOMEM;
1342 goto error;
1343 }
1344 sg_set_buf(&as->urb->sg[i], buf, u);
1345
1346 if (!is_in) {
1347 if (copy_from_user(buf, uurb->buffer, u)) {
1348 ret = -EFAULT;
1349 goto error;
1350 }
1351 }
1352 totlen -= u;
1353 }
1354 } else if (uurb->buffer_length > 0) {
1265 as->urb->transfer_buffer = kmalloc(uurb->buffer_length, 1355 as->urb->transfer_buffer = kmalloc(uurb->buffer_length,
1266 GFP_KERNEL); 1356 GFP_KERNEL);
1267 if (!as->urb->transfer_buffer) { 1357 if (!as->urb->transfer_buffer) {
1268 ret = -ENOMEM; 1358 ret = -ENOMEM;
1269 goto error; 1359 goto error;
1270 } 1360 }
1271 /* Isochronous input data may end up being discontiguous 1361
1272 * if some of the packets are short. Clear the buffer so 1362 if (!is_in) {
1273 * that the gaps don't leak kernel data to userspace. 1363 if (copy_from_user(as->urb->transfer_buffer,
1274 */ 1364 uurb->buffer,
1275 if (is_in && uurb->type == USBDEVFS_URB_TYPE_ISO) 1365 uurb->buffer_length)) {
1366 ret = -EFAULT;
1367 goto error;
1368 }
1369 } else if (uurb->type == USBDEVFS_URB_TYPE_ISO) {
1370 /*
1371 * Isochronous input data may end up being
1372 * discontiguous if some of the packets are short.
1373 * Clear the buffer so that the gaps don't leak
1374 * kernel data to userspace.
1375 */
1276 memset(as->urb->transfer_buffer, 0, 1376 memset(as->urb->transfer_buffer, 0,
1277 uurb->buffer_length); 1377 uurb->buffer_length);
1378 }
1278 } 1379 }
1279 as->urb->dev = ps->dev; 1380 as->urb->dev = ps->dev;
1280 as->urb->pipe = (uurb->type << 30) | 1381 as->urb->pipe = (uurb->type << 30) |
@@ -1328,17 +1429,12 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
1328 as->pid = get_pid(task_pid(current)); 1429 as->pid = get_pid(task_pid(current));
1329 as->cred = get_current_cred(); 1430 as->cred = get_current_cred();
1330 security_task_getsecid(current, &as->secid); 1431 security_task_getsecid(current, &as->secid);
1331 if (!is_in && uurb->buffer_length > 0) {
1332 if (copy_from_user(as->urb->transfer_buffer, uurb->buffer,
1333 uurb->buffer_length)) {
1334 ret = -EFAULT;
1335 goto error;
1336 }
1337 }
1338 snoop_urb(ps->dev, as->userurb, as->urb->pipe, 1432 snoop_urb(ps->dev, as->userurb, as->urb->pipe,
1339 as->urb->transfer_buffer_length, 0, SUBMIT, 1433 as->urb->transfer_buffer_length, 0, SUBMIT,
1340 is_in ? NULL : as->urb->transfer_buffer, 1434 NULL, 0);
1341 uurb->buffer_length); 1435 if (!is_in)
1436 snoop_urb_data(as->urb, as->urb->transfer_buffer_length);
1437
1342 async_newpending(as); 1438 async_newpending(as);
1343 1439
1344 if (usb_endpoint_xfer_bulk(&ep->desc)) { 1440 if (usb_endpoint_xfer_bulk(&ep->desc)) {
@@ -1433,11 +1529,7 @@ static int processcompl(struct async *as, void __user * __user *arg)
1433 unsigned int i; 1529 unsigned int i;
1434 1530
1435 if (as->userbuffer && urb->actual_length) { 1531 if (as->userbuffer && urb->actual_length) {
1436 if (urb->number_of_packets > 0) /* Isochronous */ 1532 if (copy_urb_data_to_user(as->userbuffer, urb))
1437 i = urb->transfer_buffer_length;
1438 else /* Non-Isoc */
1439 i = urb->actual_length;
1440 if (copy_to_user(as->userbuffer, urb->transfer_buffer, i))
1441 goto err_out; 1533 goto err_out;
1442 } 1534 }
1443 if (put_user(as->status, &userurb->status)) 1535 if (put_user(as->status, &userurb->status))
@@ -1604,10 +1696,10 @@ static int processcompl_compat(struct async *as, void __user * __user *arg)
1604 void __user *addr = as->userurb; 1696 void __user *addr = as->userurb;
1605 unsigned int i; 1697 unsigned int i;
1606 1698
1607 if (as->userbuffer && urb->actual_length) 1699 if (as->userbuffer && urb->actual_length) {
1608 if (copy_to_user(as->userbuffer, urb->transfer_buffer, 1700 if (copy_urb_data_to_user(as->userbuffer, urb))
1609 urb->actual_length))
1610 return -EFAULT; 1701 return -EFAULT;
1702 }
1611 if (put_user(as->status, &userurb->status)) 1703 if (put_user(as->status, &userurb->status))
1612 return -EFAULT; 1704 return -EFAULT;
1613 if (put_user(urb->actual_length, &userurb->actual_length)) 1705 if (put_user(urb->actual_length, &userurb->actual_length))
@@ -1820,6 +1912,22 @@ static int proc_release_port(struct dev_state *ps, void __user *arg)
1820 return usb_hub_release_port(ps->dev, portnum, ps); 1912 return usb_hub_release_port(ps->dev, portnum, ps);
1821} 1913}
1822 1914
1915static int proc_get_capabilities(struct dev_state *ps, void __user *arg)
1916{
1917 __u32 caps;
1918
1919 caps = USBDEVFS_CAP_ZERO_PACKET | USBDEVFS_CAP_NO_PACKET_SIZE_LIM;
1920 if (!ps->dev->bus->no_stop_on_short)
1921 caps |= USBDEVFS_CAP_BULK_CONTINUATION;
1922 if (ps->dev->bus->sg_tablesize)
1923 caps |= USBDEVFS_CAP_BULK_SCATTER_GATHER;
1924
1925 if (put_user(caps, (__u32 __user *)arg))
1926 return -EFAULT;
1927
1928 return 0;
1929}
1930
1823/* 1931/*
1824 * NOTE: All requests here that have interface numbers as parameters 1932 * NOTE: All requests here that have interface numbers as parameters
1825 * are assuming that somehow the configuration has been prevented from 1933 * are assuming that somehow the configuration has been prevented from
@@ -1990,6 +2098,9 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd,
1990 snoop(&dev->dev, "%s: RELEASE_PORT\n", __func__); 2098 snoop(&dev->dev, "%s: RELEASE_PORT\n", __func__);
1991 ret = proc_release_port(ps, p); 2099 ret = proc_release_port(ps, p);
1992 break; 2100 break;
2101 case USBDEVFS_GET_CAPABILITIES:
2102 ret = proc_get_capabilities(ps, p);
2103 break;
1993 } 2104 }
1994 usb_unlock_device(dev); 2105 usb_unlock_device(dev);
1995 if (ret >= 0) 2106 if (ret >= 0)