CVE-2026-89485: lockd: pin next file across nlm_inspect_file lock-drop
In the Linux kernel, the following vulnerability has been resolved:
lockd: pin next file across nlminspectfile lock-drop
nlmtraversefiles() pins the current file with fcount++ across a mutexunlock for nlminspectfile(), but nothing pins the saved next pointer. A concurrent nlmreleasefile() can kfree the next file during the unlock window, and the iterator dereferences freed memory on the next loop step.
Pin both current and next before the lock-drop. Advance by swapping the pinned cursors at the end of each iteration so next is always held alive across the unlock.
Always call nlmfilerelease() after dropping the iteration pin, regardless of whether the file matched the predicate. Use nlmfileinuse(), which does a live walk of the inode lock list, rather than the cached flocks field, so skipped files that never ran nlminspectfile() are evaluated correctly.
Because every file in a hash bucket is now pinned and released, files skipped by the isfailoverfile predicate that have no locks, blocks, shares, or external references are deleted during traversal. The old code never evaluated skipped files for cleanup. The new behavior is intentional: such files are stale and should not persist in the table.
Event History
Frequently Asked Questions
What conditions are required to trigger this issue?
The race requires nlm_traverse_files() to drop its mutex while processing a file and a concurrent nlm_release_file() to release the saved next file during that unlock window. The subsequent traversal step can then dereference the freed next-file object.
What is the practical effect of the fix besides preventing the use-after-free?
The fix pins both the current and next files throughout the lock-drop window, then releases iteration pins after use. It also evaluates skipped files for cleanup using a live inode lock-list walk, so stale files with no locks, blocks, shares, or external references may now be deleted during traversal; this behavior is intentional.