Commit cd74bb13 authored by James Morris's avatar James Morris

[CRYPTO]: Use try_inc_mod_count and semaphore for alg list.

parent 49d21b00
...@@ -15,22 +15,22 @@ ...@@ -15,22 +15,22 @@
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/spinlock.h> #include <linux/rwsem.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/crypto.h> #include <linux/crypto.h>
#include "internal.h" #include "internal.h"
static rwlock_t crypto_alg_lock = RW_LOCK_UNLOCKED;
static LIST_HEAD(crypto_alg_list); static LIST_HEAD(crypto_alg_list);
static struct rw_semaphore crypto_alg_sem;
static void *c_start(struct seq_file *m, loff_t *pos) static void *c_start(struct seq_file *m, loff_t *pos)
{ {
struct list_head *v; struct list_head *v;
loff_t n = *pos; loff_t n = *pos;
read_lock(&crypto_alg_lock); down_read(&crypto_alg_sem);
list_for_each(v, &crypto_alg_list) list_for_each(v, &crypto_alg_list)
if (!n--) if (!n--)
return list_entry(v, struct crypto_alg, cra_list); return list_entry(v, struct crypto_alg, cra_list);
...@@ -49,7 +49,7 @@ static void *c_next(struct seq_file *m, void *p, loff_t *pos) ...@@ -49,7 +49,7 @@ static void *c_next(struct seq_file *m, void *p, loff_t *pos)
static void c_stop(struct seq_file *m, void *p) static void c_stop(struct seq_file *m, void *p)
{ {
read_unlock(&crypto_alg_lock); up_read(&crypto_alg_sem);
} }
static int c_show(struct seq_file *m, void *p) static int c_show(struct seq_file *m, void *p)
...@@ -95,15 +95,17 @@ struct file_operations proc_crypto_ops = { ...@@ -95,15 +95,17 @@ struct file_operations proc_crypto_ops = {
.release = seq_release .release = seq_release
}; };
static inline int crypto_alg_get(struct crypto_alg *alg)
static inline void crypto_alg_get(struct crypto_alg *alg)
{ {
/* XXX: inc refcount */ if (alg->cra_module)
return try_inc_mod_count(alg->cra_module);
else
return 1;
} }
static inline void crypto_alg_put(struct crypto_alg *alg) static inline void crypto_alg_put(struct crypto_alg *alg)
{ {
/* XXX: dec refcount */ __MOD_DEC_USE_COUNT(alg->cra_module);
} }
struct crypto_alg *crypto_alg_lookup(u32 algid) struct crypto_alg *crypto_alg_lookup(u32 algid)
...@@ -111,18 +113,18 @@ struct crypto_alg *crypto_alg_lookup(u32 algid) ...@@ -111,18 +113,18 @@ struct crypto_alg *crypto_alg_lookup(u32 algid)
struct list_head *p; struct list_head *p;
struct crypto_alg *alg = NULL; struct crypto_alg *alg = NULL;
read_lock(&crypto_alg_lock); down_read(&crypto_alg_sem);
list_for_each(p, &crypto_alg_list) { list_for_each(p, &crypto_alg_list) {
if ((((struct crypto_alg *)p)->cra_id if ((((struct crypto_alg *)p)->cra_id
& CRYPTO_ALG_MASK) == algid) { & CRYPTO_ALG_MASK) == algid) {
alg = (struct crypto_alg *)p; if (crypto_alg_get((struct crypto_alg *)p))
crypto_alg_get(alg); alg = (struct crypto_alg *)p;
break; break;
} }
} }
read_unlock(&crypto_alg_lock); up_read(&crypto_alg_sem);
return alg; return alg;
} }
...@@ -213,7 +215,7 @@ int crypto_register_alg(struct crypto_alg *alg) ...@@ -213,7 +215,7 @@ int crypto_register_alg(struct crypto_alg *alg)
int ret = 0; int ret = 0;
struct list_head *p; struct list_head *p;
write_lock(&crypto_alg_lock); down_write(&crypto_alg_sem);
list_for_each(p, &crypto_alg_list) { list_for_each(p, &crypto_alg_list) {
struct crypto_alg *q = (struct crypto_alg *)p; struct crypto_alg *q = (struct crypto_alg *)p;
...@@ -225,7 +227,7 @@ int crypto_register_alg(struct crypto_alg *alg) ...@@ -225,7 +227,7 @@ int crypto_register_alg(struct crypto_alg *alg)
} }
list_add_tail(&alg->cra_list, &crypto_alg_list); list_add_tail(&alg->cra_list, &crypto_alg_list);
out: out:
write_unlock(&crypto_alg_lock); up_write(&crypto_alg_sem);
return ret; return ret;
} }
...@@ -234,26 +236,27 @@ int crypto_unregister_alg(struct crypto_alg *alg) ...@@ -234,26 +236,27 @@ int crypto_unregister_alg(struct crypto_alg *alg)
int ret = -ENOENT; int ret = -ENOENT;
struct list_head *p; struct list_head *p;
write_lock(&crypto_alg_lock); down_write(&crypto_alg_sem);
list_for_each(p, &crypto_alg_list) { list_for_each(p, &crypto_alg_list) {
if (alg == (struct crypto_alg *)p) { if (alg == (struct crypto_alg *)p) {
BUG_ON(!alg->cra_module);
list_del(p); list_del(p);
ret = 0; ret = 0;
goto out; goto out;
} }
} }
out: out:
write_unlock(&crypto_alg_lock); up_write(&crypto_alg_sem);
return ret; return ret;
} }
static int __init init_crypto(void) static int __init init_crypto(void)
{ {
struct proc_dir_entry *proc; struct proc_dir_entry *proc;
printk(KERN_INFO "Initializing Cryptographic API\n"); printk(KERN_INFO "Initializing Cryptographic API\n");
init_rwsem(&crypto_alg_sem);
proc = create_proc_entry("crypto", 0, NULL); proc = create_proc_entry("crypto", 0, NULL);
if (proc) if (proc)
proc->proc_fops = &proc_crypto_ops; proc->proc_fops = &proc_crypto_ops;
...@@ -267,4 +270,3 @@ EXPORT_SYMBOL_GPL(crypto_register_alg); ...@@ -267,4 +270,3 @@ EXPORT_SYMBOL_GPL(crypto_register_alg);
EXPORT_SYMBOL_GPL(crypto_unregister_alg); EXPORT_SYMBOL_GPL(crypto_unregister_alg);
EXPORT_SYMBOL_GPL(crypto_alloc_tfm); EXPORT_SYMBOL_GPL(crypto_alloc_tfm);
EXPORT_SYMBOL_GPL(crypto_free_tfm); EXPORT_SYMBOL_GPL(crypto_free_tfm);
...@@ -1259,6 +1259,7 @@ static struct crypto_alg des_alg = { ...@@ -1259,6 +1259,7 @@ static struct crypto_alg des_alg = {
.cra_name = "des", .cra_name = "des",
.cra_blocksize = DES_BLOCK_SIZE, .cra_blocksize = DES_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct des_ctx), .cra_ctxsize = sizeof(struct des_ctx),
.cra_module = THIS_MODULE,
.cra_u = { .cipher = { .cra_u = { .cipher = {
.cia_keysize = DES_KEY_SIZE, .cia_keysize = DES_KEY_SIZE,
.cia_ivsize = DES_BLOCK_SIZE, .cia_ivsize = DES_BLOCK_SIZE,
...@@ -1272,6 +1273,7 @@ static struct crypto_alg des3_ede_alg = { ...@@ -1272,6 +1273,7 @@ static struct crypto_alg des3_ede_alg = {
.cra_name = "des3_ede", .cra_name = "des3_ede",
.cra_blocksize = DES3_EDE_BLOCK_SIZE, .cra_blocksize = DES3_EDE_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct des3_ede_ctx), .cra_ctxsize = sizeof(struct des3_ede_ctx),
.cra_module = THIS_MODULE,
.cra_u = { .cipher = { .cra_u = { .cipher = {
.cia_keysize = DES3_EDE_KEY_SIZE, .cia_keysize = DES3_EDE_KEY_SIZE,
.cia_ivsize = DES3_EDE_BLOCK_SIZE, .cia_ivsize = DES3_EDE_BLOCK_SIZE,
......
...@@ -219,6 +219,7 @@ static struct crypto_alg alg = { ...@@ -219,6 +219,7 @@ static struct crypto_alg alg = {
.cra_name = "md5", .cra_name = "md5",
.cra_blocksize = MD5_HMAC_BLOCK_SIZE, .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct md5_ctx), .cra_ctxsize = sizeof(struct md5_ctx),
.cra_module = THIS_MODULE,
.cra_u = { .digest = { .cra_u = { .digest = {
.dia_digestsize = MD5_DIGEST_SIZE, .dia_digestsize = MD5_DIGEST_SIZE,
.dia_init = md5_init, .dia_init = md5_init,
......
...@@ -182,6 +182,7 @@ static struct crypto_alg alg = { ...@@ -182,6 +182,7 @@ static struct crypto_alg alg = {
.cra_name = "sha1", .cra_name = "sha1",
.cra_blocksize = SHA1_HMAC_BLOCK_SIZE, .cra_blocksize = SHA1_HMAC_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct sha1_ctx), .cra_ctxsize = sizeof(struct sha1_ctx),
.cra_module = THIS_MODULE,
.cra_u = { .digest = { .cra_u = { .digest = {
.dia_digestsize = SHA1_DIGEST_SIZE, .dia_digestsize = SHA1_DIGEST_SIZE,
.dia_init = sha1_init, .dia_init = sha1_init,
......
...@@ -931,6 +931,8 @@ void test_des(void) ...@@ -931,6 +931,8 @@ void test_des(void)
printk("%s\n", memcmp(q, des_tv[i].result, len) ? "fail" : "pass"); printk("%s\n", memcmp(q, des_tv[i].result, len) ? "fail" : "pass");
} }
crypto_free_tfm(tfm);
/* /*
* Scenario F: * Scenario F:
* *
......
...@@ -100,6 +100,8 @@ struct crypto_alg { ...@@ -100,6 +100,8 @@ struct crypto_alg {
struct digest_alg digest; struct digest_alg digest;
struct compress_alg compress; struct compress_alg compress;
} cra_u; } cra_u;
struct module *cra_module;
}; };
/* /*
......
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