aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-21 19:06:20 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-06-01 03:12:53 -0400
commit2ec196c975ffb8076df77f6fa929448717e5141b (patch)
tree61646174152a3022e1bd3e51462085fafa6ff085 /fs
parentee9d6e9cbb6655e2d34616b3f5e6e07699f40aec (diff)
vfs: make AIO use the proper rw_verify_area() area helpers
commit a70b52ec1aaeaf60f4739edb1b422827cb6f3893 upstream. 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> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/aio.c30
1 files changed, 14 insertions, 16 deletions
diff --git a/fs/aio.c b/fs/aio.c
index b4a88ccf777..278ed7dc71b 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1395,6 +1395,10 @@ static ssize_t aio_setup_vectored_rw(int type, struct kiocb *kiocb, bool compat)
1395 if (ret < 0) 1395 if (ret < 0)
1396 goto out; 1396 goto out;
1397 1397
1398 ret = rw_verify_area(type, kiocb->ki_filp, &kiocb->ki_pos, ret);
1399 if (ret < 0)
1400 goto out;
1401
1398 kiocb->ki_nr_segs = kiocb->ki_nbytes; 1402 kiocb->ki_nr_segs = kiocb->ki_nbytes;
1399 kiocb->ki_cur_seg = 0; 1403 kiocb->ki_cur_seg = 0;
1400 /* ki_nbytes/left now reflect bytes instead of segs */ 1404 /* ki_nbytes/left now reflect bytes instead of segs */
@@ -1406,11 +1410,17 @@ out:
1406 return ret; 1410 return ret;
1407} 1411}
1408 1412
1409static ssize_t aio_setup_single_vector(struct kiocb *kiocb) 1413static ssize_t aio_setup_single_vector(int type, struct file * file, struct kiocb *kiocb)
1410{ 1414{
1415 int bytes;
1416
1417 bytes = rw_verify_area(type, file, &kiocb->ki_pos, kiocb->ki_left);
1418 if (bytes < 0)
1419 return bytes;
1420
1411 kiocb->ki_iovec = &kiocb->ki_inline_vec; 1421 kiocb->ki_iovec = &kiocb->ki_inline_vec;
1412 kiocb->ki_iovec->iov_base = kiocb->ki_buf; 1422 kiocb->ki_iovec->iov_base = kiocb->ki_buf;
1413 kiocb->ki_iovec->iov_len = kiocb->ki_left; 1423 kiocb->ki_iovec->iov_len = bytes;
1414 kiocb->ki_nr_segs = 1; 1424 kiocb->ki_nr_segs = 1;
1415 kiocb->ki_cur_seg = 0; 1425 kiocb->ki_cur_seg = 0;
1416 return 0; 1426 return 0;
@@ -1435,10 +1445,7 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb, bool compat)
1435 if (unlikely(!access_ok(VERIFY_WRITE, kiocb->ki_buf, 1445 if (unlikely(!access_ok(VERIFY_WRITE, kiocb->ki_buf,
1436 kiocb->ki_left))) 1446 kiocb->ki_left)))
1437 break; 1447 break;
1438 ret = security_file_permission(file, MAY_READ); 1448 ret = aio_setup_single_vector(READ, file, kiocb);
1439 if (unlikely(ret))
1440 break;
1441 ret = aio_setup_single_vector(kiocb);
1442 if (ret) 1449 if (ret)
1443 break; 1450 break;
1444 ret = -EINVAL; 1451 ret = -EINVAL;
@@ -1453,10 +1460,7 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb, bool compat)
1453 if (unlikely(!access_ok(VERIFY_READ, kiocb->ki_buf, 1460 if (unlikely(!access_ok(VERIFY_READ, kiocb->ki_buf,
1454 kiocb->ki_left))) 1461 kiocb->ki_left)))
1455 break; 1462 break;
1456 ret = security_file_permission(file, MAY_WRITE); 1463 ret = aio_setup_single_vector(WRITE, file, kiocb);
1457 if (unlikely(ret))
1458 break;
1459 ret = aio_setup_single_vector(kiocb);
1460 if (ret) 1464 if (ret)
1461 break; 1465 break;
1462 ret = -EINVAL; 1466 ret = -EINVAL;
@@ -1467,9 +1471,6 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb, bool compat)
1467 ret = -EBADF; 1471 ret = -EBADF;
1468 if (unlikely(!(file->f_mode & FMODE_READ))) 1472 if (unlikely(!(file->f_mode & FMODE_READ)))
1469 break; 1473 break;
1470 ret = security_file_permission(file, MAY_READ);
1471 if (unlikely(ret))
1472 break;
1473 ret = aio_setup_vectored_rw(READ, kiocb, compat); 1474 ret = aio_setup_vectored_rw(READ, kiocb, compat);
1474 if (ret) 1475 if (ret)
1475 break; 1476 break;
@@ -1481,9 +1482,6 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb, bool compat)
1481 ret = -EBADF; 1482 ret = -EBADF;
1482 if (unlikely(!(file->f_mode & FMODE_WRITE))) 1483 if (unlikely(!(file->f_mode & FMODE_WRITE)))
1483 break; 1484 break;
1484 ret = security_file_permission(file, MAY_WRITE);
1485 if (unlikely(ret))
1486 break;
1487 ret = aio_setup_vectored_rw(WRITE, kiocb, compat); 1485 ret = aio_setup_vectored_rw(WRITE, kiocb, compat);
1488 if (ret) 1486 if (ret)
1489 break; 1487 break;