linux/fs/smb/client
Kuniyuki Iwashima ef7134c7fc smb: client: Fix use-after-free of network namespace.
Recently, we got a customer report that CIFS triggers oops while
reconnecting to a server.  [0]

The workload runs on Kubernetes, and some pods mount CIFS servers
in non-root network namespaces.  The problem rarely happened, but
it was always while the pod was dying.

The root cause is wrong reference counting for network namespace.

CIFS uses kernel sockets, which do not hold refcnt of the netns that
the socket belongs to.  That means CIFS must ensure the socket is
always freed before its netns; otherwise, use-after-free happens.

The repro steps are roughly:

  1. mount CIFS in a non-root netns
  2. drop packets from the netns
  3. destroy the netns
  4. unmount CIFS

We can reproduce the issue quickly with the script [1] below and see
the splat [2] if CONFIG_NET_NS_REFCNT_TRACKER is enabled.

When the socket is TCP, it is hard to guarantee the netns lifetime
without holding refcnt due to async timers.

Let's hold netns refcnt for each socket as done for SMC in commit
9744d2bf19 ("smc: Fix use-after-free in tcp_write_timer_handler().").

Note that we need to move put_net() from cifs_put_tcp_session() to
clean_demultiplex_info(); otherwise, __sock_create() still could touch a
freed netns while cifsd tries to reconnect from cifs_demultiplex_thread().

Also, maybe_get_net() cannot be put just before __sock_create() because
the code is not under RCU and there is a small chance that the same
address happened to be reallocated to another netns.

[0]:
CIFS: VFS: \\XXXXXXXXXXX has not responded in 15 seconds. Reconnecting...
CIFS: Serverclose failed 4 times, giving up
Unable to handle kernel paging request at virtual address 14de99e461f84a07
Mem abort info:
  ESR = 0x0000000096000004
  EC = 0x25: DABT (current EL), IL = 32 bits
  SET = 0, FnV = 0
  EA = 0, S1PTW = 0
  FSC = 0x04: level 0 translation fault
Data abort info:
  ISV = 0, ISS = 0x00000004
  CM = 0, WnR = 0
