mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-12-12 01:14:22 -05:00
109 lines
3.6 KiB
Diff
109 lines
3.6 KiB
Diff
From dc18eac80caaa12ff7072df9fe857b921e8c26c7 Mon Sep 17 00:00:00 2001
|
|
From: Linus Torvalds <torvalds@linux-foundation.org>
|
|
Date: Mon, 21 May 2012 16:06:20 -0700
|
|
Subject: [PATCH] UPSTREAM: 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.
|
|
|
|
Bug: 28939037
|
|
Reported-by: Manish Honap <manish_honap_vit@yahoo.co.in>
|
|
Cc: stable@vger.kernel.org
|
|
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
|
(cherry picked from commit a70b52ec1aaeaf60f4739edb1b422827cb6f3893)
|
|
|
|
Change-Id: I2e182e973b44ba97c45c80d52d8a0b7c32a72750
|
|
---
|
|
fs/aio.c | 30 ++++++++++++++----------------
|
|
1 file changed, 14 insertions(+), 16 deletions(-)
|
|
|
|
diff --git a/fs/aio.c b/fs/aio.c
|
|
index 67a6db3e1b6f8..e7f2fad7b4ce7 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)
|
|
if (ret < 0)
|
|
goto out;
|
|
|
|
+ ret = rw_verify_area(type, kiocb->ki_filp, &kiocb->ki_pos, ret);
|
|
+ if (ret < 0)
|
|
+ goto out;
|
|
+
|
|
kiocb->ki_nr_segs = kiocb->ki_nbytes;
|
|
kiocb->ki_cur_seg = 0;
|
|
/* ki_nbytes/left now reflect bytes instead of segs */
|
|
@@ -1467,11 +1471,17 @@ static ssize_t aio_setup_vectored_rw(int type, struct kiocb *kiocb, bool compat)
|
|
return ret;
|
|
}
|
|
|
|
-static ssize_t aio_setup_single_vector(struct kiocb *kiocb)
|
|
+static ssize_t aio_setup_single_vector(int type, struct file * file, struct kiocb *kiocb)
|
|
{
|
|
+ int bytes;
|
|
+
|
|
+ bytes = rw_verify_area(type, file, &kiocb->ki_pos, kiocb->ki_left);
|
|
+ if (bytes < 0)
|
|
+ return bytes;
|
|
+
|
|
kiocb->ki_iovec = &kiocb->ki_inline_vec;
|
|
kiocb->ki_iovec->iov_base = kiocb->ki_buf;
|
|
- kiocb->ki_iovec->iov_len = kiocb->ki_left;
|
|
+ kiocb->ki_iovec->iov_len = bytes;
|
|
kiocb->ki_nr_segs = 1;
|
|
kiocb->ki_cur_seg = 0;
|
|
return 0;
|
|
@@ -1496,10 +1506,7 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb, bool compat)
|
|
if (unlikely(!access_ok(VERIFY_WRITE, kiocb->ki_buf,
|
|
kiocb->ki_left)))
|
|
break;
|
|
- ret = security_file_permission(file, MAY_READ);
|
|
- if (unlikely(ret))
|
|
- break;
|
|
- ret = aio_setup_single_vector(kiocb);
|
|
+ ret = aio_setup_single_vector(READ, file, kiocb);
|
|
if (ret)
|
|
break;
|
|
ret = -EINVAL;
|
|
@@ -1514,10 +1521,7 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb, bool compat)
|
|
if (unlikely(!access_ok(VERIFY_READ, kiocb->ki_buf,
|
|
kiocb->ki_left)))
|
|
break;
|
|
- ret = security_file_permission(file, MAY_WRITE);
|
|
- if (unlikely(ret))
|
|
- break;
|
|
- ret = aio_setup_single_vector(kiocb);
|
|
+ ret = aio_setup_single_vector(WRITE, file, kiocb);
|
|
if (ret)
|
|
break;
|
|
ret = -EINVAL;
|
|
@@ -1528,9 +1532,6 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb, bool compat)
|
|
ret = -EBADF;
|
|
if (unlikely(!(file->f_mode & FMODE_READ)))
|
|
break;
|
|
- ret = security_file_permission(file, MAY_READ);
|
|
- if (unlikely(ret))
|
|
- break;
|
|
ret = aio_setup_vectored_rw(READ, kiocb, compat);
|
|
if (ret)
|
|
break;
|
|
@@ -1542,9 +1543,6 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb, bool compat)
|
|
ret = -EBADF;
|
|
if (unlikely(!(file->f_mode & FMODE_WRITE)))
|
|
break;
|
|
- ret = security_file_permission(file, MAY_WRITE);
|
|
- if (unlikely(ret))
|
|
- break;
|
|
ret = aio_setup_vectored_rw(WRITE, kiocb, compat);
|
|
if (ret)
|
|
break;
|