[PATCH v3 0/2] lockd: Fix two teardown races in the block retry loop
Chuck Lever <[email protected]>
| Newsgroups | org.kernel.vger.linux-nfs |
|---|---|
| Message-ID | <[email protected]> |
nlmsvc_retry_blocked() is the only path that operates on a block with nlm_blocked_lock dropped. Both defects live in that window. Shuangpeng Bai's KASAN report catches one of them, a block freed while the retry is still using it. sashiko-bot flagged the other while reviewing v1. The retry re-queues a block that the teardown scan has already retired, so the host that block pins is never reaped. Patch 1 fixes the first and applies without patch 2, so it can be backported on its own. Patch 2 is meant for mainline only. The race it closes leaks a host, and closing it widens the f_mutex hold across the retry loop. v2 added a B_DEAD flag that makes nlmsvc_insert_block() refuse to queue a retired block. That appeared to repair the second race, but it doesn't work. Every caller relies on that insert to take the list reference, so a refused insert lets nlmsvc_grant_blocked() drop the last reference to a block whose file_lock the VFS still has queued on a blocker. Signed-off-by: Chuck Lever <[email protected]> --- Changes in v3: - Split the fix in two. Patch 1 is the block reference alone. - Drop B_DEAD. A refused insert could free a live block (sashiko-bot). - Serialize the retry against nlmsvc_traverse_blocks() with f_mutex. - Link to v2: https://lore.kernel.org/r/[email protected] Changes in v2: - Add B_DEAD so a retry cannot requeue a retired block (sashiko-bot). - Link to v1: https://lore.kernel.org/r/[email protected] --- Chuck Lever (2): lockd: Fix use-after-free in nlmsvc_retry_blocked lockd: Serialize block retries against host teardown fs/lockd/svclock.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) --- base-commit: 01c2994ccb0197cb44b0db89aacab460110f6347 change-id: 20260820-lockd-retry-blocked-uaf-68f6b50098d9 Best regards, -- Chuck Lever