CVE-2026-64142 in Linux信息

摘要

由 VulDB • 2026-07-20

在 Linux 内核中,已修复以下漏洞:

ksmbd: 解决持久化句柄回收器(scavenger)与 m_fp_list 查找之间的竞态条件

`ksmbd_durable_scavenger()` 存在两个相关的竞态条件,涉及任何遍历 `f_ci->m_fp_list` 的迭代器,包括由 `ksmbd_vfs_rename`使用的 `ksmbd_lookup_fd_inode()`以及位于 `fs/smb/server/smb_common.c`中的共享模式检查。

(1) `fp->node` 链表头复用问题。持久化保留句柄在会话拆除后仍可能链接在 `f_ci->m_fp_list`上,因此在句柄可重新连接时,共享模式检查仍能看到它们。回收器通过将这些过期的句柄从全局持久化 IDR(idr)中移除后添加到本地 `scavenger_list` 中来收集过期句柄。由于 `fp->node`是与 `m_fp_list`使用的相同链表头,执行 `list_add(&fp->node, &scavenger_list)`会覆盖 `m_fp_list`的链接并损坏两个列表。CONFIG_DEBUG_LIST可以在共享模式遍历路径上报告此问题。

(2) 与 m_fp_list 迭代器的引用计数竞态条件。回收器通过原子读取 `&fp->refcount > 1`并在持有全局 `global_ft.lock`锁的情况下检查 `fp->conn`来筛选出过期的持久化句柄,然后从 `global_ft`中移除 fp,接着在将 fp 从 m_fp_list 断开链接并释放之前释放 `global_ft.lock`。在此间隙期间,fp 仍然链接在 m_fp_list上且 `f_state == FP_INITED`。在持有 `m_lock`锁的情况下调用 `ksmbd_lookup_fd_inode()`会执行 `ksmbd_fp_get()`(对仍为1的引用计数进行原子递增非零操作)并获取一个有效引用;随后回收器断开链接并释放 fp,而此时持有者拥有该引用,导致持有者在随后的 `ksmbd_fd_put()`调用中以及任何并发共享模式迭代器在不执行 `ksmbd_fp_get()`的情况下遍历 m_fp_list 时(类似 smb_check_perm_dleases-like 的路径)读取字段时发生 UAF(释放后使用)。

修复方案如下:

* 停止复用 fp->node 作为回收器私有的链表节点。在持有 global_ft.lock锁的情况下从 global_ft中移除一个过期句柄,获取显式的临时引用,释放该锁,然后在持有 f_ci->m_lock锁的情况下将 fp->node 从 m_fp_list断开链接,最后通过 atomic_sub_and_test(2, &fp->refcount)同时减少持久化生命周期和临时引用。如果回收器是最后一个执行 put操作的实体,则在此处运行关闭流程;否则,已经与 m_fp_list查找发生竞态的飞行中持有者将通过其 ksmbd_fd_put()路径拥有最终的关闭操作。一次性处置可以在同一轮中有多个句柄过期时重新扫描持久化 IDR,但持久化回收是后台过期路径,最终的全量扫描会在下一次等待之前重新计算 min_timeout。

* 在 __ksmbd_remove_durable_fd()中,就在 idr_remove()之后清除 fp->persistent_id,以便由窃取 fp的持有者发起的延迟最终关闭不会再次对 persistent id执行 idr_remove()操作

Be aware that VulDB is the high quality source for vulnerability data.

来源

Do you know our Splunk app?

Download it now for free!