mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
crypto: qat - fix active_devs leak on crypto alg registration failure
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: 9b2f33a1bf ("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>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
1e4d31c4eb
commit
178829f1b5
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
mutex_unlock(&algs_lock);
|
||||
return 0;
|
||||
|
||||
err_unreg_skciphers:
|
||||
crypto_unregister_skciphers(qat_skciphers, ARRAY_SIZE(qat_skciphers));
|
||||
err_dec:
|
||||
active_devs--;
|
||||
unlock:
|
||||
mutex_unlock(&algs_lock);
|
||||
return ret;
|
||||
|
||||
unreg_algs:
|
||||
crypto_unregister_skciphers(qat_skciphers, ARRAY_SIZE(qat_skciphers));
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
void qat_algs_unregister(void)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user