<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux/fs/smb/server/oplock.c, branch master</title>
<subtitle>Mirror of https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/
</subtitle>
<id>https://www.git.shady.money/linux/atom?h=master</id>
<link rel='self' href='https://www.git.shady.money/linux/atom?h=master'/>
<link rel='alternate' type='text/html' href='https://www.git.shady.money/linux/'/>
<updated>2026-05-02T02:49:35Z</updated>
<entry>
<title>ksmbd: centralize ksmbd_conn final release to plug transport leak</title>
<updated>2026-05-02T02:49:35Z</updated>
<author>
<name>DaeMyung Kang</name>
<email>charsyam@gmail.com</email>
</author>
<published>2026-04-28T14:08:54Z</published>
<link rel='alternate' type='text/html' href='https://www.git.shady.money/linux/commit/?id=b1f1e80620deb49daf63c2e677046599b693dc1f'/>
<id>urn:sha1:b1f1e80620deb49daf63c2e677046599b693dc1f</id>
<content type='text'>
ksmbd_conn_free() is one of four sites that can observe the last
refcount drop of a struct ksmbd_conn.  The other three

    fs/smb/server/connection.c    ksmbd_conn_r_count_dec()
    fs/smb/server/oplock.c        __free_opinfo()
    fs/smb/server/vfs_cache.c     session_fd_check()

end the conn with a bare kfree(), skipping
ida_destroy(&amp;conn-&gt;async_ida) and
conn-&gt;transport-&gt;ops-&gt;free_transport(conn-&gt;transport).  Whenever one
of them is the last putter, the embedded async_ida and the entire
transport struct leak -- for TCP, that is also the struct socket and
the kvec iov.

__free_opinfo() being a final putter is not theoretical.  opinfo_put()
queues the callback via call_rcu(&amp;opinfo-&gt;rcu, free_opinfo_rcu), so
ksmbd_server_terminate_conn() can deposit N opinfo releases in RCU and
have ksmbd_conn_free() run in the handler thread before any of them
fire.  ksmbd_conn_free() then observes refcnt &gt; 0 and short-circuits;
the last RCU-delivered __free_opinfo() falls onto its bare kfree(conn)
branch and the transport is lost.

A/B validation in a QEMU/virtme guest, mounting //127.0.0.1/testshare:
each iteration holds 8 files open via sleep processes, force-closes
TCP with "ss -K sport = :445", kills the holders, lazy-umounts;
repeated 10 times, then ksmbd shutdown and kmemleak scan.

    state         conn_alloc  conn_free  tcp_free  opi_rcu  kmemleak
    ----------    ----------  ---------  --------  -------  --------
    pre-patch         20          20        10       160        7
    with patch        20          20        20       160        0

Pre-patch conn_free=20 with tcp_free=10 directly demonstrates the
bare-kfree paths skipping transport cleanup; kmemleak backtraces point
into struct tcp_transport / iov.  With this patch tcp_free matches
conn_free at 20/20 and kmemleak is clean.

Move the per-struct final release into __ksmbd_conn_release_work() and
route the three bare-kfree final-put sites through a new
ksmbd_conn_put().  Those sites now pair ida_destroy() and
free_transport() with kfree(conn) regardless of which holder happens
to release the last reference.  stop_sessions() only triggers the
transport shutdown and does not itself drop the last conn reference,
so it is unaffected.

The centralized release reaches sock_release() -&gt; tcp_close() -&gt;
lock_sock_nested() (might_sleep) from every final putter, including
__free_opinfo() invoked from an RCU softirq callback, which trips
CONFIG_DEBUG_ATOMIC_SLEEP.  Defer the release to a dedicated
ksmbd_conn_wq workqueue so ksmbd_conn_put() is safe from any
non-sleeping context.

Make ksmbd_file own a strong connection reference while fp-&gt;conn is
non-NULL so durable-preserve and final-close paths cannot dereference
a stale connection.  ksmbd_open_fd() and ksmbd_reopen_durable_fd()
take the reference via ksmbd_conn_get() (the latter also reorders the
fp-&gt;conn / fp-&gt;tcon assignments before __open_id() so the published fp
is never observed with fp-&gt;conn == NULL); session_fd_check() and
__ksmbd_close_fd() drop it via ksmbd_conn_put().  With that invariant,
session_fd_check() can take a local conn pointer once and use it
across the m_op_list and lock_list iterations even though op-&gt;conn
puts may otherwise drop the last reference.

