CVE-2026-89548: SUNRPC: always drain cache_cleaner before destroying a cache_detail
In the Linux kernel, the following vulnerability has been resolved:
SUNRPC: always drain cachecleaner before destroying a cachedetail
sunrpcdestroycachedetail() only cancels the global cachecleaner delayedwork when cachelist is empty. During per-netns teardown cachelist is never empty because initnet's caches remain registered, so the cancel never fires. After unlink, the caller proceeds to cachedestroynet() which kfrees the cachedetail while cacheclean() may still hold a dangling pointer to it. The result is a use-after-free: cachedequeue() takes cd->queuelock on freed memory, and cacheput() dereferences cd->cacheput as a function pointer from freed slab.
Drop the listempty guard so that canceldelayedworksync() always runs, ensuring any in-flight cacheclean() completes before the cachedetail is freed. Re-arm the cleaner afterwards if other caches are still registered.
Affected Software
Event History
Frequently Asked Questions
When is this vulnerability reachable?
It is reachable during per-network-namespace teardown when a cache_detail is destroyed while the global SUNRPC cache_cleaner delayed work can still be running. The condition occurs because init_net caches remain registered, leaving cache_list non-empty.
What could happen if the race is triggered?
The cleaner can access a freed cache_detail, causing a use-after-free. This includes taking queue_lock from freed memory and dereferencing the cache_put function pointer from freed slab memory.
What mitigation is described if the fix is not yet applied?
The provided data describes the corrective change: always run cancel_delayed_work_sync() before freeing cache_detail, then re-arm the cleaner if other caches remain registered. No separate operational workaround is provided.
How does the fix prevent the use-after-free?
It removes the cache_list-empty condition that prevented cancellation during per-netns teardown. Draining the delayed work ensures any in-flight cache_clean() finishes before cache_detail is freed.