]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ntfs: validate resident volume name values on lookup
authorDaeMyung Kang <charsyam@gmail.com>
Sat, 30 May 2026 14:35:12 +0000 (23:35 +0900)
committerNamjae Jeon <linkinjeon@kernel.org>
Fri, 5 Jun 2026 15:20:38 +0000 (00:20 +0900)
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.

Cc: stable@vger.kernel.org # v7.1
Signed-off-by: DaeMyung Kang <charsyam@gmail.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
fs/ntfs/attrib.c

index 71704ab58fa8909a0ffb10e5c3b05ecdce124b19..5e1ad1cd01186525dc546501b05569ba73fdcdd4 100644 (file)
@@ -608,6 +608,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;
@@ -658,7 +666,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;
@@ -677,6 +685,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;