From nobody Sun May 24 18:41:33 2026 Received: from mail-pl1-f178.google.com (mail-pl1-f178.google.com [209.85.214.178]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 82B1238CFE7 for ; Sun, 24 May 2026 05:42:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.178 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779601368; cv=none; b=mJH6e1sEtqBkzwYdjJxTqwJw92tpxFHkRLSI1nGjiZwhJcs7BggylqYQ1u75dpONIdfVu2CGnQegMQx1nz541/NfjXCSyfekcT1RVAwzL1OQW3ZzhElK6/KMH5IeJsmkfTNDSUgZa0xFm2Obi5Y20mpyd82Np7Y8FAup32dCTiM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779601368; c=relaxed/simple; bh=G9Y04Vr5T7wG0e0exZw7O24VZHQbDNIe+7kN4TkOKKE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lRQneowNuRR2wSxrPeKcLHMf916S5UDE+RYVXFz1pomySXLM2mF2hTprWMvZDVg09gSNvPoli7lsOZ+axJSTW9PetbINp5jZthPjb5WHzcU20KEpgdxPIXNZlQ7VTw1vN/YpGsNIPkkfIL0YDVrhoQZ1ny+rGzhfo3qXONairWY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=XQQI7+Ou; arc=none smtp.client-ip=209.85.214.178 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="XQQI7+Ou" Received: by mail-pl1-f178.google.com with SMTP id d9443c01a7336-2bcee5f0d01so13312175ad.0 for ; Sat, 23 May 2026 22:42:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779601366; x=1780206166; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=meZqVzUjollE5pQHgO4NuBh2AucH33iC2AvQiTWocGU=; b=XQQI7+OudhC48bK0xUwCBtW/fRfD6gU4g5iD8YVP3xzUsyYP0Cfl7jxCjpnPFCvr/Q 66ctAcynCaBoS5FleM4a1FsBke6/FtuVsh6jgZXxFuJJaf+QwSS9YaqnynNQWCZP43z9 oNaNI1lqajSjOh56CYhx/ap6yrjuAy/hcY0xMIrDpx611RXGDV6FkkipkOKoY6qBEgEA sQCHdGntFbb8Bz5gabvE3tUeM/4IjdCp8/kyTzTp0FrZ9MmBQEuujUnbi906RTTuPH5S ep7TAtiT+2JjkvPz+kabzPgYwI1LPyv00GosD7GLqlANw2fFg3fU9rdtViJy88aJOPHZ v+aw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779601366; x=1780206166; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=meZqVzUjollE5pQHgO4NuBh2AucH33iC2AvQiTWocGU=; b=pbVD7wt7z9NDGPUUgdaRzzolMttHqYEU5iMqaMHrSsV7u/PVPaMVSfH1pHPmIcRtfn TW8H4K5M3mgiYGIJtADpX6KLyu05R954Uefk6DvIlIzAtHP7XkDvIq3C5/TxO0204FzD rb2o/MqrM5iCRkuQISEoeopDa0sOWpeoNbPD3sYz3gan/B4lC8aj8KGenkFD9LO27aTb ATa0/u7w6NFFRbSEjslhCgL/RmkIWEA//acIK2gmqZGspIAElmczgSlzT1ez3eu1mY19 fzXykr8YKusPI1dk9uGMM/3W7NU8yEJ3//eI17Nq3HfLPdzV8vz6QFRg2Ab0VmMPffpY 7A7Q== X-Forwarded-Encrypted: i=1; AFNElJ/xYuXL0E7QvxawQ9Fdf4NjuUKWxoWTK31QYS1CR7pTiNQBfwNEuC384izxmxzuH3qbgnafPq9lW/tszek=@vger.kernel.org X-Gm-Message-State: AOJu0YxjZ6nzamq29LlDJak6DtiIHILbz3AyYmiVQzawy6A56xxoqubO 3g64dR5wSI9jYS2h5zWqTQ6pCupTW4Ea7hc1mle1BMUFLDNNCJdD7E49C1YqFw== X-Gm-Gg: Acq92OGXhXSbXXA/ykbXNtV0lV6SiqVchuDmuIPFmyWwuJ4ZZwxAlSISR0BkMrZ+fD7 T3M99t3CYGQONHvlxZq7vUZUuOUJ9P/f2SPyephws/9AENvqYCDPl88KuI9yYiYgqVILH0OSA0H FQUkmnRzn0+KLeSe3IKYqFOZmQ9thdA2DTrkVFozVt8kGiS1ebkyKRLQwR/DJIdTWvwoMCedt8/ do5F3SiwuHhbblK4bCoi3gz6IeCe7i4YPjXyYq4itgAXaxePn3dH8P3Zed5sT95V54qGMbZ0vhT 609XK5XE1pjYJee2qEOC6Xfr/nqMQV4UxrG8/bsnvRgU3qAJkGi4XZlCaBSqNmFpPvyk9P+75sH xxqkgXIkUYMXCWSFgOaBRpx7Y/f5Cp5Pu125su36AbUMvF5KqjZbDc/VztzinCy3qt2FKkJk4th D4zFjXBD6kt+6fF4+5 X-Received: by 2002:a05:6a00:2d83:b0:835:36f2:7332 with SMTP id d2e1a72fcca58-8415f0d7b2dmr5242919b3a.2.1779601366503; Sat, 23 May 2026 22:42:46 -0700 (PDT) Received: from ser8.. ([221.156.231.192]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-84164ff7d80sm6726848b3a.56.2026.05.23.22.42.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 23 May 2026 22:42:45 -0700 (PDT) From: DaeMyung Kang To: Namjae Jeon , Hyunchul Lee Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, DaeMyung Kang Subject: [PATCH 1/2] ntfs: free link name from ntfs_name_cache Date: Sun, 24 May 2026 14:42:37 +0900 Message-ID: <20260524054238.3129288-2-charsyam@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260524054238.3129288-1-charsyam@gmail.com> References: <20260524054238.3129288-1-charsyam@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" ntfs_link() converts the new link name with ntfs_nlstoucs() using NTFS_MAX_NAME_LEN. In this case ntfs_nlstoucs() allocates the result from ntfs_name_cache, and its contract requires callers to release the buffer with kmem_cache_free(ntfs_name_cache, ...). All other ntfs_nlstoucs() callers in namei.c do that, but ntfs_link() uses kfree(), which mismatches the allocator for successfully converted names. The conversion failure path reaches the common out label with uname =3D=3D NULL. That was harmless for kfree(), but kmem_cache_free() does not provide the same NULL contract. Return directly on conversion failure and free successful conversions with ntfs_name_cache. Fixes: af0db57d4293 ("ntfs: update inode operations") Signed-off-by: DaeMyung Kang --- fs/ntfs/namei.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/fs/ntfs/namei.c b/fs/ntfs/namei.c index c4f82846c58c..9c1c36acfad2 100644 --- a/fs/ntfs/namei.c +++ b/fs/ntfs/namei.c @@ -1532,8 +1532,7 @@ static int ntfs_link(struct dentry *old_dentry, struc= t inode *dir, if (uname_len < 0) { if (uname_len !=3D -ENAMETOOLONG) ntfs_error(sb, "Failed to convert name to unicode."); - err =3D -ENOMEM; - goto out; + return -ENOMEM; } =20 if (!(vol->vol_flags & VOLUME_IS_DIRTY)) @@ -1563,7 +1562,7 @@ static int ntfs_link(struct dentry *old_dentry, struc= t inode *dir, mutex_unlock(&ni->mrec_lock); =20 out: - kfree(uname); + kmem_cache_free(ntfs_name_cache, uname); return err; } =20 --=20 2.43.0 From nobody Sun May 24 18:41:33 2026 Received: from mail-pf1-f181.google.com (mail-pf1-f181.google.com [209.85.210.181]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 38CA738D007 for ; Sun, 24 May 2026 05:42:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779601371; cv=none; b=ZXatLQjS+pKamLddhSqVFyOx9yqQ4KxpvgKtLd9xiKaiwd8t4cWspNuuJDr8i8LPJ0aXNBEN9wyk9iNvcjHw3tXwemr+1H6QeL4X7y30KLOhMwcDWCcBpyGhSV0pST4y0/i15BrSqBluZcjLlLQJkRRQdFCeEnfrv1R5lVza1NY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779601371; c=relaxed/simple; bh=dd8kh+7Dnfu3DNvlUlRWZjRhDr8HIGBBzmgPH10vHtA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=on/yPCGvYvYVbhcnZ3+lbH09huWWXWJUDZOeMXsE5LyLlhal+bFo7cBUQstOFv4CD4Z83zNznLAhGCo4vHRQsQxMypkeVMFqkfkCZh4S0yZM82bAvp/MmDVqdk23nReyCwX9OdKN90tBPbRu7Wc6C5H1JXHgRBFAYVAJfl/asec= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=BoYsvvOA; arc=none smtp.client-ip=209.85.210.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="BoYsvvOA" Received: by mail-pf1-f181.google.com with SMTP id d2e1a72fcca58-83dc08db8e0so488369b3a.3 for ; Sat, 23 May 2026 22:42:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779601369; x=1780206169; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=P0f8FTEg8jprF2Xg1CZCQ7/4fR2DvKFq//GzNUFZM4k=; b=BoYsvvOAUO2GhQbLwrLBf7BxzWN0gbWKwooDstu0hc6ghHCsbxGs/6iqgSDMzp9gw5 QYihei2+XPnLTKBZdZE0fLpF6WagRPAGt29O7IE/98Uj6KN15nNkPKZb/2Rnf6LbZIhy W9+RPNVx/4xCP9UIdR1vWoQW0K9GUYbhAHW57MYMacGkzz7dWABgHfaQWrqgl1qmgoBv 0VFkpw53EQWel3uiaYff/63R0m1NY6phZ7YZSX8RZZ2MJveYelGoTLTEVFgO/S1Eo1Es UfxLY+L72dn2UghBA3FJR0v5P5N9Rl0qZUbiaE28+OECgAN5TeyXo9vU8FRHpKZD5L8h KpBQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779601369; x=1780206169; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=P0f8FTEg8jprF2Xg1CZCQ7/4fR2DvKFq//GzNUFZM4k=; b=Cc2nEMlsxxzL+bHkKeTbv7eOwV5fD0os1xJqbyNZTAeWgYVIbxBL5sIK9kNEAMIasi a7FmLwFpHxGcSCQt9OdQHD6ctFFZM/L/kt2L390cD/Fv8Z72++8BUvRukGN40wRpDPmH yv4RL+sbrewUZyejGZTBq+Q172WcssRyVaO9/n964Ejmot1hq5vjciEW/JVAc0v10mt8 J3gI9uDLuZgwxrJyaD8/9VqlQUuZY0MBPaPWlgXQNobHDMMWX12Gn+znFFvcxvuyaYnJ +4w0Qna5fwx6BOqsls+0Ld7s0NFU/zCEwxUhV0g488AZCCqu7SrTt7e7FjelA2Y908ok 88Pw== X-Forwarded-Encrypted: i=1; AFNElJ/BcQmEa8YBff8EUcigpuhpZF/KazGI9yV5hgty0GyRnpR0WLhMQFYpH8wKarzm5Zi3zFF50lG7rTTH3Go=@vger.kernel.org X-Gm-Message-State: AOJu0YwfNUPk/9/D61JD0qhnUJmu2zBQXDF32bUXJKl1Od6rsYiYEY/I 5yGAcbnZHxBDmcrGpeLZb6kolsuXLI6BgjuyYECIN5nsB3GolyYX61Lp X-Gm-Gg: Acq92OEzvJInVAiKkr9I75toXVfQdfGztbaI7UjaO2qudlYTJDtZxQbvrJbTXmrFEZ+ KQgrEm6vvLGNyqYcigETru6PXmu5zy0JPWHCKo9hmzMFIPBsMYJrwjO+MH/lc6Pfob+AVPJUeJF ++NSUhhaVUybBokyJjqy00X5F/JfDciV7lIPE0xrHAyxZUfCSjcAPtiFnCRBncdUDO4qWZzIcFf /7Ci1RN+cSRClHFg+FaVJi7/WTFmtagZN5ooW91uWE9I2g0NG95LxoDC7jfguV++9iNgx0A1Ip/ 7JCG7qfte+p90SogMIoeyAlxLQBpBX/a0WUBfM1QinxTBWQcDg2WHZsIOW+qDWRxYKt4i5GJJrP mhBL5dNkWJHplE6arm8Hyj+KJGxd8Hwt9igllsEjdy5KBwdpPL3V1oy38ZNQD8ibtHJYAw4N/CT I7NV/KJNi/TuMFUg9D X-Received: by 2002:a05:6a00:1908:b0:82f:6cd5:f6ff with SMTP id d2e1a72fcca58-8415f385903mr4788574b3a.7.1779601369368; Sat, 23 May 2026 22:42:49 -0700 (PDT) Received: from ser8.. ([221.156.231.192]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-84164ff7d80sm6726848b3a.56.2026.05.23.22.42.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 23 May 2026 22:42:48 -0700 (PDT) From: DaeMyung Kang To: Namjae Jeon , Hyunchul Lee Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, DaeMyung Kang Subject: [PATCH 2/2] ntfs: validate resident file name attribute length Date: Sun, 24 May 2026 14:42:38 +0900 Message-ID: <20260524054238.3129288-3-charsyam@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260524054238.3129288-1-charsyam@gmail.com> References: <20260524054238.3129288-1-charsyam@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" ntfs_attr_find() and ntfs_external_attr_find() check that generic resident attribute values fit in their attribute records and that fixed-size resident values are large enough. For $FILE_NAME, however, the fixed part is not enough: the value also contains a variable-length UTF-16 name whose length is stored in file_name_length. A crafted image can set a small resident value_length while leaving file_name_length large. Callers then trust file_name_length and read past the resident value when converting or comparing the name. This was reproduced with a crafted image under KASAN as a slab-out-of-bounds read from the kmalloc-1k MFT record copy, for example through: ntfs_lookup() ntfs_iget() ntfs_read_locked_inode() ntfs_attr_name_get() ntfs_ucstonls() utf16s_to_utf8s() Validate $FILE_NAME before lookup can return the current attribute, including the AT_UNUSED enumeration case where callers inspect returned attributes directly. Reuse the same self-contained helper for both the base-record lookup path and the attribute-list lookup path. Log a specific corruption message at the rejection point, matching the existing attribute-name validation in ntfs_attr_find(). Reject non-resident $FILE_NAME records too: the format requires $FILE_NAME to be resident and callers treat returned records as resident. Fixes: 6ceb4cc81ef3 ("ntfs: add bound checking to ntfs_attr_find") Signed-off-by: DaeMyung Kang --- fs/ntfs/attrib.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c index 421c6cdcbb53..5643a097eb11 100644 --- a/fs/ntfs/attrib.c +++ b/fs/ntfs/attrib.c @@ -595,6 +595,37 @@ static u32 ntfs_resident_attr_min_value_length(const _= _le32 type) } } =20 +static bool ntfs_file_name_attr_is_valid(const struct attr_record *a) +{ + const struct file_name_attr *fn; + u32 attr_len =3D le32_to_cpu(a->length); + u32 value_length; + u16 value_offset; + u32 file_name_size; + + if (a->non_resident) + return false; + + if (attr_len < offsetof(struct attr_record, data.resident.reserved) + + sizeof(a->data.resident.reserved)) + return false; + + value_length =3D le32_to_cpu(a->data.resident.value_length); + value_offset =3D le16_to_cpu(a->data.resident.value_offset); + + if (value_length > attr_len || value_offset > attr_len - value_length) + return false; + + if (value_length < ntfs_resident_attr_min_value_length(AT_FILE_NAME)) + return false; + + fn =3D (const struct file_name_attr *)((const u8 *)a + value_offset); + file_name_size =3D fn->file_name_length * sizeof(__le16); + + return file_name_size <=3D + value_length - offsetof(struct file_name_attr, file_name); +} + /* * ntfs_attr_find - find (next) attribute in mft record * @type: attribute type to find @@ -705,6 +736,13 @@ static int ntfs_attr_find(const __le32 type, const __l= e16 *name, } } =20 + if (a->type =3D=3D AT_FILE_NAME && + !ntfs_file_name_attr_is_valid(a)) { + ntfs_error(vol->sb, + "Corrupt $FILE_NAME attribute in MFT record %llu\n", + ctx->ntfs_ino->mft_no); + break; + } if (type =3D=3D AT_UNUSED) return 0; if (a->type !=3D type) @@ -1252,6 +1290,14 @@ static int ntfs_external_attr_find(const __le32 type, =20 ctx->attr =3D a; =20 + if (a->type =3D=3D AT_FILE_NAME && + !ntfs_file_name_attr_is_valid(a)) { + ntfs_error(vol->sb, + "Corrupt $FILE_NAME attribute in MFT record %llu\n", + ctx->ntfs_ino->mft_no); + break; + } + if (a->non_resident) { u32 min_len; u16 mp_offset; --=20 2.43.0