From: Sasha Levin <sashal@kernel.org>
To: stable@vger.kernel.org
Cc: Christian Brauner <brauner@kernel.org>, Sasha Levin <sashal@kernel.org>
Subject: [PATCH 6.18.y 4/4] ntfs3: free the sbi after a grace period
Date: Wed, 21 Oct 2026 11:30:33 -0400 [thread overview]
Message-ID: <20261021152930.293677-4-sashal@kernel.org> (raw)
In-Reply-To: <20261021152930.293677-1-sashal@kernel.org>
From: Christian Brauner <brauner@kernel.org>
[ Upstream commit c01b091b06412d3b1b53d8c2925f6de586c8a2fc ]
If the "nocase" mount option ntfs3 uses custom hash and dentry compare
functions. Both access ntfs3 superblock private information in rcu
pathwalk. ntfs_put_super() and ntfs3_kill_sb() drop the info without any
rcu delay. A lookup that's still inside the filesystem when the last
reference to the mount is dropped causes a UAF. With a pathwalk held up
in ntfs_d_hash() while the last reference to the mount goes away:
BUG: KASAN: slab-use-after-free in ntfs_nls_to_utf16+0x752/0x940
Read of size 8 at addr ff1100010453c850 by task walker/99
Call Trace:
<TASK>
ntfs_nls_to_utf16+0x752/0x940
ntfs_d_hash+0x22b/0x500
link_path_walk+0x11ad/0x1d30
path_lookupat+0x63/0xb00
filename_lookup+0x1f1/0x5b0
vfs_statx+0xd7/0x3b0
[...]
Allocated by task 95:
__kmalloc_cache_noprof+0x249/0x560
ntfs_init_fs_context+0x2db/0x5a0
alloc_fs_context+0x52e/0xc70
[...]
Freed by task 98:
kfree+0x1db/0x5b0
deactivate_locked_super+0x9c/0xf0
cleanup_mnt+0x9f/0x130
task_work_run+0x131/0x250
The bug is currently masked by the grace period in namespace_unlock()
for umount(2). Keep the necessary information until the filesystem
private info is freed and free it with an rcu delay.
ntfs3_free_sbi() now runs from an rcu callback and drops the upcase
table via ntfs_put_shared(). So switch s_shared_lock over to
spin_lock_bh(). Otherwise the callback can deadlock against a task
holding the lock on the same cpu.
Fixes: a3a956c78efa ("fs/ntfs3: Add option "nocase"")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20261009-work-fixes-rcu-v1-7-7446d2d335e6@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ntfs3/ntfs_fs.h | 1 +
fs/ntfs3/super.c | 33 +++++++++++++++++++++------------
2 files changed, 22 insertions(+), 12 deletions(-)
diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h
index 99a78204b9865..9cacca3397055 100644
--- a/fs/ntfs3/ntfs_fs.h
+++ b/fs/ntfs3/ntfs_fs.h
@@ -209,6 +209,7 @@ struct ntfs_index {
/* Ntfs file system in-core superblock data. */
struct ntfs_sb_info {
struct super_block *sb;
+ struct rcu_head rcu;
u32 discard_granularity;
u64 discard_granularity_mask_inv; // ~(discard_granularity_mask_inv-1)
diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c
index 558f96db9019c..dc799ebc6c883 100644
--- a/fs/ntfs3/super.c
+++ b/fs/ntfs3/super.c
@@ -194,7 +194,7 @@ void *ntfs_set_shared(void *ptr, u32 bytes)
void *ret = NULL;
int i, j = -1;
- spin_lock(&s_shared_lock);
+ spin_lock_bh(&s_shared_lock);
for (i = 0; i < ARRAY_SIZE(s_shared); i++) {
if (!s_shared[i].cnt) {
j = i;
@@ -212,7 +212,7 @@ void *ntfs_set_shared(void *ptr, u32 bytes)
s_shared[j].cnt = 1;
ret = ptr;
}
- spin_unlock(&s_shared_lock);
+ spin_unlock_bh(&s_shared_lock);
return ret;
}
@@ -229,7 +229,7 @@ void *ntfs_put_shared(void *ptr)
void *ret = ptr;
int i;
- spin_lock(&s_shared_lock);
+ spin_lock_bh(&s_shared_lock);
for (i = 0; i < ARRAY_SIZE(s_shared); i++) {
if (s_shared[i].cnt && s_shared[i].ptr == ptr) {
if (--s_shared[i].cnt)
@@ -237,7 +237,7 @@ void *ntfs_put_shared(void *ptr)
break;
}
}
- spin_unlock(&s_shared_lock);
+ spin_unlock_bh(&s_shared_lock);
return ret;
}
@@ -684,6 +684,8 @@ static noinline void ntfs3_put_sbi(struct ntfs_sb_info *sbi)
static void ntfs3_free_sbi(struct ntfs_sb_info *sbi)
{
+ if (sbi->options)
+ put_mount_options(sbi->options);
kfree(sbi->new_rec);
kvfree(ntfs_put_shared(sbi->upcase));
kvfree(sbi->def_table);
@@ -695,6 +697,11 @@ static void ntfs3_free_sbi(struct ntfs_sb_info *sbi)
kfree(sbi);
}
+static void ntfs3_free_sbi_rcu(struct rcu_head *head)
+{
+ ntfs3_free_sbi(container_of(head, struct ntfs_sb_info, rcu));
+}
+
static void ntfs_put_super(struct super_block *sb)
{
struct ntfs_sb_info *sbi = sb->s_fs_info;
@@ -704,11 +711,11 @@ static void ntfs_put_super(struct super_block *sb)
/* Mark rw ntfs as clear, if possible. */
ntfs_set_state(sbi, NTFS_DIRTY_CLEAR);
- if (sbi->options) {
- put_mount_options(sbi->options);
- sbi->options = NULL;
- }
-
+ /*
+ * The mount options stay until the sbi is freed: ->d_hash() and
+ * ->d_compare() of a pathwalk in rcu mode read the nls table through
+ * them.
+ */
ntfs3_put_sbi(sbi);
}
@@ -1865,9 +1872,11 @@ static void ntfs3_kill_sb(struct super_block *sb)
kill_block_super(sb);
- if (sbi->options)
- put_mount_options(sbi->options);
- ntfs3_free_sbi(sbi);
+ /*
+ * A pathwalk in rcu mode may still be in ->d_hash() or ->d_compare()
+ * and read the upcase table and the nls table through the sbi.
+ */
+ call_rcu(&sbi->rcu, ntfs3_free_sbi_rcu);
}
// clang-format off
--
2.53.0
prev parent reply other threads:[~2026-10-21 15:30 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-21 14:38 FAILED: patch "[PATCH] ntfs3: free the sbi after a grace period" failed to apply to 6.18-stable tree gregkh
2026-10-21 15:30 ` [PATCH 6.18.y 1/4] ntfs3: fix use-after-free of sbi->options in cmp_fnames Sasha Levin
2026-10-21 15:30 ` [PATCH 6.18.y 2/4] ntfs3: fix double free of sbi->options->nls and clarify ownership of fc->fs_private Sasha Levin
2026-10-21 15:30 ` [PATCH 6.18.y 3/4] fs/ntfs3: fix ntfs_mount_options leak in ntfs_fill_super() Sasha Levin
2026-10-21 15:30 ` Sasha Levin [this message]
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=20261021152930.293677-4-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=brauner@kernel.org \
--cc=stable@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.