The Linux Kernel Mailing List
 help / color / mirror / Atom feed
* [PATCH v3] ntfs: validate non-resident attribute offsets
@ 2026-08-06  5:57 Hongling Zeng
  2026-08-06 13:17 ` Namjae Jeon
  0 siblings, 1 reply; 3+ messages in thread
From: Hongling Zeng @ 2026-08-06  5:57 UTC (permalink / raw)
  To: linkinjeon, hyc.lee, alexandro.calo
  Cc: ntfs, linux-kernel, zhongling0719, Hongling Zeng, stable

ntfs_attr_update_meta() shifts the attribute name when converting between
non-sparse and sparse attributes. Converting to sparse also adds the
compressed_size field before the name and mapping pairs, requiring eight
additional bytes in the attribute record.

However, the validator does not check that name_offset is within safe
boundaries for these operations or that the additional space is available.
A malicious MFT record could set name_offset such that:

1. The name is positioned at the very end of a non-sparse attribute.
   Converting to sparse would shift the name forward by 8 bytes,
   writing beyond the attribute boundary.

2. The name overlaps with the mapping pairs, causing corruption during
   conversion.

Add validation to ensure:
- For named attributes, name_offset is within valid bounds
- Name does not extend beyond the attribute or overlap with mapping pairs
- For non-sparse, non-compressed attributes, eight bytes are available
  after mapping_pairs_offset for the compressed_size field

The space check also covers unnamed attributes, for which name_offset = 0
is valid and no name range needs to be checked.

Fixes: 7e2a1c554bc4 ("ntfs: Fix min_len for compressed/sparse attributes in ntfs_non_resident_attr_value_is_valid()")
Cc: stable@vger.kernel.org
Signed-off-by: Hongling Zeng <zenghongling@kylinos.cn>
Suggested-by: Namjae Jeon <linkinjeon@kernel.org>
---
Changes in v3:
- Move the sparse conversion space check outside the if (name_length)
  block to cover both named and unnamed attributes.
- Use attr_len - mp_offset < sizeof(compressed_size) to check for
  sufficient room, as suggested by reviewer.
---
 fs/ntfs/attrib.c | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
index d354c3b0fae1..edea3d822b57 100644
--- a/fs/ntfs/attrib.c
+++ b/fs/ntfs/attrib.c
@@ -693,6 +693,8 @@ static bool ntfs_non_resident_attr_value_is_valid(const struct attr_record *a)
 	u32 attr_len;
 	u32 min_len;
 	u16 mp_offset;
+	u16 name_offset;
+	u32 name_end;
 
 	attr_len = le32_to_cpu(a->length);
 	min_len = offsetof(struct attr_record, data.non_resident.initialized_size) +
@@ -706,7 +708,28 @@ static bool ntfs_non_resident_attr_value_is_valid(const struct attr_record *a)
 		return false;
 
 	mp_offset = le16_to_cpu(a->data.non_resident.mapping_pairs_offset);
-	return mp_offset >= min_len && mp_offset <= attr_len;
+	if (mp_offset < min_len || mp_offset > attr_len)
+		return false;
+
+	if (a->name_length) {
+		name_offset = le16_to_cpu(a->name_offset);
+
+		if (name_offset < min_len || name_offset >= attr_len)
+			return false;
+
+		name_end = name_offset + a->name_length * sizeof(__le16);
+		if (name_end > attr_len || name_end > mp_offset)
+			return false;
+	}
+
+	/* Ensure there's room for the compressed_size field if needed. */
+	if (!(a->flags & ATTR_IS_SPARSE) &&
+	    !(a->flags & ATTR_IS_COMPRESSED) &&
+	    attr_len - mp_offset < sizeof(a->data.non_resident.compressed_size))
+		return false;
+
+	return true;
+
 }
 
 static bool ntfs_attr_value_is_valid(struct ntfs_volume *vol,
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v3] ntfs: validate non-resident attribute offsets
  2026-08-06  5:57 [PATCH v3] ntfs: validate non-resident attribute offsets Hongling Zeng
@ 2026-08-06 13:17 ` Namjae Jeon
  2026-08-07  1:55   ` Hongling Zeng
  0 siblings, 1 reply; 3+ messages in thread
From: Namjae Jeon @ 2026-08-06 13:17 UTC (permalink / raw)
  To: Hongling Zeng
  Cc: hyc.lee, alexandro.calo, ntfs, linux-kernel, zhongling0719,
	stable

> +       /* Ensure there's room for the compressed_size field if needed. */
> +       if (!(a->flags & ATTR_IS_SPARSE) &&
> +           !(a->flags & ATTR_IS_COMPRESSED) &&
> +           attr_len - mp_offset < sizeof(a->data.non_resident.compressed_size))
> +               return false;
Sorry for the confusion. I rechecked the code and realized that
ATTR_COMPRESSION_MASK is correct here. It covers the entire
compression field, while ATTR_IS_COMPRESSED checks only the 0x0001
bit. Since this validation checks whether the attribute layout
includes compressed_size, it should use the mask, consistent with the
existing min_len check.  So I have applied the previously attached
patch.

Thanks!

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH v3] ntfs: validate non-resident attribute offsets
  2026-08-06 13:17 ` Namjae Jeon
@ 2026-08-07  1:55   ` Hongling Zeng
  0 siblings, 0 replies; 3+ messages in thread
From: Hongling Zeng @ 2026-08-07  1:55 UTC (permalink / raw)
  To: Namjae Jeon, Hongling Zeng
  Cc: hyc.lee, alexandro.calo, ntfs, linux-kernel, stable


在 2026年08月06日 21:17, Namjae Jeon 写道:
>> +       /* Ensure there's room for the compressed_size field if needed. */
>> +       if (!(a->flags & ATTR_IS_SPARSE) &&
>> +           !(a->flags & ATTR_IS_COMPRESSED) &&
>> +           attr_len - mp_offset < sizeof(a->data.non_resident.compressed_size))
>> +               return false;
> Sorry for the confusion. I rechecked the code and realized that
> ATTR_COMPRESSION_MASK is correct here. It covers the entire
> compression field, while ATTR_IS_COMPRESSED checks only the 0x0001
> bit. Since this validation checks whether the attribute layout
> includes compressed_size, it should use the mask, consistent with the
> existing min_len check.  So I have applied the previously attached
> patch.
>
> Thanks!
You're absolutely correct, Thanks for the guidance and applied the 
patch . I now understand that ATTR_COMPRESSION_MASK
   (0x00ff) is the correct choice—it covers all compression cases, not 
just  the 0x0001 flag.


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-08-07  1:59 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-06  5:57 [PATCH v3] ntfs: validate non-resident attribute offsets Hongling Zeng
2026-08-06 13:17 ` Namjae Jeon
2026-08-07  1:55   ` Hongling Zeng

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox