In the Linux kernel, the following vulnerability has been resolved:
lockd: pin next file across nlm_inspect_file lock-drop
nlm_traverse_files() pins the current file with f_count++ across
a mutex_unlock for nlm_inspect_file(), but nothing pins the saved
next pointer. A concurrent nlm_release_file() 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 nlm_file_release() after dropping the iteration pin,
regardless of whether the file matched the predicate. Use
nlm_file_inuse(), which does a live walk of the inode lock list,
rather than the cached f_locks field, so skipped files that never
ran nlm_inspect_file() are evaluated correctly.
Because every file in a hash bucket is now pinned and released,
files skipped by the is_failover_file 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.
CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
CVSS Score: 9.8
AV:N - lockd is the in-kernel NLM RPC server on TCP/UDP, reached by remote NFSv3 clients. nlm_traverse_files() runs on NLMPROC_FREE_ALL, and nlm_release_file() runs from LOCK/UNLOCK/TEST and from rpciod NLM_GRANTED_MSG completion, so the UAF is triggered by network NLM traffic.
AC:L - A remote NFS client can populate nlm_files via LOCK, send FREE_ALL to drop nlm_file_mutex inside nlm_traverse_files(), and concurrently complete in-flight GRANTED_MSG callbacks so rpciod's nlmsvc_grant_release() calls nlm_release_file() on the unpinned next object; the attacker drives both sides of the race.
PR:N - lockd_authenticate() accepts RPC_AUTH_NULL and RPC_AUTH_UNIX. FREE_ALL is not a privileged-port callback, and nlm_fopen() opens files with NFSD_MAY_BYPASS_GSS|NFSD_MAY_NLM, so no host account or capability is required.
UI:N - Exploitation uses only attacker-sent NLM RPCs (LOCK/FREE_ALL and grant-callback completion); no victim user or administrator action is required.
S:U - The use-after-free is in the host kernel's lockd file table and impacts that same kernel; it does not cross a VM, IOMMU, or other security-authority boundary.
C:H - The iterator dereferences a kfree'd struct nlm_file (list pointers, f_file[], f_count). This UAF lets an attacker reuse the slab object and obtain a kernel read primitive, so confidentiality impact is high.
I:H - The same nlm_file UAF is a kernel heap free of list nodes, mutex state, and struct file pointers, which can be sprayed for an arbitrary write and control-flow hijack, so integrity impact is high.
A:H - Walking the freed nlm_file in nlm_traverse_files() causes a kernel oops/panic (KASAN slab-use-after-free), so availability impact is high.
| Attack Vector |
Network |
Scope |
Unchanged |
| Attack Complexity |
Low |
Confidentiality Impact |
High |
| Privileges Required |
None |
Integrity Impact |
High |
| User Interaction |
None |
Availability Impact |
High |
AV:N - lockd is the in-kernel NLM RPC server on TCP/UDP, reached by remote NFSv3 clients. nlm_traverse_files() runs on NLMPROC_FREE_ALL, and nlm_release_file() runs from LOCK/UNLOCK/TEST and from rpciod NLM_GRANTED_MSG completion, so the UAF is triggered by network NLM traffic.
AC:L - A remote NFS client can populate nlm_files via LOCK, send FREE_ALL to drop nlm_file_mutex inside nlm_traverse_files(), and concurrently complete in-flight GRANTED_MSG callbacks so rpciod's nlmsvc_grant_release() calls nlm_release_file() on the unpinned next object; the attacker drives both sides of the race.
PR:N - lockd_authenticate() accepts RPC_AUTH_NULL and RPC_AUTH_UNIX. FREE_ALL is not a privileged-port callback, and nlm_fopen() opens files with NFSD_MAY_BYPASS_GSS|NFSD_MAY_NLM, so no host account or capability is required.
UI:N - Exploitation uses only attacker-sent NLM RPCs (LOCK/FREE_ALL and grant-callback completion); no victim user or administrator action is required.
S:U - The use-after-free is in the host kernel's lockd file table and impacts that same kernel; it does not cross a VM, IOMMU, or other security-authority boundary.
C:H - The iterator dereferences a kfree'd struct nlm_file (list pointers, f_file[], f_count). This UAF lets an attacker reuse the slab object and obtain a kernel read primitive, so confidentiality impact is high.
I:H - The same nlm_file UAF is a kernel heap free of list nodes, mutex state, and struct file pointers, which can be sprayed for an arbitrary write and control-flow hijack, so integrity impact is high.
A:H - Walking the freed nlm_file in nlm_traverse_files() causes a kernel oops/panic (KASAN slab-use-after-free), so availability impact is high.
CVSS 3.1