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
>