At module exit the workqueue is flushed and destroyed after
rcu_barrier(), so any release queued by a trailing RCU callback is
drained before the inode hash and module text go away.

Fixes: ee426bfb9d09 ("ksmbd: add refcnt to ksmbd_conn struct")
Signed-off-by: DaeMyung Kang &lt;charsyam@gmail.com&gt;
Acked-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
Signed-off-by: Steve French &lt;stfrench@microsoft.com&gt;
</content>
</entry>
<entry>
<title>ksmbd: validate owner of durable handle on reconnect</title>
<updated>2026-04-12T23:07:54Z</updated>
<author>
<name>Namjae Jeon</name>
<email>linkinjeon@kernel.org</email>
</author>
<published>2026-04-12T13:16:16Z</published>
<link rel='alternate' type='text/html' href='https://www.git.shady.money/linux/commit/?id=49110a8ce654bbe56bef7c5e44cce31f4b102b8a'/>
<id>urn:sha1:49110a8ce654bbe56bef7c5e44cce31f4b102b8a</id>
<content type='text'>
Currently, ksmbd does not verify if the user attempting to reconnect
to a durable handle is the same user who originally opened the file.
This allows any authenticated user to hijack an orphaned durable handle
by predicting or brute-forcing the persistent ID.

According to MS-SMB2, the server MUST verify that the SecurityContext
of the reconnect request matches the SecurityContext associated with
the existing open.
Add a durable_owner structure to ksmbd_file to store the original opener's
UID, GID, and account name. and catpure the owner information when a file
handle becomes orphaned. and implementing ksmbd_vfs_compare_durable_owner()
to validate the identity of the requester during SMB2_CREATE (DHnC).

Fixes: c8efcc786146 ("ksmbd: add support for durable handles v1/v2")
Reported-by: Davide Ornaghi &lt;d.ornaghi97@gmail.com&gt;
Reported-by: Navaneeth K &lt;knavaneeth786@gmail.com&gt;
Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
Signed-off-by: Steve French &lt;stfrench@microsoft.com&gt;
</content>
</entry>
<entry>
<title>ksmbd: fix use-after-free and NULL deref in smb_grant_oplock()</title>
<updated>2026-03-22T22:15:00Z</updated>
<author>
<name>Werner Kasselman</name>
<email>werner@verivus.com</email>
</author>
<published>2026-03-16T11:38:47Z</published>
<link rel='alternate' type='text/html' href='https://www.git.shady.money/linux/commit/?id=48623ec358c1c600fa1e38368746f933e0f1a617'/>
<id>urn:sha1:48623ec358c1c600fa1e38368746f933e0f1a617</id>
<content type='text'>
smb_grant_oplock() has two issues in the oplock publication sequence:

1) opinfo is linked into ci-&gt;m_op_list (via opinfo_add) before
   add_lease_global_list() is called.  If add_lease_global_list()
   fails (kmalloc returns NULL), the error path frees the opinfo
   via __free_opinfo() while it is still linked in ci-&gt;m_op_list.
   Concurrent m_op_list readers (opinfo_get_list, or direct iteration
   in smb_break_all_levII_oplock) dereference the freed node.

2) opinfo-&gt;o_fp is assigned after add_lease_global_list() publishes
   the opinfo on the global lease list.  A concurrent
   find_same_lease_key() can walk the lease list and dereference
   opinfo-&gt;o_fp-&gt;f_ci while o_fp is still NULL.

Fix by restructuring the publication sequence to eliminate post-publish
failure:

- Set opinfo-&gt;o_fp before any list publication (fixes NULL deref).
- Preallocate lease_table via alloc_lease_table() before opinfo_add()
  so add_lease_global_list() becomes infallible after publication.
- Keep the original m_op_list publication order (opinfo_add before
  lease list) so concurrent opens via same_client_has_lease() and
  opinfo_get_list() still see the in-flight grant.
- Use opinfo_put() instead of __free_opinfo() on err_out so that
  the RCU-deferred free path is used.

This also requires splitting add_lease_global_list() to take a
preallocated lease_table and changing its return type from int to void,
since it can no longer fail.

