VYPR
Unrated severityNVD Advisory· Published May 27, 2026· Updated May 27, 2026

CVE-2026-46028

CVE-2026-46028

Description

In the Linux kernel, the following vulnerability has been resolved:

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.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

A race condition in the Linux kernel's AF_ALG AEAD interface allows inconsistent IV handling for async requests, fixed by snapshotting the IV per request.

Vulnerability

In the Linux kernel's algif_aead module, AF_ALG AEAD AIO requests use a socket-wide IV buffer during request processing. For asynchronous (async) AEAD requests, later socket activity can update that shared state before the original request has fully completed, leading to inconsistent IV handling. This affects all kernel versions where the algif_aead interface supports async operations. The fix is introduced in commit [1].

Exploitation

An attacker with access to the AF_ALG socket interface (requires CAP_NET_ADMIN or being in the aalg group) can trigger the race condition by sending multiple AEAD requests, some of which are async, while simultaneously modifying the IV via socket operations. The race window is timing-dependent and may require precise interleaving of operations.

Impact

Successful exploitation could lead to incorrect IV usage in AEAD operations, potentially causing data corruption or information disclosure in cryptographic operations that rely on the IV. The attacker may be able to influence the IV used in a subsequent operation, breaking the cryptographic guarantees.

Mitigation

The fix is included in the Linux kernel commit [1] and is expected to be backported to stable kernels. Users should update to a kernel containing this commit. No workaround is available without patching. The vulnerability is not listed in CISA's Known Exploited Vulnerabilities catalog.

AI Insight generated on May 27, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

1

Patches

16
08ea39a556ec

crypto: algif_aead - snapshot IV for async AEAD requests

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitDouya LeApr 30, 2026Fixed in 5.10.254via kernel-cna
1 file changed · +8 3
  • crypto/algif_aead.c+8 3 modified
    diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
    index f59728c021fc85..24e77f4968a615 100644
    --- a/crypto/algif_aead.c
    +++ b/crypto/algif_aead.c
    @@ -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.sg, used, ctx->iv);
    +			       areq->first_rsgl.sgl.sg, used, iv);
     	aead_request_set_ad(&areq->cra_u.aead_req, ctx->aead_assoclen);
     	aead_request_set_tfm(&areq->cra_u.aead_req, tfm);
     
    -- 
    cgit 1.3-korg
    
    
    
a920cabdb0b7

crypto: algif_aead - snapshot IV for async AEAD requests

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitDouya LeApr 30, 2026Fixed in 5.15.204via kernel-cna
1 file changed · +8 3
  • crypto/algif_aead.c+8 3 modified
    diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
    index f59728c021fc85..24e77f4968a615 100644
    --- a/crypto/algif_aead.c
    +++ b/crypto/algif_aead.c
    @@ -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.sg, used, ctx->iv);
    +			       areq->first_rsgl.sgl.sg, used, iv);
     	aead_request_set_ad(&areq->cra_u.aead_req, ctx->aead_assoclen);
     	aead_request_set_tfm(&areq->cra_u.aead_req, tfm);
     
    -- 
    cgit 1.3-korg
    
    
    
fa0fcec9b49d

crypto: algif_aead - snapshot IV for async AEAD requests

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitDouya LeApr 30, 2026Fixed in 6.1.170via kernel-cna
1 file changed · +8 3
  • crypto/algif_aead.c+8 3 modified
    diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
    index f59728c021fc85..24e77f4968a615 100644
    --- a/crypto/algif_aead.c
    +++ b/crypto/algif_aead.c
    @@ -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.sg, used, ctx->iv);
    +			       areq->first_rsgl.sgl.sg, used, iv);
     	aead_request_set_ad(&areq->cra_u.aead_req, ctx->aead_assoclen);
     	aead_request_set_tfm(&areq->cra_u.aead_req, tfm);
     
    -- 
    cgit 1.3-korg
    
    
    
46fdb39e8322

