Re: [PATCH] crypto: algif_aead - stop recvmsg looping after a completed request

From: Herbert Xu

Date: Sun Jul 12 2026 - 21:53:08 EST


On Sun, Jun 28, 2026 at 05:34:15PM +0200, cyper@xxxxxxxxxxxx wrote:
> >From e0ed18c8ad9a7d2ecf939f0b97e2be0567180c1d Mon Sep 17 00:00:00 2001
> From: Qiguang Wang <cyper@xxxxxxxxxxxx>
> Date: Sat, 27 Jun 2026 21:49:55 +0000
> Subject: [PATCH] crypto: algif_aead - stop recvmsg looping after a completed
> request
> To: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx>
> Cc: "David S. Miller" <davem@xxxxxxxxxxxxx>,
>     linux-crypto@xxxxxxxxxxxxxxx,
>     linux-kernel@xxxxxxxxxxxxxxx
>
> A blocking recvmsg()/read() into an output buffer larger than the cipher
> result hangs forever.
>
> After the first pass of the "while (msg_data_left(msg))" loop in
> aead_recvmsg() (and the identical loop in skcipher_recvmsg()) produces
> the result, af_alg_get_rsgl() has consumed only as many bytes from the
> output iterator as the cipher produced, so msg_data_left() is still
> non-zero and the loop runs a second pass.  By then af_alg_pull_tsgl()
> has executed
>
> ctx->init = ctx->more;
>
> which, for a request that was not flagged MSG_MORE, resets ctx->init to
> 0 and drains ctx->used.  The second pass therefore takes the
> _aead_recvmsg()/_skcipher_recvmsg() gate
>
> if (!ctx->init || ctx->more)
> err = af_alg_wait_for_data(sk, flags, 0);
>
> and af_alg_wait_for_data() blocks on
>
> ctx->init && (!ctx->more || (min && ctx->used >= min))
>
> which can never become true again (ctx->init == 0, min == 0), so the
> task sleeps in MAX_SCHEDULE_TIMEOUT forever even though the result was
> already produced in pass 1.

The point of this loop is to wait for a new sendmsg on the socket
which is supposed to set ctx->init to true again. So are you saying
that even a new sendmsg cannot get out of this wait?

Thanks,
--
Email: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt