linux/net/sunrpc
Liu Jian 0ca87e5063 sunrpc: fix one UAF issue caused by sunrpc kernel tcp socket
[ Upstream commit 3f23f96528 ]

BUG: KASAN: slab-use-after-free in tcp_write_timer_handler+0x156/0x3e0
Read of size 1 at addr ffff888111f322cd by task swapper/0/0

CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.12.0-rc4-dirty #7
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1
Call Trace:
 <IRQ>
 dump_stack_lvl+0x68/0xa0
 print_address_description.constprop.0+0x2c/0x3d0
 print_report+0xb4/0x270
 kasan_report+0xbd/0xf0
 tcp_write_timer_handler+0x156/0x3e0
 tcp_write_timer+0x66/0x170
 call_timer_fn+0xfb/0x1d0
 __run_timers+0x3f8/0x480
 run_timer_softirq+0x9b/0x100
 handle_softirqs+0x153/0x390
 __irq_exit_rcu+0x103/0x120
 irq_exit_rcu+0xe/0x20
 sysvec_apic_timer_interrupt+0x76/0x90
 </IRQ>
 <TASK>
 asm_sysvec_apic_timer_interrupt+0x1a/0x20
RIP: 0010:default_idle+0xf/0x20
Code: 4c 01 c7 4c 29 c2 e9 72 ff ff ff 90 90 90 90 90 90 90 90 90 90 90 90
 90 90 90 90 f3 0f 1e fa 66 90 0f 00 2d 33 f8 25 00 fb f4 <fa> c3 cc cc cc
 cc 66 66 2e 0f 1f 84 00 00 00 00 00 90 90 90 90 90
RSP: 0018:ffffffffa2007e28 EFLAGS: 00000242
RAX: 00000000000f3b31 RBX: 1ffffffff4400fc7 RCX: ffffffffa09c3196
RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffffffff9f00590f
RBP: 0000000000000000 R08: 0000000000000001 R09: ffffed102360835d
R10: ffff88811b041aeb R11: 0000000000000001 R12: 0000000000000000
R13: ffffffffa202d7c0 R14: 0000000000000000 R15: 00000000000147d0
 default_idle_call+0x6b/0xa0
 cpuidle_idle_call+0x1af/0x1f0
 do_idle+0xbc/0x130
 cpu_startup_entry+0x33/0x40
 rest_init+0x11f/0x210
 start_kernel+0x39a/0x420
 x86_64_start_reservations+0x18/0x30
 x86_64_start_kernel+0x97/0xa0
 common_startup_64+0x13e/0x141
 </TASK>

Allocated by task 595:
 kasan_save_stack+0x24/0x50
 kasan_save_track+0x14/0x30
 __kasan_slab_alloc+0x87/0x90
 kmem_cache_alloc_noprof+0x12b/0x3f0
 copy_net_ns+0x94/0x380
 create_new_namespaces+0x24c/0x500
 unshare_nsproxy_namespaces+0x75/0xf0
 ksys_unshare+0x24e/0x4f0
 __x64_sys_unshare+0x1f/0x30
 do_syscall_64+0x70/0x180
 entry_SYSCALL_64_after_hwframe+0x76/0x7e

Freed by task 100:
 kasan_save_stack+0x24/0x50
 kasan_save_track+0x14/0x30
 kasan_save_free_info+0x3b/0x60
 __kasan_slab_free+0x54/0x70
 kmem_cache_free+0x156/0x5d0
 cleanup_net+0x5d3/0x670
 process_one_work+0x776/0xa90
 worker_thread+0x2e2/0x560
 kthread+0x1a8/0x1f0
 ret_from_fork+0x34/0x60
 ret_from_fork_asm+0x1a/0x30

Reproduction script:

mkdir -p /mnt/nfsshare
mkdir -p /mnt/nfs/netns_1
mkfs.ext4 /dev/sdb
mount /dev/sdb /mnt/nfsshare
systemctl restart nfs-server
chmod 777 /mnt/nfsshare
exportfs -i -o rw,no_root_squash *:/mnt/nfsshare

ip netns add netns_1
ip link add name veth_1_peer type veth peer veth_1
ifconfig veth_1_peer 11.11.0.254 up
ip link set veth_1 netns netns_1
ip netns exec netns_1 ifconfig veth_1 11.11.0.1

ip netns exec netns_1 /root/iptables -A OUTPUT -d 11.11.0.254 -p tcp \
	--tcp-flags FIN FIN  -j DROP

(note: In my environment, a DESTROY_CLIENTID operation is always sent
 immediately, breaking the nfs tcp connection.)
ip netns exec netns_1 timeout -s 9 300 mount -t nfs -o proto=tcp,vers=4.1 \
	11.11.0.254:/mnt/nfsshare /mnt/nfs/netns_1

ip netns del netns_1

The reason here is that the tcp socket in netns_1 (nfs side) has been
shutdown and closed (done in xs_destroy), but the FIN message (with ack)
is discarded, and the nfsd side keeps sending retransmission messages.
As a result, when the tcp sock in netns_1 processes the received message,
it sends the message (FIN message) in the sending queue, and the tcp timer
is re-established. When the network namespace is deleted, the net structure
accessed by tcp's timer handler function causes problems.

