Linux CIFS filesystem development
 help / color / mirror / Atom feed
From: Stefan Metzmacher <metze@samba.org>
To: linux-cifs@vger.kernel.org, samba-technical@lists.samba.org
Cc: metze@samba.org, Paulo Alcantara <pc@manguebit.org>,
	Namjae Jeon <linkinjeon@kernel.org>, Tom Talpey <tom@talpey.com>
Subject: [PATCH 0/5] smb: client: don't use server->smbd_conn without a reference or lock
Date: Mon,  5 Oct 2026 20:46:55 +0200	[thread overview]
Message-ID: <cover.1791225453.git.metze@samba.org> (raw)

Hi Paulo/Namjae,

The SMB Direct client keeps the transport in server->smbd_conn and
accesses it from several places without any locking:

  - smbd_get_parameters()
  - smbd_register_mr()
  - smbd_debug_proc_show()

At the same time cifs_abort_connection() (and the reconnect path) can
call smbd_destroy() at any time, which frees the smbd_connection and
releases the underlying smbdirect socket. So the readers above can race
with the teardown and end up using a freed connection/socket, a
use-after-free.

While looking at this, smbd_get_parameters() also turned out to
dereference server->smbd_conn without checking it, which is a NULL
pointer dereference in smb2_negotiate_wsize()/smb2_negotiate_rsize()
when it is called during a reconnect window.

This series closes the races:

  - server->smbd_conn is only ever changed under server->srv_lock, so
    readers can safely look at it while holding that lock.

  - smbdirect gets smbdirect_socket_get()/smbdirect_socket_put(), which
    take and drop a reference that keeps the socket memory alive (but
    does not keep it connected). smbd_register_mr() uses them to hold
    the socket across smbdirect_connection_register_mr_io(); once the
    connection is gone the socket is no longer connected and the call
    fails gracefully. A registered MR has its own reference counting.

  - smbd_get_parameters() no longer returns a pointer into the socket
    (which cannot be kept valid for the callers). It copies the current
    parameters into the new server->smbd_params under server->srv_lock
    and returns a pointer to that; with no connection it returns zeros.

  - smbd_debug_proc_show() runs with cifs_tcp_ses_lock held, so it takes
    server->srv_lock instead of a socket reference.

The two "pass server to ..." patches are mechanical prototype changes
with no behaviour change, split out so the final fix stays small and
each step builds on its own.

All of this is a use-after-free that goes back to the switch to the
smbdirect socket API, so the whole series is tagged for stable via

  Fixes: b8aef8c8808c ("smb: client: make use of smbdirect_socket_create_kern()/smbdirect_socket_release()")

which is in mainline since v7.1-rc1.

I run various xfstests with this.

I'm unsure if this should go via cifs-next or ksmbd-for-next,
for consistency with the series I just send I guess both
could go via ksmbd-for-next?

Stefan Metzmacher (5):
  smb: client: change server->smbd_conn only under server->srv_lock
  smb: smbdirect: add smbdirect_socket_get() and smbdirect_socket_put()
  smb: client: pass server to smbd_get_parameters()
  smb: client: pass server to smbd_register_mr()
  smb: client: don't use server->smbd_conn without a reference or lock

 fs/smb/client/cifsglob.h  |  12 ++++
 fs/smb/client/connect.c   |  12 +++-
 fs/smb/client/file.c      |   4 +-
 fs/smb/client/smb2ops.c   |   4 +-
 fs/smb/client/smb2pdu.c   |   4 +-
 fs/smb/client/smbdirect.c | 124 +++++++++++++++++++++++++++++++++-----
 fs/smb/client/smbdirect.h |   8 ++-
 fs/smb/smbdirect/socket.c |  27 +++++++++
 include/linux/smbdirect.h |   3 +
 9 files changed, 171 insertions(+), 27 deletions(-)

-- 
2.43.0


             reply	other threads:[~2026-10-05 18:47 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-05 18:46 Stefan Metzmacher [this message]
2026-10-05 18:46 ` [PATCH 1/5] smb: client: change server->smbd_conn only under server->srv_lock Stefan Metzmacher
2026-10-05 18:46 ` [PATCH 2/5] smb: smbdirect: add smbdirect_socket_get() and smbdirect_socket_put() Stefan Metzmacher
2026-10-05 18:46 ` [PATCH 3/5] smb: client: pass server to smbd_get_parameters() Stefan Metzmacher
2026-10-05 18:46 ` [PATCH 4/5] smb: client: pass server to smbd_register_mr() Stefan Metzmacher
2026-10-05 18:47 ` [PATCH 5/5] smb: client: don't use server->smbd_conn without a reference or lock Stefan Metzmacher
2026-10-05 19:42 ` [PATCH 0/5] " Stefan Metzmacher
2026-10-06 20:13   ` Paulo Alcantara

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=cover.1791225453.git.metze@samba.org \
    --to=metze@samba.org \
    --cc=linkinjeon@kernel.org \
    --cc=linux-cifs@vger.kernel.org \
    --cc=pc@manguebit.org \
    --cc=samba-technical@lists.samba.org \
    --cc=tom@talpey.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox