Commit 5aa58c3a authored by Douya Le's avatar Douya Le Committed by Herbert Xu
Browse files

crypto: algif_aead - snapshot IV for async AEAD requests



AF_ALG AEAD AIO requests currently use the socket-wide IV buffer during
request processing.  For async requests, later socket activity can
update that shared state before the original request has fully
completed, which can lead to inconsistent IV handling.

Snapshot the IV into per-request storage when preparing the AEAD
request, so in-flight operations no longer depend on mutable socket
state.

Fixes: d887c52d ("crypto: algif_aead - overhaul memory management")
Cc: stable@kernel.org
Reported-by: default avatarYuan Tan <yuantan098@gmail.com>
Reported-by: default avatarYifan Wu <yifanwucs@gmail.com>
Reported-by: default avatarJuefei Pu <tomapufckgml@gmail.com>
Reported-by: default avatarXin Liu <bird@lzu.edu.cn>
Co-developed-by: default avatarLuxing Yin <tr0jan@lzu.edu.cn>
Signed-off-by: default avatarLuxing Yin <tr0jan@lzu.edu.cn>
Tested-by: default avatarYucheng Lu <kanolyc@gmail.com>
Signed-off-by: default avatarDouya Le <ldy3087146292@gmail.com>
Signed-off-by: default avatarRen Wei <n05ec@lzu.edu.cn>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent d7e20b9b
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -72,8 +72,10 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
	struct af_alg_ctx *ctx = ask->private;
	struct crypto_aead *tfm = pask->private;
	unsigned int as = crypto_aead_authsize(tfm);
	unsigned int ivsize = crypto_aead_ivsize(tfm);
	struct af_alg_async_req *areq;
	struct scatterlist *rsgl_src, *tsgl_src = NULL;
	void *iv;
	int err = 0;
	size_t used = 0;		/* [in]  TX bufs to be en/decrypted */
	size_t outlen = 0;		/* [out] RX bufs produced by kernel */
@@ -125,10 +127,14 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,

	/* Allocate cipher request for current operation. */
	areq = af_alg_alloc_areq(sk, sizeof(struct af_alg_async_req) +
				     crypto_aead_reqsize(tfm));
				     crypto_aead_reqsize(tfm) + ivsize);
	if (IS_ERR(areq))
		return PTR_ERR(areq);

	iv = (u8 *)aead_request_ctx(&areq->cra_u.aead_req) +
	     crypto_aead_reqsize(tfm);
	memcpy(iv, ctx->iv, ivsize);

	/* convert iovecs of output buffers into RX SGL */
	err = af_alg_get_rsgl(sk, msg, flags, areq, outlen, &usedpages);
	if (err)
@@ -187,7 +193,7 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,

	/* Initialize the crypto operation */
	aead_request_set_crypt(&areq->cra_u.aead_req, tsgl_src,
			       areq->first_rsgl.sgl.sgt.sgl, used, ctx->iv);
			       areq->first_rsgl.sgl.sgt.sgl, used, iv);
	aead_request_set_ad(&areq->cra_u.aead_req, ctx->aead_assoclen);
	aead_request_set_tfm(&areq->cra_u.aead_req, tfm);