diff options
| author | Henry Hu <huhai@kylinos.cn> | 2026-09-12 00:35:14 +0800 |
|---|---|---|
| committer | Namjae Jeon <linkinjeon@kernel.org> | 2026-10-21 08:55:13 +0900 |
| commit | a63bb4d91c784f63ad7c063717dff7920d8445be (patch) | |
| tree | 37a5ea961a035910baa8bdce2a46f3bf6d248036 | |
| parent | 2bc1d25fc8597fa6cbf6b1ff92653881939a6436 (diff) | |
| download | linux-a63bb4d91c784f63ad7c063717dff7920d8445be.tar.gz linux-a63bb4d91c784f63ad7c063717dff7920d8445be.zip | |
ksmbd: fix unlocked IPv6 addr_list walk in fsctl_query_iface_info_ioctl()
fsctl_query_iface_info_ioctl() walks idev6->addr_list with a plain
list_for_each_entry() while holding only rtnl_lock(). rtnl does not
serialize all writers of this list: the DAD-failure path
(addrconf_dad_failure -> ipv6_add_addr) can insert addresses without
holding RTNL. It updates idev->addr_list with list_add_tail_rcu() under
write_lock_bh(&idev->lock), so it can race with the unlocked walk.
addr_list is RCU managed, so walk it with list_for_each_entry_rcu()
under rcu_read_lock(), matching the other lockless readers of the list.
Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3")
Reported-by: Sashiko <sashiko-bot+sashiko@kernel.org>
Link: https://sashiko.dev/#/patchset/20260910090818.24479-1-15815827059%40163.com
Co-developed-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
Signed-off-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
Signed-off-by: Henry Hu <huhai@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
| -rw-r--r-- | fs/smb/server/smb2pdu.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index 007a72005501..8563b7aa4289 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -10589,13 +10589,15 @@ ipv6_retry: if (!idev6) continue; - list_for_each_entry(ifa, &idev6->addr_list, if_list) { + rcu_read_lock(); + list_for_each_entry_rcu(ifa, &idev6->addr_list, if_list) { if (ifa->flags & (IFA_F_TENTATIVE | IFA_F_DEPRECATED)) continue; memcpy(ipv6_addr, ifa->addr.s6_addr, 16); break; } + rcu_read_unlock(); sockaddr_storage->addr6.ScopeId = 0; nbytes += sizeof(struct network_interface_info_ioctl_rsp); } |
