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>
This commit is contained in:
Eric Biggers 2018-09-07 12:16:24 -07:00 committed by Mimi Zohar
parent e6123c5240
commit 691115c351

View File

@ -908,14 +908,14 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size,
goto out; goto out;
i_size = i_size_read(file_inode(file)); i_size = i_size_read(file_inode(file));
if (max_size > 0 && i_size > max_size) {
ret = -EFBIG;
goto out;
}
if (i_size <= 0) { if (i_size <= 0) {
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
} }
if (i_size > SIZE_MAX || (max_size > 0 && i_size > max_size)) {
ret = -EFBIG;
goto out;
}
if (id != READING_FIRMWARE_PREALLOC_BUFFER) if (id != READING_FIRMWARE_PREALLOC_BUFFER)
*buf = vmalloc(i_size); *buf = vmalloc(i_size);