APPLIED[Jammy]: [PATCH 1/1] ext4: limit length to bitmap_maxbytes - blocksize in punch_hole

Colin King (gmail) colin.i.king at gmail.com
Mon May 9 16:33:10 UTC 2022


Thanks for handling this so promptly!

On 09/05/2022 17:29, Kleber Souza wrote:
> 
> 
> On 09.05.22 16:00, Paolo Pisati wrote:
>> From: Tadeusz Struk <tadeusz.struk at linaro.org>
>>
>> BugLink: https://bugs.launchpad.net/bugs/196947
>>
>> Syzbot found an issue [1] in ext4_fallocate().
>> The C reproducer [2] calls fallocate(), passing size 0xffeffeff000ul,
>> and offset 0x1000000ul, which, when added together exceed the
>> bitmap_maxbytes for the inode. This triggers a BUG in
>> ext4_ind_remove_space(). According to the comments in this function
>> the 'end' parameter needs to be one block after the last block to be
>> removed. In the case when the BUG is triggered it points to the last
>> block. Modify the ext4_punch_hole() function and add constraint that
>> caps the length to satisfy the one before laster block requirement.
>>
>> LINK: [1] 
>> https://syzkaller.appspot.com/bug?id=b80bd9cf348aac724a4f4dff251800106d721331 
>>
>> LINK: [2] https://syzkaller.appspot.com/text?tag=ReproC&x=14ba0238700000
>>
>> Fixes: a4bb6b64e39a ("ext4: enable "punch hole" functionality")
>> Reported-by: syzbot+7a806094edd5d07ba029 at syzkaller.appspotmail.com
>> Signed-off-by: Tadeusz Struk <tadeusz.struk at linaro.org>
>> Link: 
>> https://lore.kernel.org/r/20220331200515.153214-1-tadeusz.struk@linaro.org 
>>
>> Signed-off-by: Theodore Ts'o <tytso at mit.edu>
>> Cc: stable at kernel.org
>> (cherry picked from commit 2da376228a2427501feb9d15815a45dbdbdd753e)
>> Reported-by: Colin King <colin.i.king at gmail.com>
>> Signed-off-by: Paolo Pisati <paolo.pisati at canonical.com>
> 
> Applied to impish:linux with some fuzz.
> 
> Thanks,
> Kleber
> 
>> ---
>>   fs/ext4/inode.c | 11 ++++++++++-
>>   1 file changed, 10 insertions(+), 1 deletion(-)
>>
>> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
>> index 54d8bdd46b9f..d22b2a522ef1 100644
>> --- a/fs/ext4/inode.c
>> +++ b/fs/ext4/inode.c
>> @@ -4314,7 +4314,8 @@ int ext4_punch_hole(struct inode *inode, loff_t 
>> offset, loff_t length)
>>       struct super_block *sb = inode->i_sb;
>>       ext4_lblk_t first_block, stop_block;
>>       struct address_space *mapping = inode->i_mapping;
>> -    loff_t first_block_offset, last_block_offset;
>> +    loff_t first_block_offset, last_block_offset, max_length;
>> +    struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
>>       handle_t *handle;
>>       unsigned int credits;
>>       int ret = 0;
>> @@ -4360,6 +4361,14 @@ int ext4_punch_hole(struct inode *inode, loff_t 
>> offset, loff_t length)
>>              offset;
>>       }
>> +    /*
>> +     * For punch hole the length + offset needs to be within one block
>> +     * before last range. Adjust the length if it goes beyond that 
>> limit.
>> +     */
>> +    max_length = sbi->s_bitmap_maxbytes - inode->i_sb->s_blocksize;
>> +    if (offset + length > max_length)
>> +        length = max_length - offset;
>> +
>>       if (offset & (sb->s_blocksize - 1) ||
>>           (offset + length) & (sb->s_blocksize - 1)) {
>>           /*




More information about the kernel-team mailing list