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 <redacted>
---
fs/ext4/super.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
@@ -3189,17 +3189,17 @@ static loff_t ext4_max_size(int blkbits, int has_huge_files)*/staticloff_text4_max_bitmap_size(intbits,inthas_huge_files){-loff_tres=EXT4_NDIR_BLOCKS;+unsignedlonglongupper_limit,res=EXT4_NDIR_BLOCKS;intmeta_blocks;-loff_tupper_limit;-/* This is calculated to be the largest file size for a dense, block++/*+*Thisiscalculatedtobethelargestfilesizeforadense,block*mappedfilesuchthatthefile'stotalnumberof512-bytesectors,*includingdataandallindirectblocks,doesnotexceed(2^48-1).**__u32i_blocks_loand_u16i_blocks_highrepresentthetotal*numberof512-bytesectorsofthefile.*/-if(!has_huge_files){/**!has_huge_filesorimpliesthattheinodei_blockfield
@@ -3242,7 +3242,7 @@ static loff_t ext4_max_bitmap_size(int bits, int has_huge_files)if(res>MAX_LFS_FILESIZE)res=MAX_LFS_FILESIZE;-returnres;+return(loff_t)res;}staticext4_fsblk_tdescriptor_loc(structsuper_block*sb,
From: Jan Kara <jack@suse.cz> Date: 2021-06-07 10:00:30
On Sat 05-06-21 10:39:32, Ritesh Harjani wrote:
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 <redacted>
OK, this works (although it's really tight ;). Won't it be somewhat safer
if we compared upper_limit and res before shifting both by blocksize_bits
to the left? Basically we need to shift only for comparison with
MAX_LFS_FILESIZE which is in bytes... But either way feel free to add:
Reviewed-by: Jan Kara <jack@suse.cz>
Honza
@@ -3189,17 +3189,17 @@ static loff_t ext4_max_size(int blkbits, int has_huge_files)*/staticloff_text4_max_bitmap_size(intbits,inthas_huge_files){-loff_tres=EXT4_NDIR_BLOCKS;+unsignedlonglongupper_limit,res=EXT4_NDIR_BLOCKS;intmeta_blocks;-loff_tupper_limit;-/* This is calculated to be the largest file size for a dense, block++/*+*Thisiscalculatedtobethelargestfilesizeforadense,block*mappedfilesuchthatthefile'stotalnumberof512-bytesectors,*includingdataandallindirectblocks,doesnotexceed(2^48-1).**__u32i_blocks_loand_u16i_blocks_highrepresentthetotal*numberof512-bytesectorsofthefile.*/-if(!has_huge_files){/**!has_huge_filesorimpliesthattheinodei_blockfield
@@ -3242,7 +3242,7 @@ static loff_t ext4_max_bitmap_size(int bits, int has_huge_files)if(res>MAX_LFS_FILESIZE)res=MAX_LFS_FILESIZE;-returnres;+return(loff_t)res;}staticext4_fsblk_tdescriptor_loc(structsuper_block*sb,
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 <redacted>
OK, this works (although it's really tight ;). Won't it be somewhat safer
if we compared upper_limit and res before shifting both by blocksize_bits
to the left? Basically we need to shift only for comparison with
MAX_LFS_FILESIZE which is in bytes... But either way feel free to add:
Yes, at 1st I did think that, but since for comparing "res" against
MAX_LFS_FILESIZE we will be anyway doing the bit shifting and since this logic
too was (just) fitting into the limits so I thought of keeping it the same.
But, if absolutely required, I can make those changes.
@@ -3189,17 +3189,17 @@ static loff_t ext4_max_size(int blkbits, int has_huge_files)*/staticloff_text4_max_bitmap_size(intbits,inthas_huge_files){-loff_tres=EXT4_NDIR_BLOCKS;+unsignedlonglongupper_limit,res=EXT4_NDIR_BLOCKS;intmeta_blocks;-loff_tupper_limit;-/* This is calculated to be the largest file size for a dense, block++/*+*Thisiscalculatedtobethelargestfilesizeforadense,block*mappedfilesuchthatthefile'stotalnumberof512-bytesectors,*includingdataandallindirectblocks,doesnotexceed(2^48-1).**__u32i_blocks_loand_u16i_blocks_highrepresentthetotal*numberof512-bytesectorsofthefile.*/-if(!has_huge_files){/**!has_huge_filesorimpliesthattheinodei_blockfield
@@ -3242,7 +3242,7 @@ static loff_t ext4_max_bitmap_size(int bits, int has_huge_files)if(res>MAX_LFS_FILESIZE)res=MAX_LFS_FILESIZE;-returnres;+return(loff_t)res;}staticext4_fsblk_tdescriptor_loc(structsuper_block*sb,--
On Sat, 5 Jun 2021 10:39:32 +0530, Ritesh Harjani wrote:
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.
[...]
Applied, thanks!
[1/1] ext4: Fix loff_t overflow in ext4_max_bitmap_size()
commit: f9b9e1afe996e8b4a0a2ea8481c41756fff53d08
Best regards,
--
Theodore Ts'o [off-list ref]