Commit ada80212 authored by Linus Torvalds's avatar Linus Torvalds

Make generic rw_verify_area check against file offset overflows.

Not that low-level code really tends to care, but since loff_t is
a signed 64-bit entity and size_t is unsigned (and potentially
64-bit), mixing the two isn't very well-defined.. 
parent fd770e66
...@@ -186,14 +186,21 @@ asmlinkage long sys_llseek(unsigned int fd, unsigned long offset_high, ...@@ -186,14 +186,21 @@ asmlinkage long sys_llseek(unsigned int fd, unsigned long offset_high,
int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count) int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count)
{ {
struct inode *inode; struct inode *inode;
loff_t pos;
if (count > file->f_maxcount) if (unlikely(count > file->f_maxcount))
return -EINVAL; goto Einval;
pos = *ppos;
if (unlikely((pos < 0) || (loff_t) (pos + count) < 0))
goto Einval;
inode = file->f_dentry->d_inode; inode = file->f_dentry->d_inode;
if (inode->i_flock && MANDATORY_LOCK(inode)) if (inode->i_flock && MANDATORY_LOCK(inode))
return locks_mandatory_area(read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE, inode, file, *ppos, count); return locks_mandatory_area(read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE, inode, file, pos, count);
return 0; return 0;
Einval:
return -EINVAL;
} }
ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos) ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
......
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