Commit 12cd5433 authored by Benjamin LaHaise's avatar Benjamin LaHaise

Add LFS style EOVERFLOW checks to sendfile*

parent 87aad03b
...@@ -1715,7 +1715,7 @@ static int file_send_actor(read_descriptor_t * desc, struct page *page, unsigned ...@@ -1715,7 +1715,7 @@ static int file_send_actor(read_descriptor_t * desc, struct page *page, unsigned
return written; return written;
} }
static ssize_t common_sendfile(int out_fd, int in_fd, loff_t *offset, size_t count) static ssize_t common_sendfile(int out_fd, int in_fd, loff_t *offset, size_t count, loff_t max)
{ {
ssize_t retval; ssize_t retval;
struct file * in_file, * out_file; struct file * in_file, * out_file;
...@@ -1760,10 +1760,22 @@ static ssize_t common_sendfile(int out_fd, int in_fd, loff_t *offset, size_t cou ...@@ -1760,10 +1760,22 @@ static ssize_t common_sendfile(int out_fd, int in_fd, loff_t *offset, size_t cou
retval = 0; retval = 0;
if (count) { if (count) {
read_descriptor_t desc; read_descriptor_t desc;
loff_t pos;
if (!offset) if (!offset)
offset = &in_file->f_pos; offset = &in_file->f_pos;
pos = *offset;
retval = -EINVAL;
if (unlikely(pos < 0))
goto fput_out;
if (unlikely(pos + count > max)) {
retval = -EOVERFLOW;
if (pos >= max)
goto fput_out;
count = max - pos;
}
desc.written = 0; desc.written = 0;
desc.count = count; desc.count = count;
desc.buf = (char *) out_file; desc.buf = (char *) out_file;
...@@ -1773,6 +1785,9 @@ static ssize_t common_sendfile(int out_fd, int in_fd, loff_t *offset, size_t cou ...@@ -1773,6 +1785,9 @@ static ssize_t common_sendfile(int out_fd, int in_fd, loff_t *offset, size_t cou
retval = desc.written; retval = desc.written;
if (!retval) if (!retval)
retval = desc.error; retval = desc.error;
pos = *offset;
if (pos > max)
retval = -EOVERFLOW;
} }
fput_out: fput_out:
...@@ -1794,9 +1809,9 @@ asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t cou ...@@ -1794,9 +1809,9 @@ asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t cou
pos = off; pos = off;
ppos = &pos; ppos = &pos;
} }
ret = common_sendfile(out_fd, in_fd, ppos, count); ret = common_sendfile(out_fd, in_fd, ppos, count, MAX_NON_LFS);
if (offset) if (offset && put_user(pos, offset))
put_user((off_t)pos, offset); ret = -EFAULT;
return ret; return ret;
} }
...@@ -1809,9 +1824,9 @@ asmlinkage ssize_t sys_sendfile64(int out_fd, int in_fd, loff_t *offset, size_t ...@@ -1809,9 +1824,9 @@ asmlinkage ssize_t sys_sendfile64(int out_fd, int in_fd, loff_t *offset, size_t
return -EFAULT; return -EFAULT;
ppos = &pos; ppos = &pos;
} }
ret = common_sendfile(out_fd, in_fd, ppos, count); ret = common_sendfile(out_fd, in_fd, ppos, count, MAX_LFS_FILESIZE);
if (offset) if (offset && put_user(pos, offset))
put_user(pos, offset); ret = -EFAULT;
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment