Commit d7c41b61 authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6

* 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
parents a8e807f7 4f3e797a
...@@ -149,6 +149,9 @@ static struct crypto_larval *__crypto_register_alg(struct crypto_alg *alg) ...@@ -149,6 +149,9 @@ static struct crypto_larval *__crypto_register_alg(struct crypto_alg *alg)
if (q == alg) if (q == alg)
goto err; goto err;
if (crypto_is_moribund(q))
continue;
if (crypto_is_larval(q)) { if (crypto_is_larval(q)) {
if (!strcmp(alg->cra_driver_name, q->cra_driver_name)) if (!strcmp(alg->cra_driver_name, q->cra_driver_name))
goto err; goto err;
...@@ -197,7 +200,7 @@ void crypto_alg_tested(const char *name, int err) ...@@ -197,7 +200,7 @@ void crypto_alg_tested(const char *name, int err)
down_write(&crypto_alg_sem); down_write(&crypto_alg_sem);
list_for_each_entry(q, &crypto_alg_list, cra_list) { 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; continue;
test = (struct crypto_larval *)q; test = (struct crypto_larval *)q;
...@@ -210,6 +213,7 @@ void crypto_alg_tested(const char *name, int err) ...@@ -210,6 +213,7 @@ void crypto_alg_tested(const char *name, int err)
goto unlock; goto unlock;
found: found:
q->cra_flags |= CRYPTO_ALG_DEAD;
alg = test->adult; alg = test->adult;
if (err || list_empty(&alg->cra_list)) if (err || list_empty(&alg->cra_list))
goto complete; goto complete;
......
...@@ -557,34 +557,34 @@ struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, ...@@ -557,34 +557,34 @@ struct crypto_tfm *crypto_alloc_tfm(const char *alg_name,
return ERR_PTR(err); return ERR_PTR(err);
} }
EXPORT_SYMBOL_GPL(crypto_alloc_tfm); 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 * @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. * 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; struct crypto_alg *alg;
int size; int size;
if (unlikely(!tfm)) if (unlikely(!mem))
return; return;
alg = tfm->__crt_alg; alg = tfm->__crt_alg;
size = sizeof(*tfm) + alg->cra_ctxsize; size = ksize(mem);
if (!tfm->exit && alg->cra_exit) if (!tfm->exit && alg->cra_exit)
alg->cra_exit(tfm); alg->cra_exit(tfm);
crypto_exit_ops(tfm); crypto_exit_ops(tfm);
crypto_mod_put(alg); crypto_mod_put(alg);
memset(tfm, 0, size); memset(mem, 0, size);
kfree(tfm); kfree(mem);
} }
EXPORT_SYMBOL_GPL(crypto_destroy_tfm);
EXPORT_SYMBOL_GPL(crypto_free_tfm);
int crypto_has_alg(const char *name, u32 type, u32 mask) int crypto_has_alg(const char *name, u32 type, u32 mask)
{ {
......
...@@ -54,7 +54,8 @@ static void scatterwalk_pagedone(struct scatter_walk *walk, int out, ...@@ -54,7 +54,8 @@ static void scatterwalk_pagedone(struct scatter_walk *walk, int out,
struct page *page; struct page *page;
page = sg_page(walk->sg) + ((walk->offset - 1) >> PAGE_SHIFT); page = sg_page(walk->sg) + ((walk->offset - 1) >> PAGE_SHIFT);
flush_dcache_page(page); if (!PageSlab(page))
flush_dcache_page(page);
} }
if (more) { if (more) {
......
...@@ -388,10 +388,15 @@ static int crypto_init_shash_ops_compat(struct crypto_tfm *tfm) ...@@ -388,10 +388,15 @@ static int crypto_init_shash_ops_compat(struct crypto_tfm *tfm)
struct shash_desc *desc = crypto_tfm_ctx(tfm); struct shash_desc *desc = crypto_tfm_ctx(tfm);
struct crypto_shash *shash; struct crypto_shash *shash;
if (!crypto_mod_get(calg))
return -EAGAIN;
shash = __crypto_shash_cast(crypto_create_tfm( shash = __crypto_shash_cast(crypto_create_tfm(
calg, &crypto_shash_type)); calg, &crypto_shash_type));
if (IS_ERR(shash)) if (IS_ERR(shash)) {
crypto_mod_put(calg);
return PTR_ERR(shash); return PTR_ERR(shash);
}
desc->tfm = shash; desc->tfm = shash;
tfm->exit = crypto_exit_shash_ops_compat; tfm->exit = crypto_exit_shash_ops_compat;
......
...@@ -222,7 +222,7 @@ static inline struct crypto_tfm *crypto_shash_tfm(struct crypto_shash *tfm) ...@@ -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) 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( static inline unsigned int crypto_shash_alignmask(
......
...@@ -552,7 +552,12 @@ struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, ...@@ -552,7 +552,12 @@ struct crypto_tfm *crypto_alloc_tfm(const char *alg_name,
const struct crypto_type *frontend, const struct crypto_type *frontend,
u32 type, u32 mask); u32 type, u32 mask);
struct crypto_tfm *crypto_alloc_base(const char *alg_name, 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); int alg_test(const char *driver, const char *alg, u32 type, u32 mask);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment