[PATCH] afs: Fix server UAF during peer appdata lookup

Jérémy Jean Jeremy.Jean at oss.cyber.gouv.fr
Tue Nov 3 15:19:30 PST 2026


AF_RXRPC does not take a reference on objects stored in peer appdata, so
afs_find_server() can race with afs_server_destroyer(): it may read an old
server pointer and pass it to afs_use_server() after the object has been
freed through RCU. KASAN reports the UAF as:

  BUG: KASAN: slab-use-after-free in afs_use_server+0x2e/0x250
  Write of size 4 at addr ffff888002b910f0 by task afs-peer-uaf/87

Keep the peer appdata lookup under RCU and use
__refcount_inc_not_zero() to get a server reference before leaving RCU.

Fixes: 40e8b52fe8c8 ("afs: Use the per-peer app data provided by rxrpc")
Cc: stable at vger.kernel.org
Signed-off-by: Jérémy Jean <Jeremy.Jean at oss.cyber.gouv.fr>
---
 fs/afs/server.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/fs/afs/server.c b/fs/afs/server.c
index 189138bd6d712..506119f9b1d32 100644
--- a/fs/afs/server.c
+++ b/fs/afs/server.c
@@ -23,11 +23,21 @@ static void afs_server_destroyer(struct work_struct *work);
  */
 struct afs_server *afs_find_server(const struct rxrpc_peer *peer)
 {
-	struct afs_server *server = (struct afs_server *)rxrpc_kernel_get_peer_data(peer);
+	struct afs_server *server;
+	unsigned int a;
+	int r;
 
-	if (!server)
-		return NULL;
-	return afs_use_server(server, false, afs_server_trace_use_cm_call);
+	rcu_read_lock();
+	server = (struct afs_server *)rxrpc_kernel_get_peer_data(peer);
+	if (server && __refcount_inc_not_zero(&server->ref, &r)) {
+		a = atomic_inc_return(&server->active);
+		trace_afs_server(server->debug_id, r + 1, a,
+				 afs_server_trace_use_cm_call);
+	} else {
+		server = NULL;
+	}
+	rcu_read_unlock();
+	return server;
 }
 
 /*
-- 
2.47.3




More information about the linux-afs mailing list