Received: by 2002:a05:6358:1087:b0:cb:c9d3:cd90 with SMTP id j7csp121779rwi; Wed, 26 Oct 2022 21:52:16 -0700 (PDT) X-Google-Smtp-Source: AMsMyM7lO4/nrmnzhxKRn2OfPwW+PH74VPDYwN3RFm7PUlI3Mcgo64YhBbcLsNjQFAVtPQgSabqK X-Received: by 2002:aa7:d506:0:b0:461:565e:8673 with SMTP id y6-20020aa7d506000000b00461565e8673mr28341606edq.416.1666846336330; Wed, 26 Oct 2022 21:52:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666846336; cv=none; d=google.com; s=arc-20160816; b=k3qKPuvdgxJySkXmDNgM7x1yyHtC99iUNJg4uZj8/eo7G2kIHMpmUFaAzRl7UugA0j OSTXoriT8RYQc+RkdCXMrjqCJ8rGp23fsTQsJiyAaXU0wCwHQFGcoa9WzxgH45Wg5+2G RYlbU7hZJN0Sc8edC9RzYKC5uXwwJzPWr+4I45/d6BgxvUhlD/YnUA7m+2CqpsA5DpS9 OOOsWEnivRTEZrnmkZsrUrUP/MMAgtIocvoRnciVYwQXTC9SdXhhbYf2KVGW40sZghxy Rx34+vUWtYU7tV6dqqKQcFyYpvDd+m49J/IIK5pV/NFe6d14t4cbcY3mNeWIhmnG3Ka3 wUXg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=1CCq70oXkrOiZ0hlpxTV/q9jKiiD+wVtMgJ5m746aQw=; b=U/j3bm5/ZQvwlcjHdXTn0F2LxGrG+V78AvQaGIKldLyrX+77IL0wljOtPyLB0/xWUj Nxx5BObMqj9GmvBvZ2uVDrLoJQuZhIM1N5VMsX2vtfp/g1QoiYg9QZNs2v8+BHC1AaSe p3T8S3So0Pm8H8KGFzgFRknepjs9sbsPiZY+ql0tTmrLLarTGUT9EuAjOJXWfUtn0APU T37TMx7fflD/4DsssVSSK+rs5AqS3AgKCzbDCF0DSVKz913RSiWNwKo4OLWF0jmB/yGy MN3QAJf/Yk73OdRzy4XwyROeeB+frzU0zsgRX8lHyzB2EKfxIwQUQ9/U/fBF/TRWZkZp xflA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=Bk2VwBCD; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id j16-20020aa7c0d0000000b004534c7d4ebfsi476271edp.434.2022.10.26.21.51.51; Wed, 26 Oct 2022 21:52:16 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=Bk2VwBCD; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234052AbiJ0EnZ (ORCPT + 99 others); Thu, 27 Oct 2022 00:43:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54310 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233810AbiJ0EnR (ORCPT ); Thu, 27 Oct 2022 00:43:17 -0400 Received: from mail-pl1-x62a.google.com (mail-pl1-x62a.google.com [IPv6:2607:f8b0:4864:20::62a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E9CB7156257; Wed, 26 Oct 2022 21:43:16 -0700 (PDT) Received: by mail-pl1-x62a.google.com with SMTP id d24so260011pls.4; Wed, 26 Oct 2022 21:43:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=1CCq70oXkrOiZ0hlpxTV/q9jKiiD+wVtMgJ5m746aQw=; b=Bk2VwBCDAGpwDYoxWcNk9af9n73eL1AzE9BSZtwllbt6iQ8p+FCHrlVcX6+1SIwlAv Qa1IFccARwZpVs+bV/LsCNIxrwHlveo6uIjDw2nbgIdlOuAA/tLwlFi40nI5uFwPVLcq rrFG3Mi5nhlaGCampV85QqYQpVoNNqtg56DiyPlG/9QUUBeC1sy3X0QVSdwAeBSjQTRU tUEMkmsIdyLMOE5BpeESBB36Lk6dU/VU+4hpfHXt1TkdJD3aCWKw1Hln98M8isg9t8G2 7RM7HAAMXBCmdZP6ZzprLnCA3K9/+j/tOEDaAfzmIs4dDsv7oCUHdFN1W51eQE1dd17+ vwVA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=1CCq70oXkrOiZ0hlpxTV/q9jKiiD+wVtMgJ5m746aQw=; b=1rAkLoyFw5SV3nSgH+yFI8nKBzA0pPFtJzh/spbRQV4CldXBGyix+zrQxTaBhI03hg bO2Mmcc5MKv2HGQvPRsBjjCS2rpCSG40K/ZDRcWKl6Y93aIYPHVmRbyPI3sLzqUk/GrH efRsJCqsUYFKzBxjpk4mHRDjyHspSGRAt4kmMPBQFneqH0nI1zZlntHOx7qrVxHOjuog NS+293wTKcmBfndnCbFagaKj0a3P6X2VW6AZgATPjFrwxoNY0pfR9CnT6F/0GFbkkX83 xtvWiZqN+23aJF5hbTV/yghmXQhm7d7faYcNgWF4MBDeD4Cgfjc+RuJAc7oUC1u8AhoE /Z3Q== X-Gm-Message-State: ACrzQf2A+5NwmVDM0BZM0rzFZ7/OV6kFM2a+yG63w4DALfTKZGh5b+Eg 5yQl0DjRCSH1LyIYnCmcG6zfZUmdIZk= X-Received: by 2002:a17:902:f78c:b0:185:3d6a:7576 with SMTP id q12-20020a170902f78c00b001853d6a7576mr6496308pln.86.1666845796292; Wed, 26 Oct 2022 21:43:16 -0700 (PDT) Received: from carrot.. (i220-108-44-211.s42.a014.ap.plala.or.jp. [220.108.44.211]) by smtp.gmail.com with ESMTPSA id m4-20020a170902db0400b00186a2274382sm186929plx.76.2022.10.26.21.43.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 Oct 2022 21:43:15 -0700 (PDT) From: Ryusuke Konishi To: Andrew Morton Cc: linux-nilfs , syzbot , syzkaller-bugs@googlegroups.com, LKML Subject: [PATCH 2/2] nilfs2: fix shift-out-of-bounds due to too large exponent of block size Date: Thu, 27 Oct 2022 13:43:06 +0900 Message-Id: <20221027044306.42774-3-konishi.ryusuke@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221027044306.42774-1-konishi.ryusuke@gmail.com> References: <20221027044306.42774-1-konishi.ryusuke@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org If field s_log_block_size of superblock data is corrupted and too large, init_nilfs() and load_nilfs() still can trigger a shift-out-of-bounds warning followed by a kernel panic (if panic_on_warn is set): shift exponent 38973 is too large for 32-bit type 'int' Call Trace: dump_stack_lvl+0xcd/0x134 ubsan_epilogue+0xb/0x50 __ubsan_handle_shift_out_of_bounds.cold.12+0x17b/0x1f5 init_nilfs.cold.11+0x18/0x1d [nilfs2] nilfs_mount+0x9b5/0x12b0 [nilfs2] ... This fixes the issue by adding and using a new helper function for getting block size with sanity check. Signed-off-by: Ryusuke Konishi Tested-by: Ryusuke Konishi --- fs/nilfs2/the_nilfs.c | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c index d588816fdf2f..20ff02b4ef5d 100644 --- a/fs/nilfs2/the_nilfs.c +++ b/fs/nilfs2/the_nilfs.c @@ -193,6 +193,34 @@ static int nilfs_store_log_cursor(struct the_nilfs *nilfs, return ret; } +/** + * nilfs_get_blocksize - get block size from raw superblock data + * @sb: super block instance + * @sbp: superblock raw data buffer + * @blocksize: place to store block size + * + * nilfs_get_blocksize() calculates the block size from the block size + * exponent information written in @sbp and stores it in @blocksize, + * or aborts with an error message if it's too large. + * + * Return Value: On success, 0 is returned. If the block size is too + * large, -EINVAL is returned. + */ +static int nilfs_get_blocksize(struct super_block *sb, + struct nilfs_super_block *sbp, int *blocksize) +{ + unsigned int shift_bits = le32_to_cpu(sbp->s_log_block_size); + + if (unlikely(shift_bits > + ilog2(NILFS_MAX_BLOCK_SIZE) - BLOCK_SIZE_BITS)) { + nilfs_err(sb, "too large filesystem blocksize: 2 ^ %u KiB", + shift_bits); + return -EINVAL; + } + *blocksize = BLOCK_SIZE << shift_bits; + return 0; +} + /** * load_nilfs - load and recover the nilfs * @nilfs: the_nilfs structure to be released @@ -246,11 +274,15 @@ int load_nilfs(struct the_nilfs *nilfs, struct super_block *sb) nilfs->ns_sbwtime = le64_to_cpu(sbp[0]->s_wtime); /* verify consistency between two super blocks */ - blocksize = BLOCK_SIZE << le32_to_cpu(sbp[0]->s_log_block_size); + err = nilfs_get_blocksize(sb, sbp[0], &blocksize); + if (err) + goto scan_error; + if (blocksize != nilfs->ns_blocksize) { nilfs_warn(sb, "blocksize differs between two super blocks (%d != %d)", blocksize, nilfs->ns_blocksize); + err = -EINVAL; goto scan_error; } @@ -609,9 +641,11 @@ int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb, char *data) if (err) goto failed_sbh; - blocksize = BLOCK_SIZE << le32_to_cpu(sbp->s_log_block_size); - if (blocksize < NILFS_MIN_BLOCK_SIZE || - blocksize > NILFS_MAX_BLOCK_SIZE) { + err = nilfs_get_blocksize(sb, sbp, &blocksize); + if (err) + goto failed_sbh; + + if (blocksize < NILFS_MIN_BLOCK_SIZE) { nilfs_err(sb, "couldn't mount because of unsupported filesystem blocksize %d", blocksize); -- 2.34.1