[PATCH v4 4/6] ntfs: validate resident volume name values on lookup
From: DaeMyung Kang
Date: Sat May 30 2026 - 10:38:30 EST
The shared lookup-time attribute validator now has a safe caller path for
$VOLUME_NAME corruption: ntfs_write_volume_label() no longer treats
lookup errors as an absent label, and the mount path reinitializes its
search context before continuing to $VOLUME_INFORMATION.
Add $VOLUME_NAME-specific resident value validation. A volume name is
stored as a UTF-16LE string, so reject odd byte lengths, and reject
values longer than the NTFS volume label limit. Empty labels remain
valid.
Also reject non-resident $VOLUME_NAME records. $VOLUME_NAME is required
to be resident, like $FILE_NAME; a crafted non-resident record would
otherwise pass lookup and ntfs_write_volume_label() would remove it as if
it were a normal resident attribute.
Signed-off-by: DaeMyung Kang <charsyam@xxxxxxxxx>
---
fs/ntfs/attrib.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
index 98e0b8ea2edd..7e293b85ad19 100644
--- a/fs/ntfs/attrib.c
+++ b/fs/ntfs/attrib.c
@@ -607,6 +607,14 @@ static bool ntfs_file_name_attr_value_is_valid(const u8 *value, const u32 value_
value_length - offsetof(struct file_name_attr, file_name);
}
+static bool ntfs_volume_name_attr_value_is_valid(const u32 value_length)
+{
+ if (value_length & 1)
+ return false;
+
+ return value_length <= NTFS_MAX_LABEL_LEN * sizeof(__le16);
+}
+
struct ntfs_resident_attr_value {
const u8 *data;
u32 len;
@@ -657,7 +665,7 @@ static bool ntfs_attr_value_is_valid(struct ntfs_volume *vol,
u32 min_len;
if (a->non_resident) {
- if (a->type == AT_FILE_NAME)
+ if (a->type == AT_FILE_NAME || a->type == AT_VOLUME_NAME)
goto corrupt;
if (!ntfs_non_resident_attr_value_is_valid(a))
goto corrupt;
@@ -676,6 +684,10 @@ static bool ntfs_attr_value_is_valid(struct ntfs_volume *vol,
if (!ntfs_file_name_attr_value_is_valid(value.data, value.len))
goto corrupt;
break;
+ case AT_VOLUME_NAME:
+ if (!ntfs_volume_name_attr_value_is_valid(value.len))
+ goto corrupt;
+ break;
}
return true;
--
2.43.0