aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-21 19:06:20 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-21 19:06:20 -0400
commita70b52ec1aaeaf60f4739edb1b422827cb6f3893 (patch)
treeb85acd421b97f018400bc55cb8eb14b4468c3b73
parentff8ce5f67ddca709fe59e6173f89260f0fdc2b22 (diff)
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>
-rw-r--r--fs/aio.c30
1 files changed, 14 insertions, 16 deletions
diff --git a/fs/aio.c b/fs/aio.c
index 67a6db3e1b6f..e7f2fad7b4ce 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1456,6 +1456,10 @@ static ssize_t aio_setup_vectored_rw(int type, struct kiocb *kiocb, bool compat)
1456 if (ret < 0) 1456 if (ret < 0)
1457 goto out; 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 kiocb->ki_nr_segs = kiocb->ki_nbytes; 1463 kiocb->ki_nr_segs = kiocb->ki_nbytes;
1460 kiocb->ki_cur_seg = 0; 1464 kiocb->ki_cur_seg = 0;
1461 /* ki_nbytes/left now reflect bytes instead of segs */ 1465 /* ki_nbytes/left now reflect bytes instead of segs */
@@ -1467,11 +1471,17 @@ out:
1467 return ret; 1471 return ret;
1468} 1472}
1469 1473
1470static ssize_t aio_setup_single_vector(struct kiocb *kiocb) 1474static 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 kiocb->ki_iovec = &kiocb->ki_inline_vec; 1482 kiocb->ki_iovec = &kiocb->ki_inline_vec;
1473 kiocb->ki_iovec->iov_base = kiocb->ki_buf; 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 kiocb->ki_nr_segs = 1; 1485 kiocb->ki_nr_segs = 1;
1476 kiocb->ki_cur_seg = 0; 1486 kiocb->ki_cur_seg = 0;
1477 return 0; 1487 return 0;
@@ -1496,10 +1506,7 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb, bool compat)
1496 if (unlikely(!access_ok(VERIFY_WRITE, kiocb->ki_buf, 1506 if (unlikely(!access_ok(VERIFY_WRITE, kiocb->ki_buf,
1497 kiocb->ki_left))) 1507 kiocb->ki_left)))
1498 break; 1508 break;
1499 ret = security_file_permission(file, MAY_READ); 1509 ret = aio_setup_single_vector(READ, file, kiocb);
1500 if (unlikely(ret))
1501 break;
1502 ret = aio_setup_single_vector(kiocb);
1503 if (ret) 1510 if (ret)
1504 break; 1511 break;
1505 ret = -EINVAL; 1512 ret = -EINVAL;
@@ -1514,10 +1521,7 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb, bool compat)
1514 if (unlikely(!access_ok(VERIFY_READ, kiocb->ki_buf, 1521 if (unlikely(!access_ok(VERIFY_READ, kiocb->ki_buf,
1515 kiocb->ki_left))) 1522 kiocb->ki_left)))
1516 break; 1523 break;
1517 ret = security_file_permission(file, MAY_WRITE); 1524 ret = aio_setup_single_vector(WRITE, file, kiocb);
1518 if (unlikely(ret))
1519 break;
1520 ret = aio_setup_single_vector(kiocb);
1521 if (ret) 1525 if (ret)
1522 break; 1526 break;
1523 ret = -EINVAL; 1527 ret = -EINVAL;
@@ -1528,9 +1532,6 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb, bool compat)
1528 ret = -EBADF; 1532 ret = -EBADF;
1529 if (unlikely(!(file->f_mode & FMODE_READ))) 1533 if (unlikely(!(file->f_mode & FMODE_READ)))
1530 break; 1534 break;
1531 ret = security_file_permission(file, MAY_READ);
1532 if (unlikely(ret))
1533 break;
1534 ret = aio_setup_vectored_rw(READ, kiocb, compat); 1535 ret = aio_setup_vectored_rw(READ, kiocb, compat);
1535 if (ret) 1536 if (ret)
1536 break; 1537 break;
@@ -1542,9 +1543,6 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb, bool compat)
1542 ret = -EBADF; 1543 ret = -EBADF;
1543 if (unlikely(!(file->f_mode & FMODE_WRITE))) 1544 if (unlikely(!(file->f_mode & FMODE_WRITE)))
1544 break; 1545 break;
1545 ret = security_file_permission(file, MAY_WRITE);
1546 if (unlikely(ret))
1547 break;
1548 ret = aio_setup_vectored_rw(WRITE, kiocb, compat); 1546 ret = aio_setup_vectored_rw(WRITE, kiocb, compat);
1549 if (ret) 1547 if (ret)
1550 break; 1548 break;