diff options
Diffstat (limited to 'crypto/cryptomgr.c')
| -rw-r--r-- | crypto/cryptomgr.c | 66 |
1 files changed, 43 insertions, 23 deletions
diff --git a/crypto/cryptomgr.c b/crypto/cryptomgr.c index 2ebffb84f1d9..6958ea83ee44 100644 --- a/crypto/cryptomgr.c +++ b/crypto/cryptomgr.c | |||
| @@ -14,17 +14,24 @@ | |||
| 14 | #include <linux/ctype.h> | 14 | #include <linux/ctype.h> |
| 15 | #include <linux/err.h> | 15 | #include <linux/err.h> |
| 16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
| 17 | #include <linux/kthread.h> | ||
| 17 | #include <linux/module.h> | 18 | #include <linux/module.h> |
| 18 | #include <linux/notifier.h> | 19 | #include <linux/notifier.h> |
| 19 | #include <linux/rtnetlink.h> | 20 | #include <linux/rtnetlink.h> |
| 20 | #include <linux/sched.h> | 21 | #include <linux/sched.h> |
| 21 | #include <linux/string.h> | 22 | #include <linux/string.h> |
| 22 | #include <linux/workqueue.h> | ||
| 23 | 23 | ||
| 24 | #include "internal.h" | 24 | #include "internal.h" |
| 25 | 25 | ||
| 26 | struct cryptomgr_param { | 26 | struct cryptomgr_param { |
| 27 | struct work_struct work; | 27 | struct task_struct *thread; |
| 28 | |||
| 29 | struct rtattr *tb[CRYPTOA_MAX]; | ||
| 30 | |||
| 31 | struct { | ||
| 32 | struct rtattr attr; | ||
| 33 | struct crypto_attr_type data; | ||
| 34 | } type; | ||
| 28 | 35 | ||
| 29 | struct { | 36 | struct { |
| 30 | struct rtattr attr; | 37 | struct rtattr attr; |
| @@ -32,18 +39,15 @@ struct cryptomgr_param { | |||
| 32 | } alg; | 39 | } alg; |
| 33 | 40 | ||
| 34 | struct { | 41 | struct { |
| 35 | u32 type; | ||
| 36 | u32 mask; | ||
| 37 | char name[CRYPTO_MAX_ALG_NAME]; | 42 | char name[CRYPTO_MAX_ALG_NAME]; |
| 38 | } larval; | 43 | } larval; |
| 39 | 44 | ||
| 40 | char template[CRYPTO_MAX_ALG_NAME]; | 45 | char template[CRYPTO_MAX_ALG_NAME]; |
| 41 | }; | 46 | }; |
| 42 | 47 | ||
| 43 | static void cryptomgr_probe(struct work_struct *work) | 48 | static int cryptomgr_probe(void *data) |
| 44 | { | 49 | { |
| 45 | struct cryptomgr_param *param = | 50 | struct cryptomgr_param *param = data; |
| 46 | container_of(work, struct cryptomgr_param, work); | ||
| 47 | struct crypto_template *tmpl; | 51 | struct crypto_template *tmpl; |
| 48 | struct crypto_instance *inst; | 52 | struct crypto_instance *inst; |
| 49 | int err; | 53 | int err; |
| @@ -53,7 +57,7 @@ static void cryptomgr_probe(struct work_struct *work) | |||
| 53 | goto err; | 57 | goto err; |
| 54 | 58 | ||
| 55 | do { | 59 | do { |
| 56 | inst = tmpl->alloc(¶m->alg, sizeof(param->alg)); | 60 | inst = tmpl->alloc(param->tb); |
| 57 | if (IS_ERR(inst)) | 61 | if (IS_ERR(inst)) |
| 58 | err = PTR_ERR(inst); | 62 | err = PTR_ERR(inst); |
| 59 | else if ((err = crypto_register_instance(tmpl, inst))) | 63 | else if ((err = crypto_register_instance(tmpl, inst))) |
| @@ -67,11 +71,11 @@ static void cryptomgr_probe(struct work_struct *work) | |||
| 67 | 71 | ||
| 68 | out: | 72 | out: |
| 69 | kfree(param); | 73 | kfree(param); |
| 70 | return; | 74 | module_put_and_exit(0); |
| 71 | 75 | ||
| 72 | err: | 76 | err: |
| 73 | crypto_larval_error(param->larval.name, param->larval.type, | 77 | crypto_larval_error(param->larval.name, param->type.data.type, |
| 74 | param->larval.mask); | 78 | param->type.data.mask); |
| 75 | goto out; | 79 | goto out; |
| 76 | } | 80 | } |
| 77 | 81 | ||
| @@ -82,10 +86,13 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval) | |||
| 82 | const char *p; | 86 | const char *p; |
| 83 | unsigned int len; | 87 | unsigned int len; |
| 84 | 88 | ||
| 85 | param = kmalloc(sizeof(*param), GFP_KERNEL); | 89 | if (!try_module_get(THIS_MODULE)) |
| 86 | if (!param) | ||
| 87 | goto err; | 90 | goto err; |
| 88 | 91 | ||
| 92 | param = kzalloc(sizeof(*param), GFP_KERNEL); | ||
| 93 | if (!param) | ||
| 94 | goto err_put_module; | ||
| 95 | |||
| 89 | for (p = name; isalnum(*p) || *p == '-' || *p == '_'; p++) | 96 | for (p = name; isalnum(*p) || *p == '-' || *p == '_'; p++) |
| 90 | ; | 97 | ; |
| 91 | 98 | ||
| @@ -94,32 +101,45 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval) | |||
| 94 | goto err_free_param; | 101 | goto err_free_param; |
| 95 | 102 | ||
| 96 | memcpy(param->template, name, len); | 103 | memcpy(param->template, name, len); |
| 97 | param->template[len] = 0; | ||
| 98 | 104 | ||
| 99 | name = p + 1; | 105 | name = p + 1; |
| 100 | for (p = name; isalnum(*p) || *p == '-' || *p == '_'; p++) | 106 | len = 0; |
| 101 | ; | 107 | for (p = name; *p; p++) { |
| 108 | for (; isalnum(*p) || *p == '-' || *p == '_' || *p == '('; p++) | ||
| 109 | ; | ||
| 102 | 110 | ||
| 103 | len = p - name; | 111 | if (*p != ')') |
| 104 | if (!len || *p != ')' || p[1]) | 112 | goto err_free_param; |
| 113 | |||
| 114 | len = p - name; | ||
| 115 | } | ||
| 116 | |||
| 117 | if (!len || name[len + 1]) | ||
| 105 | goto err_free_param; | 118 | goto err_free_param; |
| 106 | 119 | ||
| 120 | param->type.attr.rta_len = sizeof(param->type); | ||
| 121 | param->type.attr.rta_type = CRYPTOA_TYPE; | ||
| 122 | param->type.data.type = larval->alg.cra_flags; | ||
| 123 | param->type.data.mask = larval->mask; | ||
| 124 | param->tb[CRYPTOA_TYPE - 1] = ¶m->type.attr; | ||
| 125 | |||
| 107 | param->alg.attr.rta_len = sizeof(param->alg); | 126 | param->alg.attr.rta_len = sizeof(param->alg); |
| 108 | param->alg.attr.rta_type = CRYPTOA_ALG; | 127 | param->alg.attr.rta_type = CRYPTOA_ALG; |
| 109 | memcpy(param->alg.data.name, name, len); | 128 | memcpy(param->alg.data.name, name, len); |
| 110 | param->alg.data.name[len] = 0; | 129 | param->tb[CRYPTOA_ALG - 1] = ¶m->alg.attr; |
| 111 | 130 | ||
| 112 | memcpy(param->larval.name, larval->alg.cra_name, CRYPTO_MAX_ALG_NAME); | 131 | memcpy(param->larval.name, larval->alg.cra_name, CRYPTO_MAX_ALG_NAME); |
| 113 | param->larval.type = larval->alg.cra_flags; | ||
| 114 | param->larval.mask = larval->mask; | ||
| 115 | 132 | ||
| 116 | INIT_WORK(¶m->work, cryptomgr_probe); | 133 | param->thread = kthread_run(cryptomgr_probe, param, "cryptomgr"); |
| 117 | schedule_work(¶m->work); | 134 | if (IS_ERR(param->thread)) |
| 135 | goto err_free_param; | ||
| 118 | 136 | ||
| 119 | return NOTIFY_STOP; | 137 | return NOTIFY_STOP; |
| 120 | 138 | ||
| 121 | err_free_param: | 139 | err_free_param: |
| 122 | kfree(param); | 140 | kfree(param); |
| 141 | err_put_module: | ||
| 142 | module_put(THIS_MODULE); | ||
| 123 | err: | 143 | err: |
| 124 | return NOTIFY_OK; | 144 | return NOTIFY_OK; |
| 125 | } | 145 | } |
