
[BUG] When try to read a range beyond file size, btrfs driver will cause crash/segfault:
=> load host 0 $kernel_addr_r 5k_file 0 0x2000 SEGFAULT
[CAUSE] In btrfs_read(), if @len is 0, we will truncated it to file end, but if file end is beyond our file size, this truncation will underflow @len, making it -3K in this case.
And later that @len is used to memzero the output buffer, resulting above crash.
[FIX] Just error out if @offset is already beyond our file size.
Now it will fail properly with correct error message:
=> load host 0 $kernel_addr_r 5m_origin 0 0x2000 BTRFS: Read range beyond file size, offset 8192 file size 5120
Failed to load '5m_origin'
Signed-off-by: Qu Wenruo wqu@suse.com --- fs/btrfs/btrfs.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/fs/btrfs/btrfs.c b/fs/btrfs/btrfs.c index 9145727058d4..bf9e1f2f17cf 100644 --- a/fs/btrfs/btrfs.c +++ b/fs/btrfs/btrfs.c @@ -252,6 +252,12 @@ int btrfs_read(const char *file, void *buf, loff_t offset, loff_t len, return ret; }
+ if (offset >= real_size) { + error("Read range beyond file size, offset %llu file size %llu", + offset, real_size); + return -EINVAL; + } + /* * If the length is 0 (meaning read the whole file) or the range is * beyond file size, truncate it to the end of the file.