Re: [PATCH] ksmbd: only rebind the reopened file's own oplock on durable reconnect

Namjae Jeon <[email protected]> Fri, 24 Jul 2026 23:58:39 +0900
Newsgroups org.kernel.vger.linux-cifs,org.kernel.vger.linux-kernel,org.kernel.vger.stable
Message-ID <CAKYAXd-WdPK66FFaTMub8MC6SUX0R9YJ+miVvA8uOwkKioVPuA@mail.gmail.com>
On Fri, Jul 24, 2026 at 8:01 AM Your Name <[email protected]> wrote:
>
> From: Aldo Ariel Panzardo <[email protected]>
>
> ksmbd_reopen_durable_fd() walks the inode's m_op_list and rebinds every
> detached oplock to the reconnecting session:
>
>         list_for_each_entry_rcu(op, &ci->m_op_list, op_entry,
>                                 lockdep_is_held(&ci->m_lock)) {
>                 if (op->conn)
>                         continue;
>                 op->conn = ksmbd_conn_get(fp->conn);
>                 op->sess = work->sess;
>         }
>
> The only key is op->conn == NULL, which every detached durable handle on
> that inode matches, not just the one owned by fp.  When two sessions hold
> durable handles on the same file and both disconnect, reconnecting one of
> them adopts the other session's oplock: op->sess is overwritten with the
> reconnecting session without taking a reference on it, while op->conn
> pins the connection.
>
> The sibling teardown path, session_fd_check(), keys on the identity of
> the connection being torn down (op->conn == conn) rather than on shared
> state, and so does not have this problem.
>
> Once the adopting session is destroyed, ksmbd_session_destroy() frees it
> while the foreign oplock still points at it.  The reader in
> ksmbd_close_fd_app_instance_id() validates only opinfo->conn, which is
> still live thanks to the reference taken above, and then dereferences the
> stale session:
>
>         if (!opinfo->conn) {
>                 up_read(&fp->f_ci->m_lock);
>                 goto out;
>         }
>
>         ft = &opinfo->sess->file_table;
>         write_lock(&ft->lock);
>
>   BUG: KASAN: slab-use-after-free in _raw_write_lock+0x74/0xd0
>   Write of size 4 at addr ffff88810a970528 by task kworker/0:0/9
>   Workqueue: ksmbd-io handle_ksmbd_work
>   Call Trace:
>    _raw_write_lock+0x74/0xd0
>    ksmbd_close_fd_app_instance_id+0x183/0x410
>    smb2_open+0x1346/0x4430
>    handle_ksmbd_work+0x2bb/0x7b0
>
> Reached from an authenticated session against a share with the default
> durable-handle and oplock configuration: two sessions open the same file
> with a durable-v2 handle and an RH lease under distinct AppInstanceIds,
> both log off, one reconnects with DH2C, and a later durable-v2 create
> carrying the other AppInstanceId walks into the freed session.
>
> Constrain the loop to the oplock owned by the file being reopened.
>
> Fixes: f363a0fb134a ("ksmbd: fix app-instance durable supersede session UAF")
> Cc: [email protected]
> Signed-off-by: Aldo Ariel Panzardo <[email protected]>
Applied it to #ksmbd-for-next-next.
Thanks!