To fix this problem, let's hold netns refcnt for the tcp kernel socket as
done in other modules. This is an ugly hack which can easily be backported
to earlier kernels. A proper fix which cleans up the interfaces will
follow, but may not be so easy to backport.

Fixes: 26abe14379 ("net: Modify sk_alloc to not reference count the netns of kernel sockets.")
Signed-off-by: Liu Jian <liujian56@huawei.com>
Acked-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
History 2024-12-09 10:33:00 +01:00
..
auth_gss gss_krb5: Fix the error handling path for crypto_sync_skcipher_setkey 2024-08-03 08:53:42 +02:00
xprtrdma svcrdma: fix miss destroy percpu_counter in svc_rdma_proc_init() 2024-12-09 10:32:30 +01:00
.kunitconfig SUNRPC: Remove RPCSEC_GSS_KRB5_ENCTYPES_DES 2023-08-29 17:45:22 -04:00
addr.c net: sunrpc: Fix an off by one in rpc_sockaddr2uaddr() 2024-03-26 18:20:01 -04:00
auth.c cred: get rid of CONFIG_DEBUG_CREDENTIALS 2023-12-20 17:01:51 +01:00
auth_null.c SUNRPC: Add rpc_auth::au_ralign field 2019-02-14 11:48:36 -05:00
auth_tls.c SUNRPC: Fail quickly when server does not recognize TLS 2023-09-27 15:16:40 -04:00
auth_unix.c SUNRPC: Fix unx_lookup_cred() allocation 2022-03-22 15:52:55 -04:00
backchannel_rqst.c NFS client updates for Linux 5.20 2022-08-10 14:04:32 -07:00
cache.c SUNRPC: make sure cache entry active before cache_show 2024-12-09 10:32:54 +01:00
clnt.c SUNRPC: avoid soft lockup when transmitting UDP to reachable server. 2024-08-03 08:53:54 +02:00
debugfs.c SUNRPC: Cache deferral injection 2022-05-19 12:25:38 -04:00
fail.h SUNRPC: Cache deferral injection 2022-05-19 12:25:38 -04:00
Kconfig SUNRPC: Remove CONFIG_RPCSEC_GSS_KRB5_CRYPTOSYSTEM 2023-08-29 17:45:22 -04:00
Makefile SUNRPC: Add RPC client support for the RPC_AUTH_TLS auth flavor 2023-06-19 12:18:36 -04:00
netns.h SUNRPC: Fix occasional warning when destroying gss_krb5_enctypes 2023-02-20 09:20:57 -05:00
rpc_pipe.c sunrpc: convert to ctime accessor functions 2023-07-24 10:30:07 +02:00
rpcb_clnt.c SUNRPC: Add an IS_ERR() check back to where it was 2023-11-28 17:19:48 +00:00
sched.c SUNRPC: Fix a race to wake a sync task 2024-08-14 13:58:47 +02:00
socklib.c use less confusing names for iov_iter direction initializers 2022-11-25 13:01:55 -05:00
socklib.h SUNRPC: Refactor xs_sendpages() 2020-03-16 12:04:33 -04:00
stats.c sunrpc: use the struct net as the svc proc private 2024-08-19 06:04:23 +02:00
sunrpc.h treewide: Replace GPLv2 boilerplate/reference with SPDX - gpl-2.0_149.RULE 2022-06-10 14:51:35 +02:00
sunrpc_syms.c sunrpc: add IDs to multipath 2021-07-08 14:03:23 -04:00
svc.c SUNRPC: Remove BUG_ON call sites 2024-11-08 16:28:27 +01:00
svc_xprt.c SUNRPC: Revert 5f7fc5d69f 2024-01-01 12:42:26 +00:00
svcauth.c SUNRPC: Add enum svc_auth_status 2023-08-29 17:45:22 -04:00
svcauth_unix.c SUNRPC: Add enum svc_auth_status 2023-08-29 17:45:22 -04:00
svcsock.c sunrpc: fix one UAF issue caused by sunrpc kernel tcp socket 2024-12-09 10:33:00 +01:00
sysctl.c sunrpc: simplify one-level sysctl registration for debug_table 2023-04-11 12:45:19 -04:00
sysfs.c SUNRPC: Add a TCP-with-TLS RPC transport class 2023-06-19 12:28:10 -04:00
sysfs.h NFS: Add sysfs links to sunrpc clients for nfs_clients 2023-06-19 15:04:13 -04:00
timer.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
xdr.c NFS CLient Updates for Linux 6.6 2023-08-31 15:36:41 -07:00
xprt.c timers: Get rid of del_singleshot_timer_sync() 2022-11-24 15:09:10 +01:00
xprtmultipath.c SUNRPC: Fix a suspicious RCU usage warning 2024-02-05 20:14:17 +00:00
xprtsock.c sunrpc: fix one UAF issue caused by sunrpc kernel tcp socket 2024-12-09 10:33:00 +01:00