CVE-2025-22077 Information

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.

  1. 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—

Reference

https://git.kernel.org/stable/c/476617a4ca0123f0df677d547a82a110c27c8c74 https://git.kernel.org/stable/c/4e7f1644f2ac6d01dc584f6301c3b1d5aac4eaef https://git.kernel.org/stable/c/7d8dfc27d90d41627c0d6ada97ed0ab57b3dae25 https://git.kernel.org/stable/c/961755d0055e0e96d1849cc0425da966c8a64e53 https://git.kernel.org/stable/c/c6b6b8dcef4adf8ee4e439bb97e74106096c71b8

Share on: