summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2018-09-07 21:16:24 +0200
committerMimi Zohar <zohar@linux.ibm.com>2018-10-10 18:56:14 +0200
commit691115c3513ec83edf68ba6575ae85630bc94b8b (patch)
tree8e77e6e14650f10a67a314380362f9430254e151
parentsecurity: fix LSM description location (diff)
downloadlinux-691115c3513ec83edf68ba6575ae85630bc94b8b.tar.xz
linux-691115c3513ec83edf68ba6575ae85630bc94b8b.zip
vfs: require i_size <= SIZE_MAX in kernel_read_file()
On 32-bit systems, the buffer allocated by kernel_read_file() is too small if the file size is > SIZE_MAX, due to truncation to size_t. Fortunately, since the 'count' argument to kernel_read() is also truncated to size_t, only the allocated space is filled; then, -EIO is returned since 'pos != i_size' after the read loop. But this is not obvious and seems incidental. We should be more explicit about this case. So, fail early if i_size > SIZE_MAX. Signed-off-by: Eric Biggers <ebiggers@google.com> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
-rw-r--r--fs/exec.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 1ebf6e5a521d..fc281b738a98 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -908,14 +908,14 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size,
goto out;
i_size = i_size_read(file_inode(file));
- if (max_size > 0 && i_size > max_size) {
- ret = -EFBIG;
- goto out;
- }
if (i_size <= 0) {
ret = -EINVAL;
goto out;
}
+ if (i_size > SIZE_MAX || (max_size > 0 && i_size > max_size)) {
+ ret = -EFBIG;
+ goto out;
+ }
if (id != READING_FIRMWARE_PREALLOC_BUFFER)
*buf = vmalloc(i_size);