| From 75ca6ad408f459f00b09a64f04c774559848c097 Mon Sep 17 00:00:00 2001 |
| From: Ritesh Harjani <riteshh@linux.ibm.com> |
| Date: Sat, 5 Jun 2021 10:39:32 +0530 |
| Subject: ext4: fix loff_t overflow in ext4_max_bitmap_size() |
| |
| From: Ritesh Harjani <riteshh@linux.ibm.com> |
| |
| commit 75ca6ad408f459f00b09a64f04c774559848c097 upstream. |
| |
| We should use unsigned long long rather than loff_t to avoid |
| overflow in ext4_max_bitmap_size() for comparison before returning. |
| w/o this patch sbi->s_bitmap_maxbytes was becoming a negative |
| value due to overflow of upper_limit (with has_huge_files as true) |
| |
| Below is a quick test to trigger it on a 64KB pagesize system. |
| |
| sudo mkfs.ext4 -b 65536 -O ^has_extents,^64bit /dev/loop2 |
| sudo mount /dev/loop2 /mnt |
| sudo echo "hello" > /mnt/hello -> This will error out with |
| "echo: write error: File too large" |
| |
| Signed-off-by: Ritesh Harjani <riteshh@linux.ibm.com> |
| Reviewed-by: Jan Kara <jack@suse.cz> |
| Signed-off-by: Theodore Ts'o <tytso@mit.edu> |
| Cc: stable@kernel.org |
| Link: https://lore.kernel.org/r/594f409e2c543e90fd836b78188dfa5c575065ba.1622867594.git.riteshh@linux.ibm.com |
| Signed-off-by: Theodore Ts'o <tytso@mit.edu> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| fs/ext4/super.c | 10 +++++----- |
| 1 file changed, 5 insertions(+), 5 deletions(-) |
| |
| --- a/fs/ext4/super.c |
| +++ b/fs/ext4/super.c |
| @@ -3194,17 +3194,17 @@ static loff_t ext4_max_size(int blkbits, |
| */ |
| static loff_t ext4_max_bitmap_size(int bits, int has_huge_files) |
| { |
| - loff_t res = EXT4_NDIR_BLOCKS; |
| + unsigned long long upper_limit, res = EXT4_NDIR_BLOCKS; |
| int meta_blocks; |
| - loff_t upper_limit; |
| - /* This is calculated to be the largest file size for a dense, block |
| + |
| + /* |
| + * This is calculated to be the largest file size for a dense, block |
| * mapped file such that the file's total number of 512-byte sectors, |
| * including data and all indirect blocks, does not exceed (2^48 - 1). |
| * |
| * __u32 i_blocks_lo and _u16 i_blocks_high represent the total |
| * number of 512-byte sectors of the file. |
| */ |
| - |
| if (!has_huge_files) { |
| /* |
| * !has_huge_files or implies that the inode i_block field |
| @@ -3247,7 +3247,7 @@ static loff_t ext4_max_bitmap_size(int b |
| if (res > MAX_LFS_FILESIZE) |
| res = MAX_LFS_FILESIZE; |
| |
| - return res; |
| + return (loff_t)res; |
| } |
| |
| static ext4_fsblk_t descriptor_loc(struct super_block *sb, |