Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4e3a61c5 authored by Iuliana Prodan's avatar Iuliana Prodan Committed by Herbert Xu
Browse files

crypto: caam - execute module exit point only if necessary



Commit 1b46c90c ("crypto: caam - convert top level drivers to libraries")
changed entry and exit points behavior for caamalg,
caamalg_qi, caamalg_qi2, caamhash, caampkc, caamrng.

For example, previously caam_pkc_init() and caam_pkc_exit() were
module entry/exit points. This means that if an error would happen
in caam_pkc_init(), then caam_pkc_exit() wouldn't have been called.
After the mentioned commit, caam_pkc_init() and caam_pkc_exit()
are manually called - from jr.c. caam_pkc_exit() is called
unconditionally, even if caam_pkc_init() failed.

Added a global variable to keep the status of the algorithm
registration and free of resources.
The exit point of caampkc/caamrng module is executed only if the
registration was successful. Therefore we avoid double free of
resources in case the algorithm registration failed.

Fixes: 1b46c90c ("crypto: caam - convert top level drivers to libraries")
Signed-off-by: default avatarIuliana Prodan <iuliana.prodan@nxp.com>
Reviewed-by: default avatarHoria Geanta <horia.geanta@nxp.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent c59a1d41
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -29,6 +29,12 @@
/* buffer filled with zeros, used for padding */
static u8 *zero_buffer;

/*
 * variable used to avoid double free of resources in case
 * algorithm registration was unsuccessful
 */
static bool init_done;

static void rsa_io_unmap(struct device *dev, struct rsa_edesc *edesc,
			 struct akcipher_request *req)
{
@@ -1076,6 +1082,7 @@ int caam_pkc_init(struct device *ctrldev)
	struct caam_drv_private *priv = dev_get_drvdata(ctrldev);
	u32 pk_inst;
	int err;
	init_done = false;

	/* Determine public key hardware accelerator presence. */
	if (priv->era < 10)
@@ -1100,6 +1107,7 @@ int caam_pkc_init(struct device *ctrldev)
		dev_warn(ctrldev, "%s alg registration failed\n",
			 caam_rsa.base.cra_driver_name);
	} else {
		init_done = true;
		dev_info(ctrldev, "caam pkc algorithms registered in /proc/crypto\n");
	}

@@ -1108,6 +1116,9 @@ int caam_pkc_init(struct device *ctrldev)

void caam_pkc_exit(void)
{
	if (!init_done)
		return;

	kfree(zero_buffer);
	crypto_unregister_akcipher(&caam_rsa);
}
+13 −1
Original line number Diff line number Diff line
@@ -80,6 +80,12 @@ struct caam_rng_ctx {

static struct caam_rng_ctx *rng_ctx;

/*
 * Variable used to avoid double free of resources in case
 * algorithm registration was unsuccessful
 */
static bool init_done;

static inline void rng_unmap_buf(struct device *jrdev, struct buf_data *bd)
{
	if (bd->addr)
@@ -296,6 +302,9 @@ static struct hwrng caam_rng = {

void caam_rng_exit(void)
{
	if (!init_done)
		return;

	caam_jr_free(rng_ctx->jrdev);
	hwrng_unregister(&caam_rng);
	kfree(rng_ctx);
@@ -307,6 +316,7 @@ int caam_rng_init(struct device *ctrldev)
	u32 rng_inst;
	struct caam_drv_private *priv = dev_get_drvdata(ctrldev);
	int err;
	init_done = false;

	/* Check for an instantiated RNG before registration */
	if (priv->era < 10)
@@ -335,8 +345,10 @@ int caam_rng_init(struct device *ctrldev)
	dev_info(dev, "registering rng-caam\n");

	err = hwrng_register(&caam_rng);
	if (!err)
	if (!err) {
		init_done = true;
		return err;
	}

free_rng_ctx:
	kfree(rng_ctx);