From patchwork Sun Jun 28 06:08:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 11629921 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4D092618 for ; Sun, 28 Jun 2020 06:10:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3473D2076C for ; Sun, 28 Jun 2020 06:10:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1593324653; bh=eQb+Fz3rRAzfKslIoQDAR5opE1JytzPdjZ4dAMCRjCE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=O/H/wqyHVf6XzF2qEOjBSLYI1hGB8FMUB0e1wzjOzBDJDHmoaeJXFfwkX6vKNZt5j vVHKBFrCvIZjLGpoClajtm0LdV+tsPieXOEo9kLNb1PaoqksvYT+9fqv3eeQq3ktin zCheeC0pIqCBTbWjXAvXwsErYOlYTLry+pI6XdAE= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726141AbgF1GKw (ORCPT ); Sun, 28 Jun 2020 02:10:52 -0400 Received: from mail.kernel.org ([198.145.29.99]:41986 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726027AbgF1GKg (ORCPT ); Sun, 28 Jun 2020 02:10:36 -0400 Received: from sol.hsd1.ca.comcast.net (c-107-3-166-239.hsd1.ca.comcast.net [107.3.166.239]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 33EFA2076C; Sun, 28 Jun 2020 06:10:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1593324635; bh=eQb+Fz3rRAzfKslIoQDAR5opE1JytzPdjZ4dAMCRjCE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=2Qu4KmCXffqy3QlBCH9YucJ8xWAVejd8vUslbePuJeGh/h55TvRjA4NQIgyjK+AWc eGNAvIM27aGihdMrP3nWit1dL8d2Nc3W7zZ7ACIySQVTuNpjROj3zE9nAhUOXlykP2 vkCtu9CvpTPOg97slGXqbOxUyRGP+asygqOqEDFU= From: Eric Biggers To: linux-fsdevel@vger.kernel.org, Alexander Viro , Andrew Morton Cc: linux-kernel@vger.kernel.org, Qiujun Huang , stable@vger.kernel.org, syzbot+c7d9ec7a1a7272dd71b3@syzkaller.appspotmail.com, syzbot+3b7b03a0c28948054fb5@syzkaller.appspotmail.com, syzbot+6e056ee473568865f3e6@syzkaller.appspotmail.com Subject: [PATCH 3/6] fs/minix: reject too-large maximum file size Date: Sat, 27 Jun 2020 23:08:42 -0700 Message-Id: <20200628060846.682158-4-ebiggers@kernel.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200628060846.682158-1-ebiggers@kernel.org> References: <20200628060846.682158-1-ebiggers@kernel.org> MIME-Version: 1.0 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org From: Eric Biggers If the minix filesystem tries to map a very large logical block number to its on-disk location, block_to_path() can return offsets that are too large, causing out-of-bounds memory accesses when accessing indirect index blocks. This should be prevented by the check against the maximum file size, but this doesn't work because the maximum file size is read directly from the on-disk superblock and isn't validated itself. Fix this by validating the maximum file size at mount time. Reported-by: syzbot+c7d9ec7a1a7272dd71b3@syzkaller.appspotmail.com Reported-by: syzbot+3b7b03a0c28948054fb5@syzkaller.appspotmail.com Reported-by: syzbot+6e056ee473568865f3e6@syzkaller.appspotmail.com Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Signed-off-by: Eric Biggers --- fs/minix/inode.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 2bca95abe8f4..0dd929346f3f 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c @@ -150,6 +150,23 @@ static int minix_remount (struct super_block * sb, int * flags, char * data) return 0; } +static bool minix_check_superblock(struct minix_sb_info *sbi) +{ + if (sbi->s_imap_blocks == 0 || sbi->s_zmap_blocks == 0) + return false; + + /* + * s_max_size must not exceed the block mapping limitation. This check + * is only needed for V1 filesystems, since V2/V3 support an extra level + * of indirect blocks which places the limit well above U32_MAX. + */ + if (sbi->s_version == MINIX_V1 && + sbi->s_max_size > (7 + 512 + 512*512) * BLOCK_SIZE) + return false; + + return true; +} + static int minix_fill_super(struct super_block *s, void *data, int silent) { struct buffer_head *bh; @@ -228,11 +245,12 @@ static int minix_fill_super(struct super_block *s, void *data, int silent) } else goto out_no_fs; + if (!minix_check_superblock(sbi)) + goto out_illegal_sb; + /* * Allocate the buffer map to keep the superblock small. */ - if (sbi->s_imap_blocks == 0 || sbi->s_zmap_blocks == 0) - goto out_illegal_sb; i = (sbi->s_imap_blocks + sbi->s_zmap_blocks) * sizeof(bh); map = kzalloc(i, GFP_KERNEL); if (!map)