Fixes: 1dfd062caa16 ("ksmbd: fix use-after-free by using call_rcu() for oplock_info")
Cc: stable@vger.kernel.org
Signed-off-by: Werner Kasselman &lt;werner@verivus.com&gt;
Reviewed-by: ChenXiaoSong &lt;chenxiaosong@kylinos.cn&gt;
Acked-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
Signed-off-by: Steve French &lt;stfrench@microsoft.com&gt;
</content>
</entry>
<entry>
<title>ksmbd: fix use-after-free in smb_lazy_parent_lease_break_close()</title>
<updated>2026-03-09T02:28:39Z</updated>
<author>
<name>Namjae Jeon</name>
<email>linkinjeon@kernel.org</email>
</author>
<published>2026-03-02T03:55:02Z</published>
<link rel='alternate' type='text/html' href='https://www.git.shady.money/linux/commit/?id=eac3361e3d5dd8067b3258c69615888eb45e9f25'/>
<id>urn:sha1:eac3361e3d5dd8067b3258c69615888eb45e9f25</id>
<content type='text'>
opinfo pointer obtained via rcu_dereference(fp-&gt;f_opinfo) is being
accessed after rcu_read_unlock() has been called. This creates a
race condition where the memory could be freed by a concurrent
writer between the unlock and the subsequent pointer dereferences
(opinfo-&gt;is_lease, etc.), leading to a use-after-free.

Fixes: 5fb282ba4fef ("ksmbd: fix possible null-deref in smb_lazy_parent_lease_break_close")
Cc: stable@vger.kernel.org
Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
Signed-off-by: Steve French &lt;stfrench@microsoft.com&gt;
</content>
</entry>
<entry>
<title>ksmbd: fix use-after-free by using call_rcu() for oplock_info</title>
<updated>2026-03-09T02:28:39Z</updated>
<author>
<name>Namjae Jeon</name>
<email>linkinjeon@kernel.org</email>
</author>
<published>2026-03-07T02:32:31Z</published>
<link rel='alternate' type='text/html' href='https://www.git.shady.money/linux/commit/?id=1dfd062caa165ec9d7ee0823087930f3ab8a6294'/>
<id>urn:sha1:1dfd062caa165ec9d7ee0823087930f3ab8a6294</id>
<content type='text'>
ksmbd currently frees oplock_info immediately using kfree(), even
though it is accessed under RCU read-side critical sections in places
like opinfo_get() and proc_show_files().

Since there is no RCU grace period delay between nullifying the pointer
and freeing the memory, a reader can still access oplock_info
structure after it has been freed. This can leads to a use-after-free
especially in opinfo_get() where atomic_inc_not_zero() is called on
already freed memory.

Fix this by switching to deferred freeing using call_rcu().

Fixes: 18b4fac5ef17 ("ksmbd: fix use-after-free in smb_break_all_levII_oplock()")
Cc: stable@vger.kernel.org
Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
Signed-off-by: Steve French &lt;stfrench@microsoft.com&gt;
</content>
</entry>
<entry>
<title>treewide: Replace kmalloc with kmalloc_obj for non-scalar types</title>
<updated>2026-02-21T09:02:28Z</updated>
<author>
<name>Kees Cook</name>
<email>kees@kernel.org</email>
</author>
<published>2026-02-21T07:49:23Z</published>
<link rel='alternate' type='text/html' href='https://www.git.shady.money/linux/commit/?id=69050f8d6d075dc01af7a5f2f550a8067510366f'/>
<id>urn:sha1:69050f8d6d075dc01af7a5f2f550a8067510366f</id>
<content type='text'>
This is the result of running the Coccinelle script from
scripts/coccinelle/api/kmalloc_objs.cocci. The script is designed to
avoid scalar types (which need careful case-by-case checking), and
instead replace kmalloc-family calls that allocate struct or union
object instances:

Single allocations:	kmalloc(sizeof(TYPE), ...)
are replaced with:	kmalloc_obj(TYPE, ...)

Array allocations:	kmalloc_array(COUNT, sizeof(TYPE), ...)
are replaced with:	kmalloc_objs(TYPE, COUNT, ...)

Flex array allocations:	kmalloc(struct_size(PTR, FAM, COUNT), ...)
are replaced with:	kmalloc_flex(*PTR, FAM, COUNT, ...)

(where TYPE may also be *VAR)

The resulting allocations no longer return "void *", instead returning
"TYPE *".

Signed-off-by: Kees Cook &lt;kees@kernel.org&gt;
</content>
</entry>
<entry>
<title>ksmbd: rename smb2_get_msg to smb_get_msg</title>
<updated>2025-12-22T01:20:46Z</updated>
<author>
<name>Namjae Jeon</name>
<email>linkinjeon@kernel.org</email>
</author>
<published>2025-12-19T01:04:25Z</published>
<link rel='alternate' type='text/html' href='https://www.git.shady.money/linux/commit/?id=0b444cfd8b74ebce421ccd96eac9c495e536c92e'/>
<id>urn:sha1:0b444cfd8b74ebce421ccd96eac9c495e536c92e</id>
<content type='text'>
With the removal of the RFC1002 length field from the SMB header,
smb2_get_msg is now used to get the smb1 request from the request buffer.
Since this function is no longer exclusive to smb2 and now supports smb1
as well, This patch rename it to smb_get_msg to better reflect its usage.

Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
Signed-off-by: Steve French &lt;stfrench@microsoft.com&gt;
</content>
</entry>
<entry>
<title>smb: move create_durable_rsp_v2 to common/smb2pdu.h</title>
<updated>2025-12-01T03:11:44Z</updated>
<author>
<name>ChenXiaoSong</name>
<email>chenxiaosong@kylinos.cn</email>
</author>
<published>2025-11-02T07:30:50Z</published>
<link rel='alternate' type='text/html' href='https://www.git.shady.money/linux/commit/?id=96721fd292264d712b7b9a51752ab87de5035db4'/>
<id>urn:sha1:96721fd292264d712b7b9a51752ab87de5035db4</id>
<content type='text'>
Modify the following places:

  - some fields in "struct create_durable_v2_rsp" -&gt;
                       struct durable_context_v2_rsp
  - durable_reconnect_context_v2_rsp -&gt; durable_context_v2_rsp
  - create_durable_v2_rsp -&gt; create_durable_rsp_v2

Then move them to common header file.

Signed-off-by: ChenXiaoSong &lt;chenxiaosong@kylinos.cn&gt;
Acked-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
Signed-off-by: Steve French &lt;stfrench@microsoft.com&gt;
</content>
</entry>
<entry>
<title>ksmbd: fix refcount leak causing resource not released</title>
<updated>2025-08-18T00:33:29Z</updated>
<author>
<name>Ziyan Xu</name>
<email>ziyan@securitygossip.com</email>
</author>
<published>2025-08-16T01:20:05Z</published>
<link rel='alternate' type='text/html' href='https://www.git.shady.money/linux/commit/?id=89bb430f621124af39bb31763c4a8b504c9651e2'/>
<id>urn:sha1:89bb430f621124af39bb31763c4a8b504c9651e2</id>
<content type='text'>
When ksmbd_conn_releasing(opinfo-&gt;conn) returns true,the refcount was not
decremented properly, causing a refcount leak that prevents the count from
reaching zero and the memory from being released.

Cc: stable@vger.kernel.org
Signed-off-by: Ziyan Xu &lt;ziyan@securitygossip.com&gt;
Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
Signed-off-by: Steve French &lt;stfrench@microsoft.com&gt;
</content>
</entry>
<entry>
<title>ksmbd: use list_first_entry_or_null for opinfo_get_list()</title>
<updated>2025-05-22T03:30:39Z</updated>
<author>
<name>Namjae Jeon</name>
<email>linkinjeon@kernel.org</email>
</author>
<published>2025-05-20T00:25:03Z</published>
<link rel='alternate' type='text/html' href='https://www.git.shady.money/linux/commit/?id=10379171f346e6f61d30d9949500a8de4336444a'/>
<id>urn:sha1:10379171f346e6f61d30d9949500a8de4336444a</id>
<content type='text'>
The list_first_entry() macro never returns NULL.  If the list is
empty then it returns an invalid pointer.  Use list_first_entry_or_null()
to check if the list is empty.

Reported-by: kernel test robot &lt;lkp@intel.com&gt;
Reported-by: Dan Carpenter &lt;dan.carpenter@linaro.org&gt;
Closes: https://lore.kernel.org/r/202505080231.7OXwq4Te-lkp@intel.com/
Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
Signed-off-by: Steve French &lt;stfrench@microsoft.com&gt;
</content>
</entry>
</feed>
