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

Kleber Souza kleber.sacilotto.de.souza at canonical.com
Mon May 9 16:30:59 UTC 2022


The subject should obviously have been "Impish" instead of "Jammy".

On 09.05.22 18: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