From nobody Wed Feb 11 16:10:47 2026 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 A4EB9C7EE23 for ; Mon, 8 May 2023 12:38:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234240AbjEHMiT (ORCPT ); Mon, 8 May 2023 08:38:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39102 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234261AbjEHMiQ (ORCPT ); Mon, 8 May 2023 08:38:16 -0400 Received: from relayaws-01.paragon-software.com (relayaws-01.paragon-software.com [35.157.23.187]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9B318DC41; Mon, 8 May 2023 05:38:12 -0700 (PDT) Received: from dlg2.mail.paragon-software.com (vdlg-exch-02.paragon-software.com [172.30.1.105]) by relayaws-01.paragon-software.com (Postfix) with ESMTPS id 0BB2221C3; Mon, 8 May 2023 12:33:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=paragon-software.com; s=mail; t=1683549204; bh=ozLaxeqLvZ1koAu7iHKobUtKETfbqwTAtHlsxw0uvGA=; h=Date:Subject:From:To:CC:References:In-Reply-To; b=Tuy+0aG7q59X0miTQqawIcroIrb0MO6DRbdAf33UgW6iBCm2NMR7pLt3UIdczne9/ bYF0sZRpzlk6eux3NkIBH9aFhnv+4IDSafaJ7AULTAArckZcq2JFYaCPiootiaRXRs 7SrXmHgkoo6zk0XSUM6pKAlIwg3+ColKFUQXF2V0= Received: from [192.168.211.146] (192.168.211.146) by vdlg-exch-02.paragon-software.com (172.30.1.105) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.7; Mon, 8 May 2023 15:38:10 +0300 Message-ID: <45f18870-379f-fa88-382c-5600e31d33a6@paragon-software.com> Date: Mon, 8 May 2023 16:38:09 +0400 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.10.1 Subject: [PATCH 05/10] fs/ntfs3: Do not update primary boot in ntfs_init_from_boot() Content-Language: en-US From: Konstantin Komarov To: CC: Linux Kernel Mailing List , References: In-Reply-To: Content-Type: text/plain; charset="utf-8"; format="flowed" Content-Transfer-Encoding: quoted-printable X-Originating-IP: [192.168.211.146] X-ClientProxiedBy: vobn-exch-01.paragon-software.com (172.30.72.13) To vdlg-exch-02.paragon-software.com (172.30.1.105) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 'cause it may be faked boot. Let ntfs to be mounted and update boot later. Signed-off-by: Konstantin Komarov --- =C2=A0fs/ntfs3/super.c | 58 ++++++++++++++++++++++++++++++++--------------= -- =C2=A01 file changed, 39 insertions(+), 19 deletions(-) diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c index ecf899d571d8..2b48b45238ea 100644 --- a/fs/ntfs3/super.c +++ b/fs/ntfs3/super.c @@ -711,9 +711,16 @@ static u32 true_sectors_per_clst(const struct=20 NTFS_BOOT *boot) =C2=A0/* =C2=A0 * ntfs_init_from_boot - Init internal info from on-disk boot sector. + * + * NTFS mount begins from boot - special formatted 512 bytes. + * There are two boots: the first and the last 512 bytes of volume. + * The content of boot is not changed during ntfs life. + * + * NOTE: ntfs.sys checks only first (primary) boot. + * chkdsk checks both boots. =C2=A0 */ =C2=A0static int ntfs_init_from_boot(struct super_block *sb, u32 sector_si= ze, -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 u64 dev_size) +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 u64 dev_size, struct NTFS_BOOT **boot2) =C2=A0{ =C2=A0=C2=A0=C2=A0 =C2=A0struct ntfs_sb_info *sbi =3D sb->s_fs_info; =C2=A0=C2=A0=C2=A0 =C2=A0int err; @@ -937,23 +944,11 @@ static int ntfs_init_from_boot(struct super_block=20 *sb, u32 sector_size, =C2=A0=C2=A0=C2=A0 =C2=A0if (bh->b_blocknr && !sb_rdonly(sb)) { =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0/* -=C2=A0=C2=A0 =C2=A0 =C2=A0=C2=A0 =C2=A0 * Alternative boot is ok but prima= ry is not ok. -=C2=A0=C2=A0 =C2=A0 =C2=A0=C2=A0 =C2=A0 * Update primary boot. -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 */ -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0struct buffer_head *bh0 =3D sb_getbl= k(sb, 0); -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0if (bh0) { -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0if (buffer_locked= (bh0)) -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2= =A0__wait_on_buffer(bh0); - -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0lock_buffer(bh0); -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0memcpy(bh0->b_dat= a, boot, sizeof(*boot)); -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0set_buffer_uptoda= te(bh0); -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0mark_buffer_dirty= (bh0); -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0unlock_buffer(bh0= ); -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0if (!sync_dirty_b= uffer(bh0)) -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2= =A0ntfs_warn(sb, "primary boot is updated"); -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0put_bh(bh0); -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0} +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 * Alternative boot is ok but p= rimary is not ok. +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 * Do not update primary boot h= ere 'cause it may be faked boot. +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 * Let ntfs to be mounted and u= pdate boot later. +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 */ +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0*boot2 =3D kmemdup(boot, sizeof(*boo= t), GFP_NOFS | __GFP_NOWARN); =C2=A0=C2=A0=C2=A0 =C2=A0} =C2=A0out: @@ -1000,6 +995,7 @@ static int ntfs_fill_super(struct super_block *sb,=20 struct fs_context *fc) =C2=A0=C2=A0=C2=A0 =C2=A0u16 *shared; =C2=A0=C2=A0=C2=A0 =C2=A0struct MFT_REF ref; =C2=A0=C2=A0=C2=A0 =C2=A0bool ro =3D sb_rdonly(sb); +=C2=A0=C2=A0 =C2=A0struct NTFS_BOOT *boot2 =3D NULL; =C2=A0=C2=A0=C2=A0 =C2=A0ref.high =3D 0; @@ -1030,7 +1026,7 @@ static int ntfs_fill_super(struct super_block *sb,=20 struct fs_context *fc) =C2=A0=C2=A0=C2=A0 =C2=A0/* Parse boot. */ =C2=A0=C2=A0=C2=A0 =C2=A0err =3D ntfs_init_from_boot(sb, bdev_logical_bloc= k_size(bdev), -=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2= =A0=C2=A0 bdev_nr_bytes(bdev)); +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2= =A0=C2=A0 bdev_nr_bytes(bdev), &boot2); =C2=A0=C2=A0=C2=A0 =C2=A0if (err) =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0goto out; @@ -1412,6 +1408,29 @@ static int ntfs_fill_super(struct super_block=20 *sb, struct fs_context *fc) =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0goto put_inode_out; =C2=A0=C2=A0=C2=A0 =C2=A0} +=C2=A0=C2=A0 =C2=A0if (boot2) { +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0/* +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 * Alternative boot is ok but p= rimary is not ok. +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 * Volume is recognized as NTFS= . Update primary boot. +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 */ +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0struct buffer_head *bh0 =3D sb_getbl= k(sb, 0); +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0if (bh0) { +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0if (buffer_locked= (bh0)) +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2= =A0__wait_on_buffer(bh0); + +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0lock_buffer(bh0); +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0memcpy(bh0->b_dat= a, boot2, sizeof(*boot2)); +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0set_buffer_uptoda= te(bh0); +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0mark_buffer_dirty= (bh0); +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0unlock_buffer(bh0= ); +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0if (!sync_dirty_b= uffer(bh0)) +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2= =A0ntfs_warn(sb, "primary boot is updated"); +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0put_bh(bh0); +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0} + +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0kfree(boot2); +=C2=A0=C2=A0 =C2=A0} + =C2=A0=C2=A0=C2=A0 =C2=A0return 0; =C2=A0put_inode_out: @@ -1424,6 +1443,7 @@ static int ntfs_fill_super(struct super_block *sb,=20 struct fs_context *fc) =C2=A0=C2=A0=C2=A0 =C2=A0put_mount_options(sbi->options); =C2=A0=C2=A0=C2=A0 =C2=A0put_ntfs(sbi); =C2=A0=C2=A0=C2=A0 =C2=A0sb->s_fs_info =3D NULL; +=C2=A0=C2=A0 =C2=A0kfree(boot2); =C2=A0=C2=A0=C2=A0 =C2=A0return err; =C2=A0} --=20 2.34.1