diff options
Diffstat (limited to 'crypto/cryptomgr.c')
-rw-r--r-- | crypto/cryptomgr.c | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/crypto/cryptomgr.c b/crypto/cryptomgr.c index 7a3df9b41218..6958ea83ee44 100644 --- a/crypto/cryptomgr.c +++ b/crypto/cryptomgr.c | |||
@@ -14,17 +14,17 @@ | |||
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 | 28 | ||
29 | struct rtattr *tb[CRYPTOA_MAX]; | 29 | struct rtattr *tb[CRYPTOA_MAX]; |
30 | 30 | ||
@@ -45,10 +45,9 @@ struct cryptomgr_param { | |||
45 | char template[CRYPTO_MAX_ALG_NAME]; | 45 | char template[CRYPTO_MAX_ALG_NAME]; |
46 | }; | 46 | }; |
47 | 47 | ||
48 | static void cryptomgr_probe(struct work_struct *work) | 48 | static int cryptomgr_probe(void *data) |
49 | { | 49 | { |
50 | struct cryptomgr_param *param = | 50 | struct cryptomgr_param *param = data; |
51 | container_of(work, struct cryptomgr_param, work); | ||
52 | struct crypto_template *tmpl; | 51 | struct crypto_template *tmpl; |
53 | struct crypto_instance *inst; | 52 | struct crypto_instance *inst; |
54 | int err; | 53 | int err; |
@@ -72,7 +71,7 @@ static void cryptomgr_probe(struct work_struct *work) | |||
72 | 71 | ||
73 | out: | 72 | out: |
74 | kfree(param); | 73 | kfree(param); |
75 | return; | 74 | module_put_and_exit(0); |
76 | 75 | ||
77 | err: | 76 | err: |
78 | crypto_larval_error(param->larval.name, param->type.data.type, | 77 | crypto_larval_error(param->larval.name, param->type.data.type, |
@@ -87,9 +86,12 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval) | |||
87 | const char *p; | 86 | const char *p; |
88 | unsigned int len; | 87 | unsigned int len; |
89 | 88 | ||
89 | if (!try_module_get(THIS_MODULE)) | ||
90 | goto err; | ||
91 | |||
90 | param = kzalloc(sizeof(*param), GFP_KERNEL); | 92 | param = kzalloc(sizeof(*param), GFP_KERNEL); |
91 | if (!param) | 93 | if (!param) |
92 | goto err; | 94 | goto err_put_module; |
93 | 95 | ||
94 | for (p = name; isalnum(*p) || *p == '-' || *p == '_'; p++) | 96 | for (p = name; isalnum(*p) || *p == '-' || *p == '_'; p++) |
95 | ; | 97 | ; |
@@ -101,11 +103,18 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval) | |||
101 | memcpy(param->template, name, len); | 103 | memcpy(param->template, name, len); |
102 | 104 | ||
103 | name = p + 1; | 105 | name = p + 1; |
104 | for (p = name; isalnum(*p) || *p == '-' || *p == '_'; p++) | 106 | len = 0; |
105 | ; | 107 | for (p = name; *p; p++) { |
108 | for (; isalnum(*p) || *p == '-' || *p == '_' || *p == '('; p++) | ||
109 | ; | ||
106 | 110 | ||
107 | len = p - name; | 111 | if (*p != ')') |
108 | if (!len || *p != ')' || p[1]) | 112 | goto err_free_param; |
113 | |||
114 | len = p - name; | ||
115 | } | ||
116 | |||
117 | if (!len || name[len + 1]) | ||
109 | goto err_free_param; | 118 | goto err_free_param; |
110 | 119 | ||
111 | param->type.attr.rta_len = sizeof(param->type); | 120 | param->type.attr.rta_len = sizeof(param->type); |
@@ -121,13 +130,16 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval) | |||
121 | 130 | ||
122 | 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); |
123 | 132 | ||
124 | INIT_WORK(¶m->work, cryptomgr_probe); | 133 | param->thread = kthread_run(cryptomgr_probe, param, "cryptomgr"); |
125 | schedule_work(¶m->work); | 134 | if (IS_ERR(param->thread)) |
135 | goto err_free_param; | ||
126 | 136 | ||
127 | return NOTIFY_STOP; | 137 | return NOTIFY_STOP; |
128 | 138 | ||
129 | err_free_param: | 139 | err_free_param: |
130 | kfree(param); | 140 | kfree(param); |
141 | err_put_module: | ||
142 | module_put(THIS_MODULE); | ||
131 | err: | 143 | err: |
132 | return NOTIFY_OK; | 144 | return NOTIFY_OK; |
133 | } | 145 | } |