* [PATCH v3] crypto: qat - fix active_devs leak on crypto alg registration failure
@ 2026-09-09 14:15 Ahsan Atta
0 siblings, 0 replies; only message in thread
From: Ahsan Atta @ 2026-09-09 14:15 UTC (permalink / raw)
To: herbert; +Cc: linux-crypto, qat-linux, Ahsan Atta, Giovanni Cabiddu,
Thomas Huth
adf_dev_start() registered both alg sets in a single condition.
If qat_algs_register() succeeds but qat_asym_algs_register() fails,
ADF_STATUS_CRYPTO_ALGS_REGISTERED is left clear, so adf_dev_stop() skips
qat_algs_unregister(): the skciphers and aeads stay registered with
active_devs stuck at 1, pinning the module.
Both helpers leak active_devs internally as well - they increment it and
return without decrementing when a crypto_register_*() call fails, and
the asym path also leaves the already-registered akcipher behind.
Split the registration in adf_dev_start() so that an asym failure
unregisters qat_algs, and unwind active_devs (and the akcipher) on the
error paths of both register helpers. While at it, propagate the error
code returned by the register helpers instead of a blanket -EFAULT.
Fixes: 9b2f33a1bfcd ("crypto: qat - fix unregistration of crypto algorithms")
Signed-off-by: Ahsan Atta <ahsan.atta@intel.com>
Reviewed-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
---
Changes in v3:
- Added Reviewed-by tag from Thomas Huth.
Changes in v2:
- adf_dev_start(): propagate the error code returned by qat_algs_register()
and qat_asym_algs_register() instead of returning a blanket -EFAULT.
.../crypto/intel/qat/qat_common/adf_init.c | 24 ++++++++++++-----
.../crypto/intel/qat/qat_common/qat_algs.c | 15 ++++++-----
.../intel/qat/qat_common/qat_asym_algs.c | 26 ++++++++++++++-----
3 files changed, 45 insertions(+), 20 deletions(-)
diff --git a/drivers/crypto/intel/qat/qat_common/adf_init.c b/drivers/crypto/intel/qat/qat_common/adf_init.c
index 3e39c53814de..81cb5e6c9f4a 100644
--- a/drivers/crypto/intel/qat/qat_common/adf_init.c
+++ b/drivers/crypto/intel/qat/qat_common/adf_init.c
@@ -260,13 +260,23 @@ static int adf_dev_start(struct adf_accel_dev *accel_dev)
clear_bit(ADF_STATUS_STARTING, &accel_dev->status);
set_bit(ADF_STATUS_STARTED, &accel_dev->status);
- if (!list_empty(&accel_dev->crypto_list) &&
- (qat_algs_register() || qat_asym_algs_register())) {
- dev_err(&GET_DEV(accel_dev),
- "Failed to register crypto algs\n");
- set_bit(ADF_STATUS_STARTING, &accel_dev->status);
- clear_bit(ADF_STATUS_STARTED, &accel_dev->status);
- return -EFAULT;
+ if (!list_empty(&accel_dev->crypto_list)) {
+ ret = qat_algs_register();
+ if (ret) {
+ dev_err(&GET_DEV(accel_dev), "Failed to register crypto algs\n");
+ set_bit(ADF_STATUS_STARTING, &accel_dev->status);
+ clear_bit(ADF_STATUS_STARTED, &accel_dev->status);
+ return ret;
+ }
+
+ ret = qat_asym_algs_register();
+ if (ret) {
+ dev_err(&GET_DEV(accel_dev), "Failed to register crypto asym algs\n");
+ qat_algs_unregister();
+ set_bit(ADF_STATUS_STARTING, &accel_dev->status);
+ clear_bit(ADF_STATUS_STARTED, &accel_dev->status);
+ return ret;
+ }
}
set_bit(ADF_STATUS_CRYPTO_ALGS_REGISTERED, &accel_dev->status);
diff --git a/drivers/crypto/intel/qat/qat_common/qat_algs.c b/drivers/crypto/intel/qat/qat_common/qat_algs.c
index cb669fb66162..2ec19104787f 100644
--- a/drivers/crypto/intel/qat/qat_common/qat_algs.c
+++ b/drivers/crypto/intel/qat/qat_common/qat_algs.c
@@ -1319,19 +1319,22 @@ int qat_algs_register(void)
ret = crypto_register_skciphers(qat_skciphers,
ARRAY_SIZE(qat_skciphers));
if (ret)
- goto unlock;
+ goto err_dec;
ret = crypto_register_aeads(qat_aeads, ARRAY_SIZE(qat_aeads));
if (ret)
- goto unreg_algs;
+ goto err_unreg_skciphers;
-unlock:
mutex_unlock(&algs_lock);
- return ret;
+ return 0;
-unreg_algs:
+err_unreg_skciphers:
crypto_unregister_skciphers(qat_skciphers, ARRAY_SIZE(qat_skciphers));
- goto unlock;
+err_dec:
+ active_devs--;
+unlock:
+ mutex_unlock(&algs_lock);
+ return ret;
}
void qat_algs_unregister(void)
diff --git a/drivers/crypto/intel/qat/qat_common/qat_asym_algs.c b/drivers/crypto/intel/qat/qat_common/qat_asym_algs.c
index 1049c583f84f..77d59e977472 100644
--- a/drivers/crypto/intel/qat/qat_common/qat_asym_algs.c
+++ b/drivers/crypto/intel/qat/qat_common/qat_asym_algs.c
@@ -1340,13 +1340,25 @@ int qat_asym_algs_register(void)
int ret = 0;
mutex_lock(&algs_lock);
- if (++active_devs == 1) {
- rsa.base.cra_flags = 0;
- ret = crypto_register_akcipher(&rsa);
- if (ret)
- goto unlock;
- ret = crypto_register_kpp(&dh);
- }
+ if (++active_devs != 1)
+ goto unlock;
+
+ rsa.base.cra_flags = 0;
+ ret = crypto_register_akcipher(&rsa);
+ if (ret)
+ goto err_dec;
+
+ ret = crypto_register_kpp(&dh);
+ if (ret)
+ goto err_unreg_akcipher;
+
+ mutex_unlock(&algs_lock);
+ return 0;
+
+err_unreg_akcipher:
+ crypto_unregister_akcipher(&rsa);
+err_dec:
+ active_devs--;
unlock:
mutex_unlock(&algs_lock);
return ret;
--
2.50.1
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-09-09 14:15 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-09 14:15 [PATCH v3] crypto: qat - fix active_devs leak on crypto alg registration failure Ahsan Atta
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox