* ksmbd: unlocked iface_list free during server reset vs FSCTL_QUERY_NETWORK_INTERFACE_INFO traversal -> use-after-free (kernel oops)
@ 2026-09-23 8:47 朱浩
2026-09-23 9:22 ` Greg KH
0 siblings, 1 reply; 3+ messages in thread
From: 朱浩 @ 2026-09-23 8:47 UTC (permalink / raw)
To: security; +Cc: linkinjeon, linkinjeon, smfrench, sfrench, linux-cifs
[-- Attachment #1.1: Type: text/plain, Size: 7150 bytes --]
Hello,
I would like to privately report a use-after-free vulnerability in the Linux kernel SMB
server (ksmbd) that leads to a kernel oops (denial of service). The bug is present in the
current upstream master as of this writing.
-------------------------------------------------------------------
Summary
-------------------------------------------------------------------
ksmbd frees the global interface list (iface_list) without any lock during server
reset / hard-kill, *before* stop_sessions() is invoked. Meanwhile the
FSCTL_QUERY_NETWORK_INTERFACE_INFO ioctl handler traverses that same list while holding
only rtnl_lock (a lock the free path does not take), dereferencing freed iface nodes.
A remote authenticated SMB client that floods FSCTL_QUERY_NETWORK_INTERFACE_INFO while the
server is being reset can trigger a use-after-free read, producing a KASAN
slab-use-after-free report and a general protection fault (kernel oops / DoS).
-------------------------------------------------------------------
Affected component and versions
-------------------------------------------------------------------
Component: Linux kernel, fs/smb/server (ksmbd)
Confirmed present:
- Snapshot at commit af5226abb4 (6.15.0-rc3 era), where I reproduced it with KASAN.
- Current upstream master (checked 2026-09): ksmbd_tcp_destroy() still frees iface_list
without any lock, and ksmbd_find_netdev_name_iface_list() still traverses it holding
only rtnl_lock. No fix is present upstream as far as I can tell.
-------------------------------------------------------------------
Root cause (code references)
-------------------------------------------------------------------
1) The shared object:
fs/smb/server/transport_tcp.c
static LIST_HEAD(iface_list); // plain LIST_HEAD, no lock, no refcount
2) Freeing side (no lock):
fs/smb/server/transport_tcp.c : ksmbd_tcp_destroy()
unregister_netdevice_notifier(&ksmbd_netdev_notifier); // rtnl taken+released internally
list_for_each_entry_safe(iface, tmp, &iface_list, entry) {
list_del(&iface->entry); // entry->next becomes LIST_POISON under DEBUG_LIST
kfree(iface->name);
kfree(iface);
}
Call ordering (fs/smb/server/connection.c : ksmbd_conn_transport_destroy):
mutex_lock(&init_lock);
ksmbd_tcp_destroy(); // (A) frees iface_list
stop_sessions(); // (B) only afterwards stops the connection worker threads
mutex_unlock(&init_lock);
Because (A) runs before (B), the ksmbd-io workqueue workers that service in-flight SMB
requests are still active while iface_list is being freed.
3) Use side (unlocked traversal, holds only rtnl_lock):
fs/smb/server/smb2pdu.c : fsctl_query_iface_info_ioctl()
rtnl_lock();
for_each_netdev(&init_net, netdev) {
if (!ksmbd_find_netdev_name_iface_list(netdev->name)) // boolean gate
continue;
...
}
rtnl_unlock();
fs/smb/server/transport_tcp.c : ksmbd_find_netdev_name_iface_list()
list_for_each_entry(iface, &iface_list, entry)
if (!strcmp(iface->name, netdev_name)) // dereferences iface->name / walks iface->entry.next
return iface;
The traversal holds rtnl_lock; the free path does not take rtnl_lock. They are different
lock domains, so the free can proceed concurrently with the traversal.
-------------------------------------------------------------------
Trigger / reachability
-------------------------------------------------------------------
- Read side (attacker-controlled): any authenticated SMB session can issue
FSCTL_QUERY_NETWORK_INTERFACE_INFO (no_fileid_ioctl, FID = SMB2_NO_FID). No admin, no
open file, and (if the server allows guest) even weaker credentials suffice. Flooding this
ioctl from multiple connections keeps workers traversing iface_list.
- Free side (trigger): the server reset path runs when
(a) root writes "hard" to /sys/class/ksmbd-control/kill_server (kill_server_store), or
(b) the ksmbd userspace daemon heartbeat times out (server_queue_ctrl_reset_work).
These correspond to an administrator restarting / hard-killing the service.
- The race: a worker iterating iface_list (or mid-strcmp on a node) while the reset frees
that node -> use-after-free read of iface->name, or walking the list into LIST_POISON.
-------------------------------------------------------------------
Impact
-------------------------------------------------------------------
- KASAN reports "slab-use-after-free in ksmbd_find_netdev_name_iface_list".
- A subsequent general protection fault (non-canonical LIST_POISON dereference) -> kernel oops.
- Denial of service: with panic_on_oops the machine panics; otherwise the worker is killed.
The list_del + kfree of the name and the node can also leave a dangling name pointer.
- This is a read-only UAF (no write primitive, no function-pointer in struct interface),
so the practical impact is kernel DoS rather than privilege escalation.
-------------------------------------------------------------------
Evidence
-------------------------------------------------------------------
Reproduced on the vulnerable kernel (6.15.0-rc3, KASAN enabled) with:
- a userspace SMB client flooding FSCTL_QUERY_NETWORK_INTERFACE_INFO (12 threads,
authenticated session, no open file), and
- a VM-side root writing "hard" to /sys/class/ksmbd-control/kill_server (reset loop).
KASAN report (abridged):
BUG: KASAN: slab-use-after-free in ksmbd_find_netdev_name_iface_list+0x64/0x90
Read of size 8 ... by task kworker/...
Call Trace:
fsctl_query_iface_info_ioctl.isra.0
smb2_ioctl
handle_ksmbd_work
Freed by task 1:
kfree
ksmbd_tcp_destroy
ksmbd_conn_transport_destroy
server_ctrl_handle_reset
kill_server_store <- the sysfs write that triggers the reset
The buggy address belongs to the object at ffff... which belongs to the cache kmalloc-96
...
Oops: general protection fault, probably for non-canonical address 0xdead...:
RIP: ksmbd_find_netdev_name_iface_list+0x48
I also have a self-contained userspace reproducer (python, SMB2 client) and the full KASAN
splat available; happy to share them on request.
-------------------------------------------------------------------
Suggested fix
-------------------------------------------------------------------
Any of:
1. Protect iface_list with a dedicated lock shared by ksmbd_tcp_destroy() and
ksmbd_find_netdev_name_iface_list() (and all other traversers);
2. Free the nodes via RCU and traverse under rcu_read_lock();
3. Reorder ksmbd_conn_transport_destroy() to run stop_sessions() before freeing iface_list.
-------------------------------------------------------------------
Credit
-------------------------------------------------------------------
Discovered and reported by:
Hao Zhu
Peking University and Unipat AI
Thank you for maintaining ksmbd. Please let me know if you need any additional detail or
the reproducer. I am happy to follow your embargo/disclosure timeline.
Best regards,
Hao Zhu
朱浩
2401112100@stu.pku.edu.cn
[-- Attachment #1.2: Type: text/html, Size: 11086 bytes --]
[-- Attachment #2: vuln_n1_iface_list_uaf.tar.gz --]
[-- Type: application/x-gzip, Size: 13728 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: ksmbd: unlocked iface_list free during server reset vs FSCTL_QUERY_NETWORK_INTERFACE_INFO traversal -> use-after-free (kernel oops)
2026-09-23 8:47 ksmbd: unlocked iface_list free during server reset vs FSCTL_QUERY_NETWORK_INTERFACE_INFO traversal -> use-after-free (kernel oops) 朱浩
@ 2026-09-23 9:22 ` Greg KH
[not found] ` <AK2AhgCLKwK9zwB7Ti6KtqpK.3.1790166059428.Hmail.2401112100@stu.pku.edu.cn>
0 siblings, 1 reply; 3+ messages in thread
From: Greg KH @ 2026-09-23 9:22 UTC (permalink / raw)
To: 朱浩
Cc: security, linkinjeon, linkinjeon, smfrench, sfrench, linux-cifs
On Wed, Sep 23, 2026 at 04:47:44PM +0800, 朱浩 wrote:
> Hello,
> I would like to privately report a use-after-free vulnerability in the Linux kernel SMB
> server (ksmbd) that leads to a kernel oops (denial of service). The bug is present in the
> current upstream master as of this writing.
> -------------------------------------------------------------------
> Summary
> -------------------------------------------------------------------
> ksmbd frees the global interface list (iface_list) without any lock during server
> reset / hard-kill, *before* stop_sessions() is invoked. Meanwhile the
> FSCTL_QUERY_NETWORK_INTERFACE_INFO ioctl handler traverses that same list while holding
> only rtnl_lock (a lock the free path does not take), dereferencing freed iface nodes.
> A remote authenticated SMB client that floods FSCTL_QUERY_NETWORK_INTERFACE_INFO while the
> server is being reset can trigger a use-after-free read, producing a KASAN
> slab-use-after-free report and a general protection fault (kernel oops / DoS).
> -------------------------------------------------------------------
> Affected component and versions
> -------------------------------------------------------------------
> Component: Linux kernel, fs/smb/server (ksmbd)
> Confirmed present:
> - Snapshot at commit af5226abb4 (6.15.0-rc3 era), where I reproduced it with KASAN.
That is very very very old and obsolete and known broken and buggy.
Please always test on the latest kernel version, hundreds, if not
thousands, of changes to the ksmbd code have happened since then.
> - Current upstream master (checked 2026-09): ksmbd_tcp_destroy() still frees iface_list
> without any lock, and ksmbd_find_netdev_name_iface_list() still traverses it holding
> only rtnl_lock. No fix is present upstream as far as I can tell.
Please test to verify.
> Suggested fix
> -------------------------------------------------------------------
> Any of:
> 1. Protect iface_list with a dedicated lock shared by ksmbd_tcp_destroy() and
> ksmbd_find_netdev_name_iface_list() (and all other traversers);
> 2. Free the nodes via RCU and traverse under rcu_read_lock();
> 3. Reorder ksmbd_conn_transport_destroy() to run stop_sessions() before freeing iface_list.
Please create a patch that can be applied to resolve the issue so that
you get full credit for this.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-09-23 12:36 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-23 8:47 ksmbd: unlocked iface_list free during server reset vs FSCTL_QUERY_NETWORK_INTERFACE_INFO traversal -> use-after-free (kernel oops) 朱浩
2026-09-23 9:22 ` Greg KH
[not found] ` <AK2AhgCLKwK9zwB7Ti6KtqpK.3.1790166059428.Hmail.2401112100@stu.pku.edu.cn>
2026-09-23 12:35 ` Greg KH
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox