* [PATCH v2] crypto: ixp4xx - fix buffer chain unwind on allocation failure
@ 2026-04-23 11:19 Ruoyu Wang
2026-04-24 7:50 ` Linus Walleij
2026-05-05 9:24 ` Herbert Xu
0 siblings, 2 replies; 3+ messages in thread
From: Ruoyu Wang @ 2026-04-23 11:19 UTC (permalink / raw)
To: Herbert Xu, Corentin Labbe, linux-crypto
Cc: Linus Walleij, Imre Kaloz, David S . Miller, linux-arm-kernel,
linux-kernel, Ruoyu Wang
chainup_buffers() builds a linked list of buffer descriptors for a
scatterlist. If dma_pool_alloc() fails while constructing the list, the
current code sets buf to NULL and later dereferences it unconditionally
at the end of the function:
buf->next = NULL;
buf->phys_next = 0;
This can lead to a null-pointer dereference on allocation failure.
If the failure happens after part of the descriptor chain has already
been allocated and DMA-mapped, the partially constructed chain also
needs to be released.
Fix this by terminating the partially constructed chain on allocation
failure and letting the callers unwind it via their existing cleanup
paths. Also fix ablk_perform() to preserve the hook pointers before
checking for failure, so partially built chains can be freed correctly.
Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
---
v2:
- Keep the unwind path in the callers, per Herbert Xu's feedback.
- Terminate the partial chain before returning NULL on allocation failure.
- Save the hook pointers in ablk_perform() before checking the return value.
- Thanks to Herbert Xu for the review.
drivers/crypto/intel/ixp4xx/ixp4xx_crypto.c | 25 ++++++++++++---------
1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/drivers/crypto/intel/ixp4xx/ixp4xx_crypto.c b/drivers/crypto/intel/ixp4xx/ixp4xx_crypto.c
index fcc0cf4df..5b90cf0fb 100644
--- a/drivers/crypto/intel/ixp4xx/ixp4xx_crypto.c
+++ b/drivers/crypto/intel/ixp4xx/ixp4xx_crypto.c
@@ -884,8 +884,9 @@ static struct buffer_desc *chainup_buffers(struct device *dev,
ptr = sg_virt(sg);
next_buf = dma_pool_alloc(buffer_pool, flags, &next_buf_phys);
if (!next_buf) {
- buf = NULL;
- break;
+ buf->next = NULL;
+ buf->phys_next = 0;
+ return NULL;
}
sg_dma_address(sg) = dma_map_single(dev, ptr, len, dir);
buf->next = next_buf;
@@ -983,7 +984,7 @@ static int ablk_perform(struct skcipher_request *req, int encrypt)
unsigned int nbytes = req->cryptlen;
enum dma_data_direction src_direction = DMA_BIDIRECTIONAL;
struct ablk_ctx *req_ctx = skcipher_request_ctx(req);
- struct buffer_desc src_hook;
+ struct buffer_desc *buf, src_hook;
struct device *dev = &pdev->dev;
unsigned int offset;
gfp_t flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ?
@@ -1025,22 +1026,24 @@ static int ablk_perform(struct skcipher_request *req, int encrypt)
/* This was never tested by Intel
* for more than one dst buffer, I think. */
req_ctx->dst = NULL;
- if (!chainup_buffers(dev, req->dst, nbytes, &dst_hook,
- flags, DMA_FROM_DEVICE))
- goto free_buf_dest;
- src_direction = DMA_TO_DEVICE;
+ buf = chainup_buffers(dev, req->dst, nbytes, &dst_hook,
+ flags, DMA_FROM_DEVICE);
req_ctx->dst = dst_hook.next;
crypt->dst_buf = dst_hook.phys_next;
+ if (!buf)
+ goto free_buf_dest;
+ src_direction = DMA_TO_DEVICE;
} else {
req_ctx->dst = NULL;
}
req_ctx->src = NULL;
- if (!chainup_buffers(dev, req->src, nbytes, &src_hook, flags,
- src_direction))
- goto free_buf_src;
-
+ buf = chainup_buffers(dev, req->src, nbytes, &src_hook, flags,
+ src_direction);
req_ctx->src = src_hook.next;
crypt->src_buf = src_hook.phys_next;
+ if (!buf)
+ goto free_buf_src;
+
crypt->ctl_flags |= CTL_FLAG_PERFORM_ABLK;
qmgr_put_entry(send_qid, crypt_virt2phys(crypt));
BUG_ON(qmgr_stat_overflow(send_qid));
--
2.43.0
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH v2] crypto: ixp4xx - fix buffer chain unwind on allocation failure
2026-04-23 11:19 [PATCH v2] crypto: ixp4xx - fix buffer chain unwind on allocation failure Ruoyu Wang
@ 2026-04-24 7:50 ` Linus Walleij
2026-05-05 9:24 ` Herbert Xu
1 sibling, 0 replies; 3+ messages in thread
From: Linus Walleij @ 2026-04-24 7:50 UTC (permalink / raw)
To: Ruoyu Wang
Cc: Herbert Xu, Corentin Labbe, linux-crypto, Imre Kaloz,
David S . Miller, linux-arm-kernel, linux-kernel
On Thu, Apr 23, 2026 at 1:20 PM Ruoyu Wang <ruoyuw560@gmail.com> wrote:
> chainup_buffers() builds a linked list of buffer descriptors for a
> scatterlist. If dma_pool_alloc() fails while constructing the list, the
> current code sets buf to NULL and later dereferences it unconditionally
> at the end of the function:
>
> buf->next = NULL;
> buf->phys_next = 0;
>
> This can lead to a null-pointer dereference on allocation failure.
>
> If the failure happens after part of the descriptor chain has already
> been allocated and DMA-mapped, the partially constructed chain also
> needs to be released.
>
> Fix this by terminating the partially constructed chain on allocation
> failure and letting the callers unwind it via their existing cleanup
> paths. Also fix ablk_perform() to preserve the hook pointers before
> checking for failure, so partially built chains can be freed correctly.
>
> Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
Essentially I think Corentin & Herbert are better at reviewing this code
but it sure looks good to me!
Acked-by: Linus Walleij <linusw@kernel.org>
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH v2] crypto: ixp4xx - fix buffer chain unwind on allocation failure
2026-04-23 11:19 [PATCH v2] crypto: ixp4xx - fix buffer chain unwind on allocation failure Ruoyu Wang
2026-04-24 7:50 ` Linus Walleij
@ 2026-05-05 9:24 ` Herbert Xu
1 sibling, 0 replies; 3+ messages in thread
From: Herbert Xu @ 2026-05-05 9:24 UTC (permalink / raw)
To: Ruoyu Wang
Cc: Corentin Labbe, linux-crypto, Linus Walleij, Imre Kaloz,
David S . Miller, linux-arm-kernel, linux-kernel
On Thu, Apr 23, 2026 at 07:19:56PM +0800, Ruoyu Wang wrote:
> chainup_buffers() builds a linked list of buffer descriptors for a
> scatterlist. If dma_pool_alloc() fails while constructing the list, the
> current code sets buf to NULL and later dereferences it unconditionally
> at the end of the function:
>
> buf->next = NULL;
> buf->phys_next = 0;
>
> This can lead to a null-pointer dereference on allocation failure.
>
> If the failure happens after part of the descriptor chain has already
> been allocated and DMA-mapped, the partially constructed chain also
> needs to be released.
>
> Fix this by terminating the partially constructed chain on allocation
> failure and letting the callers unwind it via their existing cleanup
> paths. Also fix ablk_perform() to preserve the hook pointers before
> checking for failure, so partially built chains can be freed correctly.
>
> Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
> ---
> v2:
> - Keep the unwind path in the callers, per Herbert Xu's feedback.
> - Terminate the partial chain before returning NULL on allocation failure.
> - Save the hook pointers in ablk_perform() before checking the return value.
> - Thanks to Herbert Xu for the review.
>
> drivers/crypto/intel/ixp4xx/ixp4xx_crypto.c | 25 ++++++++++++---------
> 1 file changed, 14 insertions(+), 11 deletions(-)
Patch applied. Thanks.
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-05-05 9:24 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-23 11:19 [PATCH v2] crypto: ixp4xx - fix buffer chain unwind on allocation failure Ruoyu Wang
2026-04-24 7:50 ` Linus Walleij
2026-05-05 9:24 ` Herbert Xu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox