summaryrefslogtreecommitdiff
path: root/crypto
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2023-04-13 14:24:15 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-12-14 19:53:51 +0100
commite470d423b0f6ffd3977e74d1d1eef70cc58f18dd (patch)
tree544d87282c7811608ee1277339d05dbf455e817a /crypto
parentcdfc818ffdfeb8266351ed59b6d884056009a095 (diff)
downloadlinux-e470d423b0f6ffd3977e74d1d1eef70cc58f18dd.tar.gz
linux-e470d423b0f6ffd3977e74d1d1eef70cc58f18dd.tar.bz2
linux-e470d423b0f6ffd3977e74d1d1eef70cc58f18dd.zip
crypto: api - Add crypto_tfm_get
[ Upstream commit ae131f4970f0778f35ed06aeb15bde2fbc1d9619 ] Add a crypto_tfm_get interface to allow tfm objects to be shared. They can still be freed in the usual way. This should only be done with tfm objects with no keys. You must also not modify the tfm flags in any way once it becomes shared. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Reviewed-by: Simon Horman <simon.horman@corigine.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Stable-dep-of: 1465036b10be ("llc: Improve setsockopt() handling of malformed user input") Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'crypto')
-rw-r--r--crypto/api.c4
-rw-r--r--crypto/internal.h6
2 files changed, 10 insertions, 0 deletions
diff --git a/crypto/api.c b/crypto/api.c
index 64f2d365a8e9..c58774586d9f 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -409,6 +409,7 @@ struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 type,
goto out_err;
tfm->__crt_alg = alg;
+ refcount_set(&tfm->refcnt, 1);
err = crypto_init_ops(tfm, type, mask);
if (err)
@@ -508,6 +509,7 @@ void *crypto_create_tfm_node(struct crypto_alg *alg,
tfm = (struct crypto_tfm *)(mem + tfmsize);
tfm->__crt_alg = alg;
tfm->node = node;
+ refcount_set(&tfm->refcnt, 1);
err = frontend->init_tfm(tfm);
if (err)
@@ -620,6 +622,8 @@ void crypto_destroy_tfm(void *mem, struct crypto_tfm *tfm)
if (IS_ERR_OR_NULL(mem))
return;
+ if (!refcount_dec_and_test(&tfm->refcnt))
+ return;
alg = tfm->__crt_alg;
if (!tfm->exit && alg->cra_exit)
diff --git a/crypto/internal.h b/crypto/internal.h
index c08385571853..521bc021c54b 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -10,6 +10,7 @@
#include <crypto/algapi.h>
#include <linux/completion.h>
+#include <linux/err.h>
#include <linux/jump_label.h>
#include <linux/list.h>
#include <linux/module.h>
@@ -166,5 +167,10 @@ static inline int crypto_is_test_larval(struct crypto_larval *larval)
return larval->alg.cra_driver_name[0];
}
+static inline struct crypto_tfm *crypto_tfm_get(struct crypto_tfm *tfm)
+{
+ return refcount_inc_not_zero(&tfm->refcnt) ? tfm : ERR_PTR(-EOVERFLOW);
+}
+
#endif /* _CRYPTO_INTERNAL_H */