Re: [PATCH] lockd: fix use-after-free in nlmsvc_retry_blocked()
From: Chuck Lever
Date: Wed Sep 30 2026 - 21:07:53 EST
Hi Abdifatah,
Thanks for looking at this code. I'm not going to take this patch,
for the reasons below.
On Wed, Sep 30, 2026 at 11:22:12PM +0300, Abdifatah Suruur wrote:
> Pin the block before dropping the spinlock in nlmsvc_retry_blocked()
> and release the pin after processing, so the block cannot be freed
> while it is in use.
This part is already fixed. The nfsd-testing branch carries
lockd: Fix use-after-free in nlmsvc_retry_blocked
lockd: Serialize block retries against host teardown
The first takes the same reference in the same place, so your patch
no longer applies there. For lockd and NFSD work, please base patches
on the nfsd-testing branch of
git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux.git
> nlmsvc_notify_blocked() has the same problem: it moves the block to
> the head of the list and then calls svc_wake_up(block->b_daemon)
> after dropping nlm_blocked_lock. Keep that wake-up under the
> spinlock, as nlmsvc_grant_deferred() already does.
This one appears to be unreachable.
nlmsvc_notify_blocked() is the lm_notify callback. It is called from
__locks_wake_up_blocks() with blocked_lock_lock held, and that
function clears waiter->flc_blocker only after lm_notify returns.
The block is on nlm_blocked when the callback finds it, so the list
holds a reference. A block whose file_lock is waiting comes off that
list through nlmsvc_unlink_block(), which calls locks_delete_block()
on the block's file_lock before it calls nlmsvc_remove_block(). That
covers GRANT_RES, CANCEL, nlmsvc_traverse_blocks(), and
nlmsvc_grant_blocked().
While the callback is running, flc_blocker is still set, so
locks_delete_block() cannot take its lockless early return. It has to
acquire blocked_lock_lock, and it waits there until the callback has
returned. The list reference therefore cannot be dropped between the
spin_unlock() and the svc_wake_up().
--
Chuck Lever (Come to NFS bake-a-thon! https://nfsv4bat.org)