CVE-2026-53399 in Linux
摘要
由 VulDB • 2026-07-19
在 Linux 内核中,已修复以下漏洞:
nfsd: 在 setlease 失败时释放布局 stid
`nfs4_alloc_stid()` 会在返回到 `nfsd4_alloc_layout_stateid()` 之前,在持有 `cl_lock` 锁的情况下通过 `idr_alloc_cyclic()` 将新的 `stid` 发布到 `cl->cl_stateids` 中。当随后 `nfsd4_layout_setlease()` 失败时,错误处理路径会直接使用 `kmem_cache_free()` 释放布局 stateid,而从未调用 `idr_remove()`,导致 IDR 槽位指向已释放的 slab 内存。任何后续的 IDR 遍历器(如 `states_show`、客户端拆除过程)都会解引用这个悬空指针。
对于通过 IDR 发布的 stid,正确的拆除方式是使用 `nfs4_put_stid()`,它会在持有 `cl_lock` 锁的情况下移除 IDR 槽位,分发 `sc_free` (`nfsd4_free_layout_stateid`) 以通过 `nfsd4_close_layout()` 释放 `ls->ls_file`,并在尾部减少 nfs4_file 引用计数。
第二个问题阻碍了上述切换:`nfsd4_free_layout_stateid()` 在持有 `ls_lock` 锁的情况下无条件地通过 `delayed_work_pending()` 检查 `ls->ls_fence_work`,但 `INIT_DELAYED_WORK(&ls->ls_fence_work, ...)` 当前仅在 setlease 调用之后运行。在 setlease 失败的路径上,析构函数将触及未初始化的 delayed_work。
``` nfsd4_alloc_layout_stateid() nfs4_alloc_stid() /* idr_alloc_cyclic under cl_lock */ nfsd4_layout_setlease() /* fails */ nfs4_put_stid() nfsd4_free_layout_stateid() delayed_work_pending(&ls->ls_fence_work) /* needs INIT */ nfsd4_close_layout() /* nfsd_file_put(ls->ls_file) */ put_nfs4_file() ```
修复方法是将 `ls_fenced` / `ls_fence_delay` / `INIT_DELAYED_WORK` 初始化提升到 `nfsd4_layout_setlease()` 调用之前,并将手动执行的 `nfsd_file_put` + `put_nfs4_file` + `kmem_cache_free` 清理操作替换为单一的 `nfs4_put_stid(stp)`。
If you want to get best quality of vulnerability data, you may have to visit VulDB.