[14de99e461f84a07] address between user and kernel address ranges
Internal error: Oops: 0000000096000004 [#1] SMP
Modules linked in: cls_bpf sch_ingress nls_utf8 cifs cifs_arc4 cifs_md4 dns_resolver tcp_diag inet_diag veth xt_state xt_connmark nf_conntrack_netlink xt_nat xt_statistic xt_MASQUERADE xt_mark xt_addrtype ipt_REJECT nf_reject_ipv4 nft_chain_nat nf_nat xt_conntrack nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 xt_comment nft_compat nf_tables nfnetlink overlay nls_ascii nls_cp437 sunrpc vfat fat aes_ce_blk aes_ce_cipher ghash_ce sm4_ce_cipher sm4 sm3_ce sm3 sha3_ce sha512_ce sha512_arm64 sha1_ce ena button sch_fq_codel loop fuse configfs dmi_sysfs sha2_ce sha256_arm64 dm_mirror dm_region_hash dm_log dm_mod dax efivarfs
CPU: 5 PID: 2690970 Comm: cifsd Not tainted 6.1.103-109.184.amzn2023.aarch64 #1
Hardware name: Amazon EC2 r7g.4xlarge/, BIOS 1.0 11/1/2018
pstate: 00400005 (nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : fib_rules_lookup+0x44/0x238
lr : __fib_lookup+0x64/0xbc
sp : ffff8000265db790
x29: ffff8000265db790 x28: 0000000000000000 x27: 000000000000bd01
x26: 0000000000000000 x25: ffff000b4baf8000 x24: ffff00047b5e4580
x23: ffff8000265db7e0 x22: 0000000000000000 x21: ffff00047b5e4500
x20: ffff0010e3f694f8 x19: 14de99e461f849f7 x18: 0000000000000000
x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
x14: 0000000000000000 x13: 0000000000000000 x12: 3f92800abd010002
x11: 0000000000000001 x10: ffff0010e3f69420 x9 : ffff800008a6f294
x8 : 0000000000000000 x7 : 0000000000000006 x6 : 0000000000000000
x5 : 0000000000000001 x4 : ffff001924354280 x3 : ffff8000265db7e0
x2 : 0000000000000000 x1 : ffff0010e3f694f8 x0 : ffff00047b5e4500
Call trace:
 fib_rules_lookup+0x44/0x238
 __fib_lookup+0x64/0xbc
 ip_route_output_key_hash_rcu+0x2c4/0x398
 ip_route_output_key_hash+0x60/0x8c
 tcp_v4_connect+0x290/0x488
 __inet_stream_connect+0x108/0x3d0
 inet_stream_connect+0x50/0x78
 kernel_connect+0x6c/0xac
 generic_ip_connect+0x10c/0x6c8 [cifs]
 __reconnect_target_unlocked+0xa0/0x214 [cifs]
 reconnect_dfs_server+0x144/0x460 [cifs]
 cifs_reconnect+0x88/0x148 [cifs]
 cifs_readv_from_socket+0x230/0x430 [cifs]
 cifs_read_from_socket+0x74/0xa8 [cifs]
 cifs_demultiplex_thread+0xf8/0x704 [cifs]
 kthread+0xd0/0xd4
Code: aa0003f8 f8480f13 eb18027f 540006c0 (b9401264)

[1]:
CIFS_CRED="/root/cred.cifs"
CIFS_USER="Administrator"
CIFS_PASS="Password"
CIFS_IP="X.X.X.X"
CIFS_PATH="//${CIFS_IP}/Users/Administrator/Desktop/CIFS_TEST"
CIFS_MNT="/mnt/smb"
DEV="enp0s3"

cat <<EOF > ${CIFS_CRED}
username=${CIFS_USER}
password=${CIFS_PASS}
domain=EXAMPLE.COM
EOF

unshare -n bash -c "
mkdir -p ${CIFS_MNT}
ip netns attach root 1
ip link add eth0 type veth peer veth0 netns root
ip link set eth0 up
ip -n root link set veth0 up
ip addr add 192.168.0.2/24 dev eth0
ip -n root addr add 192.168.0.1/24 dev veth0
ip route add default via 192.168.0.1 dev eth0
ip netns exec root sysctl net.ipv4.ip_forward=1
ip netns exec root iptables -t nat -A POSTROUTING -s 192.168.0.2 -o ${DEV} -j MASQUERADE
mount -t cifs ${CIFS_PATH} ${CIFS_MNT} -o vers=3.0,sec=ntlmssp,credentials=${CIFS_CRED},rsize=65536,wsize=65536,cache=none,echo_interval=1
touch ${CIFS_MNT}/a.txt
ip netns exec root iptables -t nat -D POSTROUTING -s 192.168.0.2 -o ${DEV} -j MASQUERADE
"

umount ${CIFS_MNT}

[2]:
ref_tracker: net notrefcnt@000000004bbc008d has 1/1 users at
     sk_alloc (./include/net/net_namespace.h:339 net/core/sock.c:2227)
     inet_create (net/ipv4/af_inet.c:326 net/ipv4/af_inet.c:252)
     __sock_create (net/socket.c:1576)
     generic_ip_connect (fs/smb/client/connect.c:3075)
     cifs_get_tcp_session.part.0 (fs/smb/client/connect.c:3160 fs/smb/client/connect.c:1798)
     cifs_mount_get_session (fs/smb/client/trace.h:959 fs/smb/client/connect.c:3366)
     dfs_mount_share (fs/smb/client/dfs.c:63 fs/smb/client/dfs.c:285)
     cifs_mount (fs/smb/client/connect.c:3622)
     cifs_smb3_do_mount (fs/smb/client/cifsfs.c:949)
     smb3_get_tree (fs/smb/client/fs_context.c:784 fs/smb/client/fs_context.c:802 fs/smb/client/fs_context.c:794)
     vfs_get_tree (fs/super.c:1800)
     path_mount (fs/namespace.c:3508 fs/namespace.c:3834)
     __x64_sys_mount (fs/namespace.c:3848 fs/namespace.c:4057 fs/namespace.c:4034 fs/namespace.c:4034)
     do_syscall_64 (arch/x86/entry/common.c:52 arch/x86/entry/common.c:83)
     entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130)

Fixes: 26abe14379 ("net: Modify sk_alloc to not reference count the netns of kernel sockets.")
Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Acked-by: Tom Talpey <tom@talpey.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
2024-11-03 19:28:31 -06:00
..
compress move asm/unaligned.h to linux/unaligned.h 2024-10-02 17:23:23 -04:00
asn1.c
cached_dir.c smb3: fix Open files on server counter going negative 2024-04-11 16:02:02 -05:00
cached_dir.h smb: client: make laundromat a delayed worker 2023-10-12 09:41:04 -05:00
cifs_debug.c smb3: mark compression as CONFIG_EXPERIMENTAL and fix missing compression operation 2024-09-15 10:42:44 -05:00
cifs_debug.h
cifs_fs_sb.h
cifs_ioctl.h smb3: allow dumping session and tcon id to improve stats analysis and debugging 2023-11-10 02:00:30 -06:00
cifs_spnego_negtokeninit.asn1
cifs_spnego.c cifs: spnego: add ';' in HOST_KEY_LEN 2023-11-13 16:21:34 -06:00
cifs_spnego.h
cifs_swn.c
cifs_swn.h
cifs_unicode.c cifs: Fix creating native symlinks pointing to current or parent directory 2024-10-06 22:57:12 -05:00
cifs_unicode.h fs/smb/client: Use common code in client 2023-08-30 08:55:52 -05:00
cifsacl.c smb: client: Use min() macro 2024-09-15 10:42:44 -05:00
cifsacl.h smb: client: Correct typos in multiple comments across various files 2024-10-02 17:52:24 -05:00
cifsencrypt.c smb: client: Correct typos in multiple comments across various files 2024-10-02 17:52:24 -05:00
cifsfs.c cifs: fix warning when destroy 'cifs_io_request_pool' 2024-10-23 07:42:44 -05:00
cifsfs.h cifs: update internal version number 2024-09-24 21:54:06 -05:00
cifsglob.h smb: client: Correct typos in multiple comments across various files 2024-10-02 17:52:24 -05:00
cifspdu.h nine smb3 client fixes 2024-10-04 09:56:05 -07:00
cifsproto.h cifs: Remove unused functions 2024-10-16 00:30:52 -05:00
cifsroot.c
cifssmb.c smb: client: Correct typos in multiple comments across various files 2024-10-02 17:52:24 -05:00
compress.c smb/client: Fix logically dead code 2024-10-16 00:30:52 -05:00
compress.h smb: client: compress: LZ77 code improvements cleanup 2024-09-15 10:42:45 -05:00
connect.c smb: client: Fix use-after-free of network namespace. 2024-11-03 19:28:31 -06:00
dfs_cache.c smb: client: fix DFS interlink failover 2024-09-24 21:51:48 -05:00
dfs_cache.h smb: client: ensure to try all targets when finding nested links 2023-08-20 16:05:50 -05:00
dfs.c smb: client: fix DFS interlink failover 2024-09-24 21:51:48 -05:00
dfs.h smb: client: fix DFS interlink failover 2024-09-24 21:51:48 -05:00
dir.c cifs: Fix caching to try to do open O_WRONLY as rdwr on server 2024-04-02 09:29:55 -05:00
dns_resolve.c
dns_resolve.h
export.c exportfs: make ->encode_fh() a mandatory method for NFS export 2023-10-28 16:15:15 +02:00
file.c smb: client: Correct typos in multiple comments across various files 2024-10-02 17:52:24 -05:00
fs_context.c smb: client: Handle kstrdup failures for passwords 2024-10-23 07:42:22 -05:00
fs_context.h smb: client: Correct typos in multiple comments across various files 2024-10-02 17:52:24 -05:00
fscache.c cifs: Remove some code that's no longer used, part 1 2024-05-01 18:08:21 +01:00
fscache.h cifs: Remove some code that's no longer used, part 1 2024-05-01 18:08:21 +01:00
inode.c cifs: Check for UTF-16 null codepoint in SFU symlink target location 2024-09-29 17:28:40 -05:00
ioctl.c struct fd layout change (and conversion to accessor helpers) 2024-09-23 09:35:36 -07:00
Kconfig smb3: mark compression as CONFIG_EXPERIMENTAL and fix missing compression operation 2024-09-15 10:42:44 -05:00
link.c cifs: Add support for creating SFU symlinks 2024-09-16 20:10:34 -05:00
Makefile smb3: mark compression as CONFIG_EXPERIMENTAL and fix missing compression operation 2024-09-15 10:42:44 -05:00
misc.c smb: client: Correct typos in multiple comments across various files 2024-10-02 17:52:24 -05:00
namespace.c smb: client: fix DFS interlink failover 2024-09-24 21:51:48 -05:00
netlink.c
netlink.h
netmisc.c smb: client: Correct typos in multiple comments across various files 2024-10-02 17:52:24 -05:00
nterr.c
nterr.h
ntlmssp.h cifs: Add client version details to NTLM authenticate message 2023-10-22 19:03:42 -05:00
readdir.c smb: client: Correct typos in multiple comments across various files 2024-10-02 17:52:24 -05:00
reparse.c cifs: Improve creating native symlinks pointing to directory 2024-10-06 22:57:12 -05:00
reparse.h smb: client: fix parsing of device numbers 2024-09-24 21:51:48 -05:00
rfc1002pdu.h
sess.c cifs: Remove unused functions 2024-10-16 00:30:52 -05:00
smb1ops.c smb: client: use actual path when queryfs 2024-10-01 21:47:16 -05:00
smb2file.c smb: use LIST_HEAD() to simplify code 2024-09-15 10:42:45 -05:00
smb2glob.h smb: client: introduce SMB2_OP_QUERY_WSL_EA 2024-03-10 19:33:58 -05:00
smb2inode.c cifs: Improve creating native symlinks pointing to directory 2024-10-06 22:57:12 -05:00
smb2maperror.c smb: move SMB2 Status code to common header file 2024-09-15 10:42:44 -05:00
smb2misc.c Revert "smb: client: make SHA-512 TFM ephemeral" 2024-09-30 22:07:45 -05:00
smb2ops.c smb: client: fix possible double free in smb2_set_ea() 2024-10-16 00:25:54 -05:00
smb2pdu.c smb: client: fix OOBs when building SMB2_IOCTL request 2024-10-16 00:30:52 -05:00
smb2pdu.h smb/client: rename cifs_sid to smb_sid 2024-09-15 10:42:44 -05:00
smb2proto.h cifs: Improve creating native symlinks pointing to directory 2024-10-06 22:57:12 -05:00
smb2transport.c smb: client: Correct typos in multiple comments across various files 2024-10-02 17:52:24 -05:00
smbdirect.c smb: client: Correct typos in multiple comments across various files 2024-10-02 17:52:24 -05:00
smbdirect.h smb: client: Correct typos in multiple comments across various files 2024-10-02 17:52:24 -05:00
smbencrypt.c smb: client: delete "true", "false" defines 2024-01-23 12:41:02 -06:00
smberr.h
trace.c
trace.h cifs: Make the write_{enter,done,err} tracepoints display netfs info 2024-09-24 21:51:48 -05:00
transport.c cifs: Fix reversion of the iter in cifs_readv_receive(). 2024-09-24 21:53:08 -05:00
unc.c
winucase.c
xattr.c smb/client: rename cifs_ntsd to smb_ntsd 2024-09-15 10:42:44 -05:00