]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 9 Feb 2009 16:52:02 +0000 (08:52 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 9 Feb 2009 16:52:02 +0000 (08:52 -0800)
* git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6:
  crypto: scatterwalk - Avoid flush_dcache_page on slab pages
  crypto: shash - Fix tfm destruction
  crypto: api - Fix zeroing on free
  crypto: shash - Fix module refcount
  crypto: api - Fix algorithm test race that broke aead initialisation

crypto/algapi.c
crypto/api.c
crypto/scatterwalk.c
crypto/shash.c
include/crypto/hash.h
include/linux/crypto.h

index 7c41e7405c41a4392791cc4a01a22cce52f983b0..56c62e2858d56a9eee11b9167fe8362a71a7c6c1 100644 (file)
@@ -149,6 +149,9 @@ static struct crypto_larval *__crypto_register_alg(struct crypto_alg *alg)
                if (q == alg)
                        goto err;
 
+               if (crypto_is_moribund(q))
+                       continue;
+
                if (crypto_is_larval(q)) {
                        if (!strcmp(alg->cra_driver_name, q->cra_driver_name))
                                goto err;
@@ -197,7 +200,7 @@ void crypto_alg_tested(const char *name, int err)
 
        down_write(&crypto_alg_sem);
        list_for_each_entry(q, &crypto_alg_list, cra_list) {
-               if (!crypto_is_larval(q))
+               if (crypto_is_moribund(q) || !crypto_is_larval(q))
                        continue;
 
                test = (struct crypto_larval *)q;
@@ -210,6 +213,7 @@ void crypto_alg_tested(const char *name, int err)
        goto unlock;
 
 found:
+       q->cra_flags |= CRYPTO_ALG_DEAD;
        alg = test->adult;
        if (err || list_empty(&alg->cra_list))
                goto complete;
index 9975a7bd246c21d4d7e3152249ffefdb38812ee5..efe77df6863f4378f4f0da414591f940870b76ea 100644 (file)
@@ -557,34 +557,34 @@ err:
        return ERR_PTR(err);
 }
 EXPORT_SYMBOL_GPL(crypto_alloc_tfm);
+
 /*
- *     crypto_free_tfm - Free crypto transform
+ *     crypto_destroy_tfm - Free crypto transform
+ *     @mem: Start of tfm slab
  *     @tfm: Transform to free
  *
- *     crypto_free_tfm() frees up the transform and any associated resources,
+ *     This function frees up the transform and any associated resources,
  *     then drops the refcount on the associated algorithm.
  */
-void crypto_free_tfm(struct crypto_tfm *tfm)
+void crypto_destroy_tfm(void *mem, struct crypto_tfm *tfm)
 {
        struct crypto_alg *alg;
        int size;
 
-       if (unlikely(!tfm))
+       if (unlikely(!mem))
                return;
 
        alg = tfm->__crt_alg;
-       size = sizeof(*tfm) + alg->cra_ctxsize;
+       size = ksize(mem);
 
        if (!tfm->exit && alg->cra_exit)
                alg->cra_exit(tfm);
        crypto_exit_ops(tfm);
        crypto_mod_put(alg);
-       memset(tfm, 0, size);
-       kfree(tfm);
+       memset(mem, 0, size);
+       kfree(mem);
 }
-
-EXPORT_SYMBOL_GPL(crypto_free_tfm);
+EXPORT_SYMBOL_GPL(crypto_destroy_tfm);
 
 int crypto_has_alg(const char *name, u32 type, u32 mask)
 {
index 9aeeb52004a5399d0a9b7a3484044b5de1e3083c..3de89a424401c1918818145a3d27df627c99f7ef 100644 (file)
@@ -54,7 +54,8 @@ static void scatterwalk_pagedone(struct scatter_walk *walk, int out,
                struct page *page;
 
                page = sg_page(walk->sg) + ((walk->offset - 1) >> PAGE_SHIFT);
-               flush_dcache_page(page);
+               if (!PageSlab(page))
+                       flush_dcache_page(page);
        }
 
        if (more) {
index c9df367332ffd1f122b1d675bcb434b936848bc4..d5a2b619c55f79e3b7cbff1f1d06d3048364b49c 100644 (file)
@@ -388,10 +388,15 @@ static int crypto_init_shash_ops_compat(struct crypto_tfm *tfm)
        struct shash_desc *desc = crypto_tfm_ctx(tfm);
        struct crypto_shash *shash;
 
+       if (!crypto_mod_get(calg))
+               return -EAGAIN;
+
        shash = __crypto_shash_cast(crypto_create_tfm(
                calg, &crypto_shash_type));
-       if (IS_ERR(shash))
+       if (IS_ERR(shash)) {
+               crypto_mod_put(calg);
                return PTR_ERR(shash);
+       }
 
        desc->tfm = shash;
        tfm->exit = crypto_exit_shash_ops_compat;
index cd16d6e668ce78a523a7865f747d5078ad0ecd76..d797e119e3d5e9677a60457670ed097982916691 100644 (file)
@@ -222,7 +222,7 @@ static inline struct crypto_tfm *crypto_shash_tfm(struct crypto_shash *tfm)
 
 static inline void crypto_free_shash(struct crypto_shash *tfm)
 {
-       crypto_free_tfm(crypto_shash_tfm(tfm));
+       crypto_destroy_tfm(tfm, crypto_shash_tfm(tfm));
 }
 
 static inline unsigned int crypto_shash_alignmask(
index 3bacd71509fb1ce7197ac675044807a2d76f2fd1..1f2e9020acc667d5f0dd0f2e501e6f85f0fff140 100644 (file)
@@ -552,7 +552,12 @@ struct crypto_tfm *crypto_alloc_tfm(const char *alg_name,
                                    const struct crypto_type *frontend,
                                    u32 type, u32 mask);
 struct crypto_tfm *crypto_alloc_base(const char *alg_name, u32 type, u32 mask);
-void crypto_free_tfm(struct crypto_tfm *tfm);
+void crypto_destroy_tfm(void *mem, struct crypto_tfm *tfm);
+
+static inline void crypto_free_tfm(struct crypto_tfm *tfm)
+{
+       return crypto_destroy_tfm(tfm, tfm);
+}
 
 int alg_test(const char *driver, const char *alg, u32 type, u32 mask);