[PATCH v3] Fix multiple issues in chcr driver:
From: Wentao Liang
Date: Mon Jun 22 2026 - 11:19:27 EST
1. In chcr_ahash_final() and chcr_ahash_digest(), chcr_send_wr()
return value is not checked. If it fails, DMA buffers are not
unmapped, causing leaks.
2. In chcr_aead_op(), the inflight counter is not decremented when
assoclen validation fails.
Fix by:
- Adding error handling for chcr_send_wr() with goto unmap
- Adding chcr_dec_wrcount() on the assoclen error path
Fix the following functions with missing decrement on error paths:
- chcr_aes_encrypt()
- chcr_aes_decrypt()
- chcr_aead_op()
For chcr_aes_encrypt() and chcr_aes_decrypt(), use a common error
label to decrement the counter. For chcr_aead_op(), use the existing
chcr_dec_wrcount() helper on the invalid assoclen error path.
Cc: stable@xxxxxxxxxxxxxxx
Fixes: b8fd1f4170e7 ("crypto: chcr - Add ctr mode and process large sg entries for cipher")
Fixes: d91a3159e8d9 ("Crypto/chcr: fix gcm-aes and rfc4106-gcm failed tests")
Fixes: 324429d74127 ("chcr: Support for Chelsio's Crypto Hardware")
Signed-off-by: Wentao Liang <vulab@xxxxxxxxxxx>
---
drivers/crypto/chelsio/chcr_algo.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/drivers/crypto/chelsio/chcr_algo.c b/drivers/crypto/chelsio/chcr_algo.c
index 6dec42282768..e431e8c1fdbd 100644
--- a/drivers/crypto/chelsio/chcr_algo.c
+++ b/drivers/crypto/chelsio/chcr_algo.c
@@ -1359,7 +1359,7 @@ static int chcr_aes_encrypt(struct skcipher_request *req)
err = process_cipher(req, u_ctx->lldi.rxq_ids[reqctx->rxqidx],
&skb, CHCR_ENCRYPT_OP);
if (err || !skb)
- return err;
+ goto error;
skb->dev = u_ctx->lldi.ports[0];
set_wr_txq(skb, CPL_PRIORITY_DATA, reqctx->txqidx);
chcr_send_wr(skb);
@@ -1402,11 +1402,15 @@ static int chcr_aes_decrypt(struct skcipher_request *req)
err = process_cipher(req, u_ctx->lldi.rxq_ids[reqctx->rxqidx],
&skb, CHCR_DECRYPT_OP);
if (err || !skb)
- return err;
+ goto error;
skb->dev = u_ctx->lldi.ports[0];
set_wr_txq(skb, CPL_PRIORITY_DATA, reqctx->txqidx);
chcr_send_wr(skb);
return -EINPROGRESS;
+
+error:
+ chcr_dec_wrcount(dev);
+ return err;
}
static int chcr_device_init(struct chcr_context *ctx)
{
@@ -1877,7 +1881,10 @@ static int chcr_ahash_finup(struct ahash_request *req)
req_ctx->hctx_wr.processed += params.sg_len;
skb->dev = u_ctx->lldi.ports[0];
set_wr_txq(skb, CPL_PRIORITY_DATA, req_ctx->txqidx);
- chcr_send_wr(skb);
+ if (chcr_send_wr(skb)) {
+ error = -EIO;
+ goto unmap;
+ }
return -EINPROGRESS;
unmap:
chcr_hash_dma_unmap(&u_ctx->lldi.pdev->dev, req);
@@ -1978,7 +1985,10 @@ static int chcr_ahash_digest(struct ahash_request *req)
req_ctx->hctx_wr.processed += params.sg_len;
skb->dev = u_ctx->lldi.ports[0];
set_wr_txq(skb, CPL_PRIORITY_DATA, req_ctx->txqidx);
- chcr_send_wr(skb);
+ if (chcr_send_wr(skb)) {
+ error = -EIO;
+ goto unmap;
+ }
return -EINPROGRESS;
unmap:
chcr_hash_dma_unmap(&u_ctx->lldi.pdev->dev, req);
@@ -3636,6 +3646,7 @@ static int chcr_aead_op(struct aead_request *req,
crypto_ipsec_check_assoclen(req->assoclen) != 0) {
pr_err("RFC4106: Invalid value of assoclen %d\n",
req->assoclen);
+ chcr_dec_wrcount(cdev);
return -EINVAL;
}
--
2.39.5 (Apple Git-154)