crypto: algapi - convert cra_refcnt to refcount_t
authorEric Biggers <ebiggers@google.com>
Fri, 29 Dec 2017 16:00:46 +0000 (10:00 -0600)
committerHerbert Xu <herbert@gondor.apana.org.au>
Fri, 5 Jan 2018 07:43:09 +0000 (18:43 +1100)
Reference counters should use refcount_t rather than atomic_t, since the
refcount_t implementation can prevent overflows, reducing the
exploitability of reference leak bugs.  crypto_alg.cra_refcount is a
reference counter with the usual semantics, so switch it over to
refcount_t.

Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
crypto/algapi.c
crypto/api.c
crypto/crypto_user.c
crypto/internal.h
crypto/proc.c
include/linux/crypto.h

index 60d7366ed343e9ad6a76b9dd36be22fbd7543c89..8084a76e01d848f0214cbe45a537a3d879c00c60 100644 (file)
@@ -62,7 +62,7 @@ static int crypto_check_alg(struct crypto_alg *alg)
        if (alg->cra_priority < 0)
                return -EINVAL;
 
-       atomic_set(&alg->cra_refcnt, 1);
+       refcount_set(&alg->cra_refcnt, 1);
 
        return crypto_set_driver_name(alg);
 }
@@ -224,7 +224,7 @@ static struct crypto_larval *__crypto_register_alg(struct crypto_alg *alg)
        if (!larval->adult)
                goto free_larval;
 
-       atomic_set(&larval->alg.cra_refcnt, 1);
+       refcount_set(&larval->alg.cra_refcnt, 1);
        memcpy(larval->alg.cra_driver_name, alg->cra_driver_name,
               CRYPTO_MAX_ALG_NAME);
        larval->alg.cra_priority = alg->cra_priority;
@@ -399,7 +399,7 @@ int crypto_unregister_alg(struct crypto_alg *alg)
        if (ret)
                return ret;
 
-       BUG_ON(atomic_read(&alg->cra_refcnt) != 1);
+       BUG_ON(refcount_read(&alg->cra_refcnt) != 1);
        if (alg->cra_destroy)
                alg->cra_destroy(alg);
 
@@ -490,7 +490,7 @@ void crypto_unregister_template(struct crypto_template *tmpl)
        up_write(&crypto_alg_sem);
 
        hlist_for_each_entry_safe(inst, n, list, list) {
-               BUG_ON(atomic_read(&inst->alg.cra_refcnt) != 1);
+               BUG_ON(refcount_read(&inst->alg.cra_refcnt) != 1);
                crypto_free_instance(inst);
        }
        crypto_remove_final(&users);
index 6da802d7be67c8edd938b5b45ca6506af8b914b2..70a894e52ff3b78ca460591124ca32aeb24181ff 100644 (file)
@@ -137,7 +137,7 @@ static struct crypto_alg *crypto_larval_add(const char *name, u32 type,
        if (IS_ERR(larval))
                return ERR_CAST(larval);
 
-       atomic_set(&larval->alg.cra_refcnt, 2);
+       refcount_set(&larval->alg.cra_refcnt, 2);
 
        down_write(&crypto_alg_sem);
        alg = __crypto_alg_lookup(name, type, mask);
index 0dbe2be7f78316b2359f11be09ac24e528f3b8de..5c291eedaa7029427513521ace34aea2cf9e1ff7 100644 (file)
@@ -169,7 +169,7 @@ static int crypto_report_one(struct crypto_alg *alg,
        ualg->cru_type = 0;
        ualg->cru_mask = 0;
        ualg->cru_flags = alg->cra_flags;
-       ualg->cru_refcnt = atomic_read(&alg->cra_refcnt);
+       ualg->cru_refcnt = refcount_read(&alg->cra_refcnt);
 
        if (nla_put_u32(skb, CRYPTOCFGA_PRIORITY_VAL, alg->cra_priority))
                goto nla_put_failure;
@@ -387,7 +387,7 @@ static int crypto_del_alg(struct sk_buff *skb, struct nlmsghdr *nlh,
                goto drop_alg;
 
        err = -EBUSY;
-       if (atomic_read(&alg->cra_refcnt) > 2)
+       if (refcount_read(&alg->cra_refcnt) > 2)
                goto drop_alg;
 
        err = crypto_unregister_instance((struct crypto_instance *)alg);
index ae65e5fcaa596eae2c6b1f6a10222f60024f1f70..1388af6da85ae4e361654fdccb2d876edfe9627d 100644 (file)
@@ -105,13 +105,13 @@ int crypto_type_has_alg(const char *name, const struct crypto_type *frontend,
 
 static inline struct crypto_alg *crypto_alg_get(struct crypto_alg *alg)
 {
-       atomic_inc(&alg->cra_refcnt);
+       refcount_inc(&alg->cra_refcnt);
        return alg;
 }
 
 static inline void crypto_alg_put(struct crypto_alg *alg)
 {
-       if (atomic_dec_and_test(&alg->cra_refcnt) && alg->cra_destroy)
+       if (refcount_dec_and_test(&alg->cra_refcnt) && alg->cra_destroy)
                alg->cra_destroy(alg);
 }
 
index 2cc10c96d7530f486f90afb2336909ed44b61490..822fcef6d91cf0dd534e9cfaaafdff7d03b09563 100644 (file)
@@ -46,7 +46,7 @@ static int c_show(struct seq_file *m, void *p)
        seq_printf(m, "driver       : %s\n", alg->cra_driver_name);
        seq_printf(m, "module       : %s\n", module_name(alg->cra_module));
        seq_printf(m, "priority     : %d\n", alg->cra_priority);
-       seq_printf(m, "refcnt       : %d\n", atomic_read(&alg->cra_refcnt));
+       seq_printf(m, "refcnt       : %u\n", refcount_read(&alg->cra_refcnt));
        seq_printf(m, "selftest     : %s\n",
                   (alg->cra_flags & CRYPTO_ALG_TESTED) ?
                   "passed" : "unknown");
index 78508ca4b108573a4dee3d33038e8e6224b6d30f..231e59f90d32c6ad93544513b0695ad5b363de22 100644 (file)
@@ -447,7 +447,7 @@ struct crypto_alg {
        unsigned int cra_alignmask;
 
        int cra_priority;
-       atomic_t cra_refcnt;
+       refcount_t cra_refcnt;
 
        char cra_name[CRYPTO_MAX_ALG_NAME];
        char cra_driver_name[CRYPTO_MAX_ALG_NAME];