From: Matthias Goergens <matthias.goergens@gmail.com>
To: Namjae Jeon <linkinjeon@kernel.org>, Hyunchul Lee <hyc.lee@gmail.com>
Cc: ntfs@lists.linux.dev, linux-kernel@vger.kernel.org
Subject: [PATCH v2 5/6] ntfs: fail the mount when $MFT's data size exceeds its allocation
Date: Sun, 27 Sep 2026 13:08:24 +0800 [thread overview]
Message-ID: <20260927050831.2739166-5-matthias.goergens@gmail.com> (raw)
In-Reply-To: <cover.1790417653.git.matthias.goergens@gmail.com>
ntfs_read_inode_mount() takes $MFT's i_size from data_size without
checking it against allocated_size, unlike the resident case in
ntfs_read_locked_inode(). mft records between the two are not on disk.
On a crafted volume with 512-byte clusters whose $MFT is cut to 4
clusters while data_size still says 27 records, reading the folio
holding records 0-3 finds the end of the runlist at vcn 4. An unpatched
kernel hangs there on the folio lock, as in "ntfs: fail the mount when
$MFT needs its own extent records". With the previous patch vcn 4-7 are
past the allocation and so read as a hole: records 2 and 3 come back as
zeros and the mount carries on until check_mft_mirror() finds the zeroed
record 2.
Refuse such a $MFT before anything is read through it. The mount now
fails with:
ntfs: (device vda): ntfs_read_inode_mount(): $MFT data size 27648
exceeds its allocated size 2048. $MFT is corrupt. Run chkdsk.
fs/ntfs3 rejects any non-resident attribute whose data_size exceeds its
allocated size. This patch checks only $MFT; the next one covers the
other non-resident attributes.
Fixes: b041ca562526 ("ntfs: update iomap and address space operations")
Cc: stable@vger.kernel.org
Signed-off-by: Matthias Goergens <matthias.goergens@gmail.com>
---
fs/ntfs/inode.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
index a61f1519549cb..9c97fc3f9e5ff 100644
--- a/fs/ntfs/inode.c
+++ b/fs/ntfs/inode.c
@@ -2136,6 +2136,16 @@ int ntfs_read_inode_mount(struct inode *vi)
vi->i_size = le64_to_cpu(a->data.non_resident.data_size);
ni->initialized_size = le64_to_cpu(a->data.non_resident.initialized_size);
ni->allocated_size = le64_to_cpu(a->data.non_resident.allocated_size);
+ /*
+ * Records between allocated_size and data_size are not
+ * on disk, and would be read as zeros.
+ */
+ if (vi->i_size > ni->allocated_size) {
+ ntfs_error(sb,
+ "$MFT data size %lld exceeds its allocated size %lld. $MFT is corrupt. Run chkdsk.",
+ vi->i_size, ni->allocated_size);
+ goto put_err_out;
+ }
/*
* Verify the number of mft records does not exceed
* 2^32 - 1.
--
2.55.0
next prev parent reply other threads:[~2026-09-27 5:08 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-22 15:39 [PATCH] ntfs: fail the mount when $MFT needs its own extent records Matthias Goergens
2026-09-23 1:16 ` Hyunchul Lee
2026-09-27 5:08 ` [PATCH v2 0/6] ntfs: fix the $MFT bootstrap hang and reads of unmapped runlist ranges Matthias Goergens
2026-09-27 5:08 ` [PATCH v2 1/6] ntfs: do not map an unmappable runlist fragment as a hole Matthias Goergens
2026-09-27 23:03 ` liubaolin
2026-09-27 5:08 ` [PATCH v2 2/6] ntfs: do not turn an unmappable runlist fragment into delalloc on write Matthias Goergens
2026-09-27 5:08 ` [PATCH v2 3/6] ntfs: fail the mount when $MFT needs its own extent records Matthias Goergens
2026-09-27 5:08 ` [PATCH v2 4/6] ntfs: do not map a vcn as a hole when its runlist lookup failed Matthias Goergens
2026-09-27 5:08 ` Matthias Goergens [this message]
2026-09-27 5:08 ` [PATCH v2 6/6] ntfs: reject non-resident attributes whose sizes exceed their allocation Matthias Goergens
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260927050831.2739166-5-matthias.goergens@gmail.com \
--to=matthias.goergens@gmail.com \
--cc=hyc.lee@gmail.com \
--cc=linkinjeon@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=ntfs@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®