On Sun, 9 Aug 2026, Runyu Xiao wrote:

> If the initial GFP_NOWAIT page allocation fails, crypt_alloc_buffer()
> sets __GFP_DIRECT_RECLAIM and retries while holding bio_alloc_lock. If a
> later page allocation fails, the retry edge bypasses the common unlock and
> reacquires the same mutex. This can deadlock the dm-crypt I/O path and
> leave I/O for the affected mapping stalled.

Hi

When __GFP_DIRECT_RECLAIM is set, mempool_alloc can't return NULL. So, the 
bug can't happen.

Mikulas

> Release the mutex before retrying, but only when this attempt took the
> direct-reclaim path; the first attempt did not acquire it.
> 
> This issue was identified by a static-analysis checker and manually
> confirmed by following the retry control flow in v6.1.66 and current
> mainline. A source-level control-flow check verified the vulnerable
> ordering and the unlock-before-retry ordering after this change. A small
> POSIX-thread model checked only the mutex re-acquisition condition; it does
> not exercise dm-crypt.
> 
> Fixes: 7145c241a1bf ("dm crypt: avoid deadlock in mempools")
> Cc: [email protected]
> Signed-off-by: Runyu Xiao <[email protected]>
> ---
>  drivers/md/dm-crypt.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
> index 608b617fb817..aabb9a5f85a7 100644
> --- a/drivers/md/dm-crypt.c
> +++ b/drivers/md/dm-crypt.c
> @@ -1674,6 +1674,8 @@ static struct bio *crypt_alloc_buffer(struct 
> dm_crypt_io *io, unsigned int size)
>               if (!pages) {
>                       crypt_free_buffer_pages(cc, clone);
>                       bio_put(clone);
> +                     if (unlikely(gfp_mask & __GFP_DIRECT_RECLAIM))
> +                             mutex_unlock(&cc->bio_alloc_lock);
>                       gfp_mask |= __GFP_DIRECT_RECLAIM;
>                       order = 0;
>                       goto retry;
> -- 
> 2.34.1
> 


Reply via email to