From: Abdifatah Suruur <suruurism@gmail.com>
To: linux-cifs@vger.kernel.org
Cc: linkinjeon@kernel.org, sfrench@samba.org,
senozhatsky@chromium.org, tom@talpey.com
Subject: [PATCH] ksmbd: fix use-after-free in oplock break notification
Date: Sat, 29 Aug 2026 13:22:17 +0300 [thread overview]
Message-ID: <20260829102217.6201-1-suruurism@gmail.com> (raw)
smb2_oplock_break_noti() reads opinfo->conn without any lock and
dereferences it after two allocations which may sleep. When the
durable handle owning the oplock is disconnected, session_fd_check()
clears opinfo->conn and drops its conn reference under ci->m_lock, and
the last ksmbd_conn_put() frees the connection. A break triggered by
another connection that races with the teardown can then resurrect the
freed connection: ksmbd_conn_get() is a plain atomic_inc, and the
queued break work later dereferences the stale conn via
ksmbd_conn_write(), a use-after-free reachable by any authenticated
client holding a durable batch oplock.
Select and pin the connection under ci->m_lock before the allocations,
the same lock session_fd_check() uses to clear opinfo->conn, so a
concurrent teardown either loses the race to the clear or keeps the
connection alive until the notification work releases it. Transfer the
reference to the work item and release it on allocation failures.
Fixes: b003086d7696 ("ksmbd: fix NULL-deref of opinfo->conn in oplock/lease break notifiers")
Cc: stable@vger.kernel.org
Signed-off-by: Abdifatah Suruur <suruurism@gmail.com>
---
fs/smb/server/oplock.c | 36 ++++++++++++++++++++++++++++--------
1 file changed, 28 insertions(+), 8 deletions(-)
diff --git a/fs/smb/server/oplock.c b/fs/smb/server/oplock.c
@@ -924,6 +924,32 @@
ksmbd_conn_put(conn);
}
+/*
+ * Select and pin the connection used for an oplock break before doing any
+ * allocations which may sleep. opinfo->conn is cleared under ci->m_lock by
+ * session_fd_check() when the durable handle owning the oplock is
+ * disconnected, and the last ksmbd_conn_put() frees the connection.
+ */
+static struct ksmbd_conn *smb2_oplock_break_conn_get(struct oplock_info *opinfo)
+{
+ struct ksmbd_inode *ci;
+ struct ksmbd_conn *conn;
+
+ if (!opinfo->o_fp)
+ return NULL;
+ ci = opinfo->o_fp->f_ci;
+
+ down_read(&ci->m_lock);
+ conn = READ_ONCE(opinfo->conn);
+ if (conn && !ksmbd_conn_releasing(conn))
+ conn = ksmbd_conn_get(conn);
+ else
+ conn = NULL;
+ up_read(&ci->m_lock);
+
+ return conn;
+}
+
/**
* smb2_oplock_break_noti() - send smb2 exclusive/batch to level2 oplock
* break command from server to client
@@ -938,17 +964,20 @@
int ret = 0;
struct ksmbd_work *work;
- conn = READ_ONCE(opinfo->conn);
+ conn = smb2_oplock_break_conn_get(opinfo);
if (!conn)
return ksmbd_invalidate_durable_fd(opinfo->fid);
work = ksmbd_alloc_work_struct();
- if (!work)
+ if (!work) {
+ ksmbd_conn_put(conn);
return -ENOMEM;
+ }
br_info = kmalloc_obj(struct oplock_break_info, KSMBD_DEFAULT_GFP);
if (!br_info) {
ksmbd_free_work_struct(work);
+ ksmbd_conn_put(conn);
return -ENOMEM;
}
@@ -957,7 +986,8 @@
br_info->open_trunc = opinfo->open_trunc;
work->request_buf = (char *)br_info;
- work->conn = ksmbd_conn_get(conn);
+ /* Transfer the reference acquired by smb2_oplock_break_conn_get(). */
+ work->conn = conn;
work->sess = opinfo->sess;
ksmbd_conn_r_count_inc(conn);
next reply other threads:[~2026-08-29 10:22 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-29 10:22 Abdifatah Suruur [this message]
2026-08-29 11:05 ` [PATCH] ksmbd: fix use-after-free in oplock break notification Namjae Jeon
-- strict thread matches above, loose matches on Subject: below --
2026-08-29 11:38 Abdifatah Suruur
2026-08-29 11:38 Abdifatah Suruur
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=20260829102217.6201-1-suruurism@gmail.com \
--to=suruurism@gmail.com \
--cc=linkinjeon@kernel.org \
--cc=linux-cifs@vger.kernel.org \
--cc=senozhatsky@chromium.org \
--cc=sfrench@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