CVE-2025-22077
Published: April 18, 2025Last modified: April 18, 2025
Description
In the Linux kernel, the following vulnerability has been resolved: smb: client: Fix netns refcount imbalance causing leaks and use-after-free Commit ef7134c7fc48 ("smb: client: Fix use-after-free of network namespace.") attempted to fix a netns use-after-free issue by manually adjusting reference counts via sk->sk_net_refcnt and sock_inuse_add(). However, a later commit e9f2517a3e18 ("smb: client: fix TCP timers deadlock after rmmod") pointed out that the approach of manually setting sk->sk_net_refcnt in the first commit was technically incorrect, as sk->sk_net_refcnt should only be set for user sockets. It led to issues like TCP timers not being cleared properly on close. The second commit moved to a model of just holding an extra netns reference for server->ssocket using get_net(), and dropping it when the server is torn down. But there remain some gaps in the get_net()/put_net() balancing added by these commits. The incomplete reference handling in these fixes results in two issues: 1. Netns refcount leaks[1] The problem process is as follows: ``` mount.cifs cifsd cifs_do_mount cifs_mount cifs_mount_get_session cifs_get_tcp_session get_net() /* First get net. */ ip_connect generic_ip_connect /* Try port 445 */ get_net() ->connect() /* Failed */ put_net() generic_ip_connect /* Try port 139 */ get_net() /* Missing matching put_net() for this get_net().*/ cifs_get_smb_ses cifs_negotiate_protocol smb2_negotiate SMB2_negotiate cifs_send_recv wait_for_response cifs_demultiplex_thread cifs_read_from_socket cifs_readv_from_socket cifs_reconnect cifs_abort_connection sock_release(); server->ssocket = NULL; /* Missing put_net() here. */ generic_ip_connect get_net() ->connect() /* Failed */ put_net() sock_release(); server->ssocket = NULL; free_rsp_buf ... clean_demultiplex_info /* It's only called once here. */ put_net() ``` When cifs_reconnect() is triggered, the server->ssocket is released without a corresponding put_net() for the reference acquired in generic_ip_connect() before. it ends up calling generic_ip_connect() again to retry get_net(). After that, server->ssocket is set to NULL in the error path of generic_ip_connect(), and the net count cannot be released in the final clean_demultiplex_info() function. 2. Potential use-after-free The current refcounting scheme can lead to a potential use-after-free issue in the following scenario: ``` cifs_do_mount cifs_mount cifs_mount_get_session cifs_get_tcp_session get_net() /* First get net */ ip_connect generic_ip_connect get_net() bind_socket kernel_bind /* failed */ put_net() /* after out_err_crypto_release label */ put_net() /* after out_err label */ put_net() ``` In the exception handling process where binding the socket fails, the get_net() and put_net() calls are unbalanced, which may cause the server->net reference count to drop to zero and be prematurely released. To address both issues, this patch ties the netns reference counti ---truncated---
Status
Product | Release | Package | Status |
---|---|---|---|
Alpaquita Linux | 23 LTS | linux-lts | Not affected (6.1.33-r0) |
Stream | linux-lts | Not affected (6.1.33-r0) |
References
- https://git.kernel.org/stable/c/476617a4ca0123f0df677d547a82a110c27c8c74
- https://git.kernel.org/stable/c/4b6f6bf1bde8d6045c389fda8d21c304dfe49384
- https://git.kernel.org/stable/c/4e7f1644f2ac6d01dc584f6301c3b1d5aac4eaef
- https://git.kernel.org/stable/c/7d8dfc27d90d41627c0d6ada97ed0ab57b3dae25
- https://git.kernel.org/stable/c/8dbf060480236877703bff0106fc984576184d11
- https://git.kernel.org/stable/c/95d2b9f693ff2a1180a23d7d59acc0c4e72f4c41
- https://git.kernel.org/stable/c/961755d0055e0e96d1849cc0425da966c8a64e53
- https://git.kernel.org/stable/c/c6b6b8dcef4adf8ee4e439bb97e74106096c71b8
- https://git.kernel.org/stable/c/f761eeefd531e6550cd3a5c047835b4892acb00d