[PATCH] net: sunrpc: fix null-ptr-deref Read in xprt_reserve
From: Drif Abdelmalek Mohamed Said
Date: Fri Oct 16 2026 - 16:19:09 EST
syzbot reported:
BUG: KASAN: null-ptr-deref in instrument_atomic_read
include/linux/instrumented.h:82 [inline]
BUG: KASAN: null-ptr-deref in _test_bit
include/asm-generic/bitops/instrumented-non-atomic.h:141 [inline]
BUG: KASAN: null-ptr-deref in xprt_throttle_congested
net/sunrpc/xprt.c:1708 [inline]
BUG: KASAN: null-ptr-deref in xprt_reserve+0xe2/0x2c0 net/sunrpc/xprt.c:1948
Read of size 8 at addr 0000000000000628 by task syz.8.3118/20390
Call Trace:
<TASK>
dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120
kasan_report+0x117/0x150 mm/kasan/report.c:595
check_region_inline mm/kasan/generic.c:-1 [inline]
kasan_check_range+0x264/0x2c0 mm/kasan/generic.c:200
instrument_atomic_read include/linux/instrumented.h:82 [inline]
_test_bit include/asm-generic/bitops/instrumented-non-atomic.h:141 [inline]
xprt_throttle_congested net/sunrpc/xprt.c:1708 [inline]
xprt_reserve+0xe2/0x2c0 net/sunrpc/xprt.c:1948
__rpc_execute+0x526/0x1280 net/sunrpc/sched.c:947
rpc_execute+0x1c1/0x390 net/sunrpc/sched.c:1023
rpc_run_task+0x4a6/0x660 net/sunrpc/clnt.c:1269
rpc_ping_noreply net/sunrpc/clnt.c:2944 [inline]
rpc_create_xprt+0x452/0xa90 net/sunrpc/clnt.c:494
rpc_create+0x649/0x900 net/sunrpc/clnt.c:619
gssp_rpc_create net/sunrpc/auth_gss/gss_rpc_upcall.c:107 [inline]
set_gssp_clnt+0x188/0x2d0 net/sunrpc/auth_gss/gss_rpc_upcall.c:131
write_gssp+0x21e/0x310 net/sunrpc/auth_gss/svcauth_gss.c:1423
pde_write fs/proc/inode.c:330 [inline]
proc_reg_write+0x1e9/0x2e0 fs/proc/inode.c:342
vfs_write+0x296/0xba0 fs/read_write.c:685
ksys_write+0x150/0x270 fs/read_write.c:739
do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
do_syscall_64+0x166/0x520 arch/x86/entry/syscall_64.c:84
entry_SYSCALL_64_after_hwframe+0x77/0x7f
The GSS proxy client setup races with sysfs. xprt_switch_alloc() publishes
the transport in sysfs before rpc_new_client() sets xprt->main = true. The
sysfs offline handler rejects writes when main is already true, so
userspace can set XPRT_OFFLINE in that window.
The initial RPC then runs with the only transport offline.
xprt_is_active() only rejects a transport whose refcount is zero
or whose XPRT_OFFLINE bit is set, and a transport that is still on the switch's
list always holds a reference.
xprt_switch_find_first_entry() returns NULL, rpc_task_get_next_xprt()
returns NULL with it, and since rpc_task_set_transport() returns void,
the task continues with tk_xprt == NULL until xprt_reserve() dereferences it.
Mark the first transport as main in xprt_switch_alloc() before creating the
sysfs entries, and drop the assignment from rpc_new_client().
Fixes: e091853ebdb4 ("SUNRPC mark the first transport")
Reported-by: syzbot+ae55a0fac80c73c938ac@xxxxxxxxxxxxxxxxxxxxxxxxx
Closes: https://syzkaller.appspot.com/bug?extid=ae55a0fac80c73c938ac
Signed-off-by: Drif Abdelmalek Mohamed Said <drifabdelmalekmohamedsaid@xxxxxxxxx>
---
net/sunrpc/clnt.c | 1 -
net/sunrpc/xprtmultipath.c | 1 +
2 files changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 6cedc824cf82..aa9f9c185c02 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -419,7 +419,6 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args,
}
rpc_clnt_set_transport(clnt, xprt, timeout);
- xprt->main = true;
xprt_iter_init(&clnt->cl_xpi, xps);
xprt_switch_put(xps);
diff --git a/net/sunrpc/xprtmultipath.c b/net/sunrpc/xprtmultipath.c
index 3ba818d637be..5e2d43d6c643 100644
--- a/net/sunrpc/xprtmultipath.c
+++ b/net/sunrpc/xprtmultipath.c
@@ -159,6 +159,7 @@ struct rpc_xprt_switch *xprt_switch_alloc(struct rpc_xprt *xprt,
atomic_long_set(&xps->xps_queuelen, 0);
xps->xps_net = NULL;
INIT_LIST_HEAD(&xps->xps_xprt_list);
+ xprt->main = true;
xps->xps_iter_ops = &rpc_xprt_iter_singular;
rpc_sysfs_xprt_switch_setup(xps, xprt, gfp_flags);
xprt_switch_add_xprt_locked(xps, xprt);
--
2.43.0