diff options
| -rw-r--r-- | drivers/usb/core/devio.c | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index ca948bbc388f..a678186f218f 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
| @@ -1334,14 +1334,11 @@ static int processcompl(struct async *as, void __user * __user *arg) | |||
| 1334 | } | 1334 | } |
| 1335 | } | 1335 | } |
| 1336 | 1336 | ||
| 1337 | free_async(as); | ||
| 1338 | |||
| 1339 | if (put_user(addr, (void __user * __user *)arg)) | 1337 | if (put_user(addr, (void __user * __user *)arg)) |
| 1340 | return -EFAULT; | 1338 | return -EFAULT; |
| 1341 | return 0; | 1339 | return 0; |
| 1342 | 1340 | ||
| 1343 | err_out: | 1341 | err_out: |
| 1344 | free_async(as); | ||
| 1345 | return -EFAULT; | 1342 | return -EFAULT; |
| 1346 | } | 1343 | } |
| 1347 | 1344 | ||
| @@ -1371,8 +1368,11 @@ static struct async *reap_as(struct dev_state *ps) | |||
| 1371 | static int proc_reapurb(struct dev_state *ps, void __user *arg) | 1368 | static int proc_reapurb(struct dev_state *ps, void __user *arg) |
| 1372 | { | 1369 | { |
| 1373 | struct async *as = reap_as(ps); | 1370 | struct async *as = reap_as(ps); |
| 1374 | if (as) | 1371 | if (as) { |
| 1375 | return processcompl(as, (void __user * __user *)arg); | 1372 | int retval = processcompl(as, (void __user * __user *)arg); |
| 1373 | free_async(as); | ||
| 1374 | return retval; | ||
| 1375 | } | ||
| 1376 | if (signal_pending(current)) | 1376 | if (signal_pending(current)) |
| 1377 | return -EINTR; | 1377 | return -EINTR; |
| 1378 | return -EIO; | 1378 | return -EIO; |
| @@ -1380,11 +1380,16 @@ static int proc_reapurb(struct dev_state *ps, void __user *arg) | |||
| 1380 | 1380 | ||
| 1381 | static int proc_reapurbnonblock(struct dev_state *ps, void __user *arg) | 1381 | static int proc_reapurbnonblock(struct dev_state *ps, void __user *arg) |
| 1382 | { | 1382 | { |
| 1383 | int retval; | ||
| 1383 | struct async *as; | 1384 | struct async *as; |
| 1384 | 1385 | ||
| 1385 | if (!(as = async_getcompleted(ps))) | 1386 | as = async_getcompleted(ps); |
| 1386 | return -EAGAIN; | 1387 | retval = -EAGAIN; |
| 1387 | return processcompl(as, (void __user * __user *)arg); | 1388 | if (as) { |
| 1389 | retval = processcompl(as, (void __user * __user *)arg); | ||
| 1390 | free_async(as); | ||
| 1391 | } | ||
| 1392 | return retval; | ||
| 1388 | } | 1393 | } |
| 1389 | 1394 | ||
| 1390 | #ifdef CONFIG_COMPAT | 1395 | #ifdef CONFIG_COMPAT |
| @@ -1497,7 +1502,6 @@ static int processcompl_compat(struct async *as, void __user * __user *arg) | |||
| 1497 | } | 1502 | } |
| 1498 | } | 1503 | } |
| 1499 | 1504 | ||
| 1500 | free_async(as); | ||
| 1501 | if (put_user(ptr_to_compat(addr), (u32 __user *)arg)) | 1505 | if (put_user(ptr_to_compat(addr), (u32 __user *)arg)) |
| 1502 | return -EFAULT; | 1506 | return -EFAULT; |
| 1503 | return 0; | 1507 | return 0; |
| @@ -1506,8 +1510,11 @@ static int processcompl_compat(struct async *as, void __user * __user *arg) | |||
| 1506 | static int proc_reapurb_compat(struct dev_state *ps, void __user *arg) | 1510 | static int proc_reapurb_compat(struct dev_state *ps, void __user *arg) |
| 1507 | { | 1511 | { |
| 1508 | struct async *as = reap_as(ps); | 1512 | struct async *as = reap_as(ps); |
| 1509 | if (as) | 1513 | if (as) { |
| 1510 | return processcompl_compat(as, (void __user * __user *)arg); | 1514 | int retval = processcompl_compat(as, (void __user * __user *)arg); |
| 1515 | free_async(as); | ||
| 1516 | return retval; | ||
| 1517 | } | ||
| 1511 | if (signal_pending(current)) | 1518 | if (signal_pending(current)) |
| 1512 | return -EINTR; | 1519 | return -EINTR; |
| 1513 | return -EIO; | 1520 | return -EIO; |
| @@ -1515,11 +1522,16 @@ static int proc_reapurb_compat(struct dev_state *ps, void __user *arg) | |||
| 1515 | 1522 | ||
| 1516 | static int proc_reapurbnonblock_compat(struct dev_state *ps, void __user *arg) | 1523 | static int proc_reapurbnonblock_compat(struct dev_state *ps, void __user *arg) |
| 1517 | { | 1524 | { |
| 1525 | int retval; | ||
| 1518 | struct async *as; | 1526 | struct async *as; |
| 1519 | 1527 | ||
| 1520 | if (!(as = async_getcompleted(ps))) | 1528 | retval = -EAGAIN; |
| 1521 | return -EAGAIN; | 1529 | as = async_getcompleted(ps); |
| 1522 | return processcompl_compat(as, (void __user * __user *)arg); | 1530 | if (as) { |
| 1531 | retval = processcompl_compat(as, (void __user * __user *)arg); | ||
| 1532 | free_async(as); | ||
| 1533 | } | ||
| 1534 | return retval; | ||
| 1523 | } | 1535 | } |
| 1524 | 1536 | ||
| 1525 | 1537 | ||
