Commit a70b52ec1aaeaf60f4739edb1b422827cb6f3893

Authored by Linus Torvalds
1 parent ff8ce5f67d

vfs: make AIO use the proper rw_verify_area() area helpers

We had for some reason overlooked the AIO interface, and it didn't use
the proper rw_verify_area() helper function that checks (for example)
mandatory locking on the file, and that the size of the access doesn't
cause us to overflow the provided offset limits etc.

Instead, AIO did just the security_file_permission() thing (that
rw_verify_area() also does) directly.

This fixes it to do all the proper helper functions, which not only
means that now mandatory file locking works with AIO too, we can
actually remove lines of code.

Reported-by: Manish Honap <manish_honap_vit@yahoo.co.in>
Cc: stable@vger.kernel.org
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 1 changed file with 14 additions and 16 deletions Side-by-side Diff

... ... @@ -1456,6 +1456,10 @@
1456 1456 if (ret < 0)
1457 1457 goto out;
1458 1458  
  1459 + ret = rw_verify_area(type, kiocb->ki_filp, &kiocb->ki_pos, ret);
  1460 + if (ret < 0)
  1461 + goto out;
  1462 +
1459 1463 kiocb->ki_nr_segs = kiocb->ki_nbytes;
1460 1464 kiocb->ki_cur_seg = 0;
1461 1465 /* ki_nbytes/left now reflect bytes instead of segs */
1462 1466  
1463 1467  
... ... @@ -1467,11 +1471,17 @@
1467 1471 return ret;
1468 1472 }
1469 1473  
1470   -static ssize_t aio_setup_single_vector(struct kiocb *kiocb)
  1474 +static ssize_t aio_setup_single_vector(int type, struct file * file, struct kiocb *kiocb)
1471 1475 {
  1476 + int bytes;
  1477 +
  1478 + bytes = rw_verify_area(type, file, &kiocb->ki_pos, kiocb->ki_left);
  1479 + if (bytes < 0)
  1480 + return bytes;
  1481 +
1472 1482 kiocb->ki_iovec = &kiocb->ki_inline_vec;
1473 1483 kiocb->ki_iovec->iov_base = kiocb->ki_buf;
1474   - kiocb->ki_iovec->iov_len = kiocb->ki_left;
  1484 + kiocb->ki_iovec->iov_len = bytes;
1475 1485 kiocb->ki_nr_segs = 1;
1476 1486 kiocb->ki_cur_seg = 0;
1477 1487 return 0;
... ... @@ -1496,10 +1506,7 @@
1496 1506 if (unlikely(!access_ok(VERIFY_WRITE, kiocb->ki_buf,
1497 1507 kiocb->ki_left)))
1498 1508 break;
1499   - ret = security_file_permission(file, MAY_READ);
1500   - if (unlikely(ret))
1501   - break;
1502   - ret = aio_setup_single_vector(kiocb);
  1509 + ret = aio_setup_single_vector(READ, file, kiocb);
1503 1510 if (ret)
1504 1511 break;
1505 1512 ret = -EINVAL;
... ... @@ -1514,10 +1521,7 @@
1514 1521 if (unlikely(!access_ok(VERIFY_READ, kiocb->ki_buf,
1515 1522 kiocb->ki_left)))
1516 1523 break;
1517   - ret = security_file_permission(file, MAY_WRITE);
1518   - if (unlikely(ret))
1519   - break;
1520   - ret = aio_setup_single_vector(kiocb);
  1524 + ret = aio_setup_single_vector(WRITE, file, kiocb);
1521 1525 if (ret)
1522 1526 break;
1523 1527 ret = -EINVAL;
... ... @@ -1528,9 +1532,6 @@
1528 1532 ret = -EBADF;
1529 1533 if (unlikely(!(file->f_mode & FMODE_READ)))
1530 1534 break;
1531   - ret = security_file_permission(file, MAY_READ);
1532   - if (unlikely(ret))
1533   - break;
1534 1535 ret = aio_setup_vectored_rw(READ, kiocb, compat);
1535 1536 if (ret)
1536 1537 break;
... ... @@ -1541,9 +1542,6 @@
1541 1542 case IOCB_CMD_PWRITEV:
1542 1543 ret = -EBADF;
1543 1544 if (unlikely(!(file->f_mode & FMODE_WRITE)))
1544   - break;
1545   - ret = security_file_permission(file, MAY_WRITE);
1546   - if (unlikely(ret))
1547 1545 break;
1548 1546 ret = aio_setup_vectored_rw(WRITE, kiocb, compat);
1549 1547 if (ret)