From patchwork Tue Apr 26 08:21:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greg Kroah-Hartman X-Patchwork-Id: 567867 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E13BAC433EF for ; Tue, 26 Apr 2022 08:55:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236933AbiDZI6O (ORCPT ); Tue, 26 Apr 2022 04:58:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44652 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345849AbiDZI5B (ORCPT ); Tue, 26 Apr 2022 04:57:01 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 001A98300C; Tue, 26 Apr 2022 01:41:40 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id A8AC1B81CED; Tue, 26 Apr 2022 08:41:39 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 17279C385A4; Tue, 26 Apr 2022 08:41:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1650962498; bh=Wky2LVegEVbuR6r6OwodDevRj0k5Ql7r04s9AbO0HOM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IjZKQwiyFFuGETzD+UKJv+Vyv5d450ofyw+ezR3/AOi2gztryhWujKnM/5Lhb8VkW 1gLdWGad0x1t/aZowGpI6p+XkYtdzhnOJjSE8bSLJDurWr+Iy5IJBbq0agNaNIYiX8 1DiFzIfEF8PMsoOR61vqPTBIGvp2dkOvpb4K55EE= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, syzbot+7a806094edd5d07ba029@syzkaller.appspotmail.com, Tadeusz Struk , Theodore Tso , stable@kernel.org Subject: [PATCH 5.15 116/124] ext4: limit length to bitmap_maxbytes - blocksize in punch_hole Date: Tue, 26 Apr 2022 10:21:57 +0200 Message-Id: <20220426081750.588477544@linuxfoundation.org> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220426081747.286685339@linuxfoundation.org> References: <20220426081747.286685339@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Tadeusz Struk commit 2da376228a2427501feb9d15815a45dbdbdd753e upstream. 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@syzkaller.appspotmail.com Signed-off-by: Tadeusz Struk Link: https://lore.kernel.org/r/20220331200515.153214-1-tadeusz.struk@linaro.org Signed-off-by: Theodore Ts'o Cc: stable@kernel.org Signed-off-by: Greg Kroah-Hartman --- fs/ext4/inode.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -3945,7 +3945,8 @@ int ext4_punch_hole(struct file *file, l 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, ret2 = 0; @@ -3988,6 +3989,14 @@ int ext4_punch_hole(struct file *file, l 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)) { /*