* [PATCH v2] NFS: defer access-cache entry and group_info free past RCU
@ 2026-10-26 10:52 Cheng Yongkang
0 siblings, 0 replies; only message in thread
From: Cheng Yongkang @ 2026-10-26 10:52 UTC (permalink / raw)
To: Trond Myklebust, Anna Schumaker; +Cc: linux-nfs, linux-kernel, stable
nfs_access_free_entry() drops the group_info reference synchronously
while the nfs_access_entry itself is only freed after an RCU grace
period. The lockless lookup path (nfs_access_get_cached_rcu() ->
access_cmp()) can still be walking group_info->ngroups/gid[] after the
entry was replaced and unlinked, so put_group_info() can reach
groups_free() -> kvfree() under a reader and free the array it is
reading: a slab-use-after-free read.
put_group_info() may end in kvfree(), so it cannot run from a plain RCU
callback. Defer both the group_info reference drop and the entry free
to process context after a grace period with queue_rcu_work() on
nfsiod_workqueue. The entry accounting (nfs_access_nr_entries) and all
call-site locking are unchanged; the work only drops the reference and
frees the entry.
On a 7.3 KASAN kernel, the following workload triggers the report: a
userspace NFSv3 server plus eight readers doing faccessat() with 2048
supplementary gids, and serialized credential replacements that detach
the previous killer's group_info reference.
BUG: KASAN: use-after-free in nfs_access_get_cached+0xb8f/0xf80
Read of size 4 at addr ... by task poc/9552
Call Trace:
nfs_access_get_cached
nfs_do_access
nfs_permission
inode_permission
do_faccessat
Page last allocated by task ...:
__kvmalloc_node_noprof
__se_sys_setgroups
Page last freed by task ...:
nfs_access_free_entry
nfs_access_add_cache
nfs_do_access
The trigger needs CAP_SETGID in the guest for the setgroups-based
credential churn; the faulty read path is the ordinary access(2) /
faccessat(2) path used by any NFS user.
Link: https://lore.kernel.org/all/20261025180329.349613-1-teel4res@gmail.com/
Fixes: 6238aec83f3f ("NFS: don't store 'struct cred *' in struct nfs_access_entry")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Cheng Yongkang <teel4res@gmail.com>
---
v2: add Link, Fixes and stable tags, and remove local validation details from the
commit message.
fs/nfs/dir.c | 21 +++++++++++++++++----
include/linux/nfs_fs.h | 3 ++-
2 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -2898,10 +2898,25 @@
module_param(nfs_access_max_cachesize, ulong, 0644);
MODULE_PARM_DESC(nfs_access_max_cachesize, "NFS access maximum total cache length");
-static void nfs_access_free_entry(struct nfs_access_entry *entry)
+static void nfs_access_free_entry_work(struct work_struct *work)
{
+ struct nfs_access_entry *entry =
+ container_of(to_rcu_work(work), struct nfs_access_entry, rcu_work);
+
put_group_info(entry->group_info);
- kfree_rcu(entry, rcu_head);
+ kfree(entry);
+}
+
+static void nfs_access_free_entry(struct nfs_access_entry *entry)
+{
+ /*
+ * The entry can still be reached by RCU readers that dereference
+ * its group_info in access_cmp(). Drop the group_info reference
+ * only after a grace period, in process context because
+ * put_group_info() may end in kvfree().
+ */
+ INIT_RCU_WORK(&entry->rcu_work, nfs_access_free_entry_work);
+ queue_rcu_work(nfsiod_workqueue, &entry->rcu_work);
smp_mb__before_atomic();
atomic_long_dec(&nfs_access_nr_entries);
smp_mb__after_atomic();
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -26,6 +26,7 @@
#include <linux/refcount.h>
#include <linux/rwsem.h>
#include <linux/wait.h>
+#include <linux/workqueue.h>
#include <linux/sunrpc/debug.h>
#include <linux/sunrpc/auth.h>
@@ -65,7 +66,7 @@
struct group_info *group_info;
u64 timestamp;
__u32 mask;
- struct rcu_head rcu_head;
+ struct rcu_work rcu_work;
};
struct nfs_lock_context {
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-10-26 10:52 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-26 10:52 [PATCH v2] NFS: defer access-cache entry and group_info free past RCU Cheng Yongkang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®