crypto: algif_aead - snapshot IV for async AEAD requests

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitDouya LeApr 30, 2026Fixed in 6.12.85via kernel-cna
1 file changed · +8 3
  • crypto/algif_aead.c+8 3 modified
    diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
    index f8bd45f7dc8392..cb651ab58d6293 100644
    --- a/crypto/algif_aead.c
    +++ b/crypto/algif_aead.c
    @@ -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);
     
    -- 
    cgit 1.3-korg
    
    
    
c2138c9bd02a

crypto: algif_aead - snapshot IV for async AEAD requests

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitDouya LeApr 30, 2026Fixed in 6.6.137via kernel-cna
1 file changed · +8 3
  • crypto/algif_aead.c+8 3 modified
    diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
    index f8bd45f7dc8392..cb651ab58d6293 100644
    --- a/crypto/algif_aead.c
    +++ b/crypto/algif_aead.c
    @@ -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);
     
    -- 
    cgit 1.3-korg
    
    
    
3d72f8c6490d

crypto: algif_aead - snapshot IV for async AEAD requests

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitDouya LeApr 19, 2026Fixed in 7.0.4via kernel-cna
1 file changed · +8 3
  • crypto/algif_aead.c+8 3 modified
    diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
    index f8bd45f7dc8392..cb651ab58d6293 100644
    --- a/crypto/algif_aead.c
    +++ b/crypto/algif_aead.c
    @@ -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);
     
    -- 
    cgit 1.3-korg
    
    
    
5aa58c3a572b

crypto: algif_aead - snapshot IV for async AEAD requests

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitDouya LeApr 19, 2026Fixed in 7.1-rc1via kernel-cna
1 file changed · +8 3
  • crypto/algif_aead.c+8 3 modified
    diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
    index f8bd45f7dc8392..cb651ab58d6293 100644
    --- a/crypto/algif_aead.c
    +++ b/crypto/algif_aead.c
    @@ -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);
     
    -- 
    cgit 1.3-korg
    
    
    
ebc235675f24

crypto: algif_aead - snapshot IV for async AEAD requests

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitDouya LeApr 19, 2026Fixed in 6.18.27via kernel-cna
1 file changed · +8 3
  • crypto/algif_aead.c+8 3 modified
    diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
    index f8bd45f7dc8392..cb651ab58d6293 100644
    --- a/crypto/algif_aead.c
    +++ b/crypto/algif_aead.c
    @@ -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);
     
    -- 
    cgit 1.3-korg
    
    
    
08ea39a556ec

crypto: algif_aead - snapshot IV for async AEAD requests

1 file changed · +8 3
  • crypto/algif_aead.c+8 3 modified
    diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
    index f59728c021fc85..24e77f4968a615 100644
    --- a/crypto/algif_aead.c
    +++ b/crypto/algif_aead.c
    @@ -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.sg, used, ctx->iv);
    +			       areq->first_rsgl.sgl.sg, used, iv);
     	aead_request_set_ad(&areq->cra_u.aead_req, ctx->aead_assoclen);
     	aead_request_set_tfm(&areq->cra_u.aead_req, tfm);
     
    -- 
    cgit 1.3-korg
    
    
    
a920cabdb0b7

crypto: algif_aead - snapshot IV for async AEAD requests

1 file changed · +8 3
  • crypto/algif_aead.c+8 3 modified
    diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
    index f59728c021fc85..24e77f4968a615 100644
    --- a/crypto/algif_aead.c
    +++ b/crypto/algif_aead.c
    @@ -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.sg, used, ctx->iv);
    +			       areq->first_rsgl.sgl.sg, used, iv);
     	aead_request_set_ad(&areq->cra_u.aead_req, ctx->aead_assoclen);
     	aead_request_set_tfm(&areq->cra_u.aead_req, tfm);
     
    -- 
    cgit 1.3-korg
    
    
    
fa0fcec9b49d

crypto: algif_aead - snapshot IV for async AEAD requests

1 file changed · +8 3
  • crypto/algif_aead.c+8 3 modified
    diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
    index f59728c021fc85..24e77f4968a615 100644
    --- a/crypto/algif_aead.c
    +++ b/crypto/algif_aead.c
    @@ -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.sg, used, ctx->iv);
    +			       areq->first_rsgl.sgl.sg, used, iv);
     	aead_request_set_ad(&areq->cra_u.aead_req, ctx->aead_assoclen);
     	aead_request_set_tfm(&areq->cra_u.aead_req, tfm);
     
    -- 
    cgit 1.3-korg
    
    
    
c2138c9bd02a

crypto: algif_aead - snapshot IV for async AEAD requests

1 file changed · +8 3
  • crypto/algif_aead.c+8 3 modified
    diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
    index f8bd45f7dc8392..cb651ab58d6293 100644
    --- a/crypto/algif_aead.c
    +++ b/crypto/algif_aead.c
    @@ -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);
     
    -- 
    cgit 1.3-korg
    
    
    
46fdb39e8322

crypto: algif_aead - snapshot IV for async AEAD requests

1 file changed · +8 3
  • crypto/algif_aead.c+8 3 modified
    diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
    index f8bd45f7dc8392..cb651ab58d6293 100644
    --- a/crypto/algif_aead.c
    +++ b/crypto/algif_aead.c
    @@ -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);
     
    -- 
    cgit 1.3-korg
    
    
    
ebc235675f24

crypto: algif_aead - snapshot IV for async AEAD requests

1 file changed · +8 3
  • crypto/algif_aead.c+8 3 modified
    diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
    index f8bd45f7dc8392..cb651ab58d6293 100644
    --- a/crypto/algif_aead.c
    +++ b/crypto/algif_aead.c
    @@ -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);
     
    -- 
    cgit 1.3-korg
    
    
    
5aa58c3a572b

crypto: algif_aead - snapshot IV for async AEAD requests

1 file changed · +8 3
  • crypto/algif_aead.c+8 3 modified
    diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
    index f8bd45f7dc8392..cb651ab58d6293 100644
    --- a/crypto/algif_aead.c
    +++ b/crypto/algif_aead.c
    @@ -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);
     
    -- 
    cgit 1.3-korg
    
    
    
3d72f8c6490d

crypto: algif_aead - snapshot IV for async AEAD requests

1 file changed · +8 3
  • crypto/algif_aead.c+8 3 modified
    diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
    index f8bd45f7dc8392..cb651ab58d6293 100644
    --- a/crypto/algif_aead.c
    +++ b/crypto/algif_aead.c
    @@ -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);
     
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"Shared mutable IV buffer (ctx->iv) used by async AEAD requests without snapshotting, allowing a race condition where concurrent socket operations corrupt the IV of an in-flight request."

Attack vector

An attacker with access to an AF_ALG AEAD socket can submit asynchronous AIO encryption/decryption requests. Because the kernel used the socket-wide IV buffer (`ctx->iv`) during request processing, a subsequent `sendmsg` or `recvmsg` call on the same socket could overwrite the IV before an earlier async request completes. This race condition can cause the crypto operation to use an incorrect or corrupted IV, leading to data corruption or information disclosure. The attacker needs only local access to create and use AF_ALG sockets; no special privileges are required beyond what is needed to open such sockets.

Affected code

The vulnerability resides in the `_aead_recvmsg` function in `crypto/algif_aead.c` [patch_id=2660303]. The function passed `ctx->iv` (the socket-wide IV buffer) directly to `aead_request_set_crypt`, making in-flight async AEAD requests depend on mutable socket state.

What the fix does

The patch makes three coordinated changes in `_aead_recvmsg` [patch_id=2660303]. First, it queries the IV size via `crypto_aead_ivsize(tfm)` and adds that extra space to the per-request allocation (`af_alg_alloc_areq`). Second, it copies `ctx->iv` into a private buffer (`iv`) located after the AEAD request context. Third, it passes this private `iv` pointer to `aead_request_set_crypt` instead of `ctx->iv`. This ensures each in-flight async request operates on its own snapshot of the IV, eliminating the race condition.

Preconditions

  • authLocal access to create AF_ALG AEAD sockets
  • inputAbility to submit asynchronous (AIO) AEAD requests on the same socket
  • inputConcurrent socket operations that modify ctx->iv before an async request completes

Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

8

News mentions

0

No linked articles in our index yet.