From: DaeMyung Kang <charsyam@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
Subject: [PATCH 3/3] ntfs: validate attribute name bounds before returning it
Date: Sat, 9 May 2026 00:34:10 +0900 [thread overview]
Message-ID: <20260508153410.2624801-4-charsyam@gmail.com> (raw)
In-Reply-To: <20260508153410.2624801-1-charsyam@gmail.com>
ntfs_attr_find() validates a named attribute before comparing it with the
requested name, but that check is currently after the AT_UNUSED handling.
When callers enumerate attributes with AT_UNUSED, ntfs_attr_find() can
return a malformed named attribute before checking whether name_offset
and name_length stay within the attribute record.
Some enumeration callers use the returned attribute name pointer
directly. For example, one path passes (attr + name_offset, name_length)
to ntfs_attr_iget(), where the name can later be copied according to
name_length. A malformed on-disk name_offset/name_length pair should not
be exposed to those callers.
Move the existing name bounds validation before returning attributes
during AT_UNUSED enumeration, and write it as an offset/remaining-size
check so the subtraction cannot underflow. Extract the converted values
into local variables (name_offset, attr_len, name_size) to make the
intent explicit and avoid repeating the endian conversions inside the
bounds check. This keeps matching attributes on the same checked path
while also covering attribute enumeration.
A small userspace ASAN model with attr length=32, name_offset=124 and
name_length=8 reproduces a heap-buffer-overflow read in the old
enumeration path. With this change the same malformed attribute is
rejected before the name pointer is returned to the caller.
Fixes: d3ad708fecaa ("ntfs: Initial commit")
Signed-off-by: DaeMyung Kang <charsyam@gmail.com>
---
fs/ntfs/attrib.c | 25 +++++++++++++++++--------
1 file changed, 17 insertions(+), 8 deletions(-)
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
index 330127975b26..f51917b4a494 100644
--- a/fs/ntfs/attrib.c
+++ b/fs/ntfs/attrib.c
@@ -675,6 +675,9 @@ static int ntfs_attr_find(const __le32 type, const __le16 *name,
__le16 *upcase = vol->upcase;
u32 upcase_len = vol->upcase_len;
unsigned int space;
+ u16 name_offset;
+ u32 attr_len;
+ u32 name_size;
/*
* Iterate over attributes in mft record starting at @ctx->attr, or the
@@ -702,6 +705,20 @@ static int ntfs_attr_find(const __le32 type, const __le16 *name,
return -ENOENT;
if (unlikely(!a->length))
break;
+ if (a->name_length) {
+ name_offset = le16_to_cpu(a->name_offset);
+ attr_len = le32_to_cpu(a->length);
+ name_size = a->name_length * sizeof(__le16);
+
+ if (name_offset > attr_len ||
+ attr_len - name_offset < name_size) {
+ ntfs_error(vol->sb,
+ "Corrupt attribute name in MFT record %llu\n",
+ ctx->ntfs_ino->mft_no);
+ break;
+ }
+ }
+
if (type == AT_UNUSED)
return 0;
if (a->type != type)
@@ -715,14 +732,6 @@ static int ntfs_attr_find(const __le32 type, const __le16 *name,
if (a->name_length)
return -ENOENT;
} else {
- if (a->name_length && ((le16_to_cpu(a->name_offset) +
- a->name_length * sizeof(__le16)) >
- le32_to_cpu(a->length))) {
- ntfs_error(vol->sb, "Corrupt attribute name in MFT record %llu\n",
- ctx->ntfs_ino->mft_no);
- break;
- }
-
if (!ntfs_are_names_equal(name, name_len,
(__le16 *)((u8 *)a + le16_to_cpu(a->name_offset)),
a->name_length, ic, upcase, upcase_len)) {
--
2.34.1
next prev parent reply other threads:[~2026-05-08 15:34 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-08 15:34 [PATCH 0/3] ntfs: harden MFT record and attribute parsing DaeMyung Kang
2026-05-08 15:34 ` [PATCH 1/3] ntfs: validate MFT attrs_offset against bytes_in_use DaeMyung Kang
2026-05-08 15:34 ` [PATCH 2/3] ntfs: fix MFT bitmap scan 2^32 boundary check DaeMyung Kang
2026-05-09 4:03 ` Namjae Jeon
2026-05-09 6:14 ` CharSyam
2026-05-08 15:34 ` DaeMyung Kang [this message]
2026-05-09 6:12 ` [PATCH v2 0/3] ntfs: harden MFT record and attribute parsing DaeMyung Kang
2026-05-09 15:44 ` Namjae Jeon
2026-05-09 6:12 ` [PATCH v2 1/3] ntfs: validate MFT attrs_offset against bytes_in_use DaeMyung Kang
2026-05-09 6:12 ` [PATCH v2 2/3] ntfs: fix MFT bitmap scan 2^32 boundary check DaeMyung Kang
2026-05-09 6:12 ` [PATCH v2 3/3] ntfs: validate attribute name bounds before returning it DaeMyung Kang
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=20260508153410.2624801-4-charsyam@gmail.com \
--to=charsyam@gmail.com \
--cc=hyc.lee@gmail.com \
--cc=linkinjeon@kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
/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