From: Hyunchul Lee <hyc.lee@gmail.com>
To: Namjae Jeon <linkinjeon@kernel.org>
Cc: Hyunchul Lee <hyc.lee@gmail.com>,
linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org,
woot000 <woot000@woot000.com>
Subject: [PATCH v2 2/4] ntfs: centalize $INDEX_ROOT header validation
Date: Sat, 23 May 2026 13:14:21 +0900 [thread overview]
Message-ID: <20260523041423.2726275-3-hyc.lee@gmail.com> (raw)
In-Reply-To: <20260523041423.2726275-1-hyc.lee@gmail.com>
Add a dedicated helper to perform stricter validation of $INDEX_ROOT and
use it for both directory inodes and named index inodes. This keeps the
root size and header geometry checks consistent across both read paths.
Tested-by: woot000 <woot000@woot000.com>
Signed-off-by: Hyunchul Lee <hyc.lee@gmail.com>
---
fs/ntfs/index.c | 18 ++++++++++++++++++
fs/ntfs/index.h | 3 +++
fs/ntfs/inode.c | 11 ++---------
3 files changed, 23 insertions(+), 9 deletions(-)
diff --git a/fs/ntfs/index.c b/fs/ntfs/index.c
index 9713b082b03d..97c0e7d6a580 100644
--- a/fs/ntfs/index.c
+++ b/fs/ntfs/index.c
@@ -541,6 +541,24 @@ int ntfs_index_block_inconsistent(struct ntfs_volume *vol,
return 0;
}
+int ntfs_index_root_inconsistent(struct ntfs_volume *vol,
+ const struct attr_record *a,
+ const struct index_root *ir, u64 inum)
+{
+ u32 value_length = le32_to_cpu(a->data.resident.value_length);
+
+ if (value_length < offsetof(struct index_root, index)) {
+ ntfs_error(vol->sb, "$INDEX_ROOT in inode %llu is too small.",
+ (unsigned long long)inum);
+ return -EIO;
+ }
+
+ return ntfs_index_header_inconsistent(vol, &ir->index,
+ value_length -
+ offsetof(struct index_root, index),
+ inum);
+}
+
static struct index_root *ntfs_ir_lookup(struct ntfs_inode *ni, __le16 *name,
u32 name_len, struct ntfs_attr_search_ctx **ctx)
{
diff --git a/fs/ntfs/index.h b/fs/ntfs/index.h
index 3451ec8a1c4e..cad78568d8b3 100644
--- a/fs/ntfs/index.h
+++ b/fs/ntfs/index.h
@@ -89,6 +89,9 @@ struct ntfs_index_context {
bool sync_write;
};
+int ntfs_index_root_inconsistent(struct ntfs_volume *vol,
+ const struct attr_record *a,
+ const struct index_root *ir, u64 inum);
int ntfs_index_block_inconsistent(struct ntfs_volume *vol,
const struct index_block *ib,
u32 block_size, s64 vcn, u64 inum);
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
index 360bebd1ee3f..63ee7acff4fc 100644
--- a/fs/ntfs/inode.c
+++ b/fs/ntfs/inode.c
@@ -890,7 +890,6 @@ static int ntfs_read_locked_inode(struct inode *vi)
*/
if (S_ISDIR(vi->i_mode)) {
struct index_root *ir;
- u8 *ir_end, *index_end;
view_index_meta:
/* It is a directory, find index root attribute. */
@@ -940,10 +939,7 @@ static int ntfs_read_locked_inode(struct inode *vi)
}
ir = (struct index_root *)((u8 *)a +
le16_to_cpu(a->data.resident.value_offset));
- ir_end = (u8 *)ir + le32_to_cpu(a->data.resident.value_length);
- index_end = (u8 *)&ir->index +
- le32_to_cpu(ir->index.index_length);
- if (index_end > ir_end) {
+ if (ntfs_index_root_inconsistent(ni->vol, a, ir, ni->mft_no)) {
ntfs_error(vi->i_sb, "Directory index is corrupt.");
goto unm_err_out;
}
@@ -1483,7 +1479,6 @@ static int ntfs_read_locked_index_inode(struct inode *base_vi, struct inode *vi)
struct attr_record *a;
struct ntfs_attr_search_ctx *ctx;
struct index_root *ir;
- u8 *ir_end, *index_end;
int err = 0;
ntfs_debug("Entering for i_ino 0x%llx.", ni->mft_no);
@@ -1534,9 +1529,7 @@ static int ntfs_read_locked_index_inode(struct inode *base_vi, struct inode *vi)
}
ir = (struct index_root *)((u8 *)a + le16_to_cpu(a->data.resident.value_offset));
- ir_end = (u8 *)ir + le32_to_cpu(a->data.resident.value_length);
- index_end = (u8 *)&ir->index + le32_to_cpu(ir->index.index_length);
- if (index_end > ir_end) {
+ if (ntfs_index_root_inconsistent(vol, a, ir, ni->mft_no)) {
ntfs_error(vi->i_sb, "Index is corrupt.");
goto unm_err_out;
}
--
2.43.0
next prev parent reply other threads:[~2026-05-23 4:15 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-23 4:14 [PATCH v2 0/4] ntfs: tighten EA and index metadata validation Hyunchul Lee
2026-05-23 4:14 ` [PATCH v2 1/4] ntfs: validate index block header more strictly Hyunchul Lee
2026-05-23 4:14 ` Hyunchul Lee [this message]
2026-05-23 4:14 ` [PATCH v2 3/4] ntfs: validate index entries on reading Hyunchul Lee
2026-05-23 4:14 ` [PATCH v2 4/4] ntfs: add bounds check before accessing EA entries Hyunchul Lee
2026-05-25 2:56 ` [PATCH v2 0/4] ntfs: tighten EA and index metadata validation Namjae Jeon
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=20260523041423.2726275-3-hyc.lee@gmail.com \
--to=hyc.lee@gmail.com \
--cc=linkinjeon@kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=woot000@woot000.com \
/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