diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2016-09-14 20:20:44 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-09-15 13:29:52 -0700 |
commit | b71dbf1032f546bf3efd60fb5d9d0cefd200a508 (patch) | |
tree | 6b09fe48b1c87c94f8274be6e834dc6abada6c63 /fs | |
parent | 5297e0f0fe13305a1fc7f01986be0dccd063d57a (diff) | |
download | lwn-b71dbf1032f546bf3efd60fb5d9d0cefd200a508.tar.gz lwn-b71dbf1032f546bf3efd60fb5d9d0cefd200a508.zip |
vfs: cap dedupe request structure size at PAGE_SIZE
Kirill A Shutemov reports that the kernel doesn't try to cap dest_count
in any way, and uses the number to allocate kernel memory. This causes
high order allocation warnings in the kernel log if someone passes in a
big enough value. We should clamp the allocation at PAGE_SIZE to avoid
stressing the VM.
The two existing users of the dedupe ioctl never send more than 120
requests, so we can safely clamp dest_range at PAGE_SIZE, because with
4k pages we can handle up to 127 dedupe candidates. Given the max
extent length of 16MB, we can end up doing 2GB of IO which is plenty.
[ Note: the "offsetof()" can't overflow, because 'count' is just a
16-bit integer. That's not obvious in the limited context of the
patch, so I'm noting it here because it made me go look. - Linus ]
Reported-by: "Kirill A. Shutemov" <kirill@shutemov.name>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ioctl.c | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/fs/ioctl.c b/fs/ioctl.c index 26aba0942a98..c415668c86d4 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c @@ -582,6 +582,10 @@ static int ioctl_file_dedupe_range(struct file *file, void __user *arg) } size = offsetof(struct file_dedupe_range __user, info[count]); + if (size > PAGE_SIZE) { + ret = -ENOMEM; + goto out; + } same = memdup_user(argp, size); if (IS_ERR(same)) { |