]>
Commit | Line | Data |
---|---|---|
3681ac45 GKH |
1 | From 82fb82be05585426405667dd5f0510aa953ba439 Mon Sep 17 00:00:00 2001 |
2 | From: Aurelien Aptel <aaptel@suse.com> | |
3 | Date: Fri, 16 Feb 2018 19:19:27 +0100 | |
4 | Subject: CIFS: refactor crypto shash/sdesc allocation&free | |
5 | ||
6 | From: Aurelien Aptel <aaptel@suse.com> | |
7 | ||
8 | commit 82fb82be05585426405667dd5f0510aa953ba439 upstream. | |
9 | ||
10 | shash and sdesc and always allocated and freed together. | |
11 | * abstract this in new functions cifs_alloc_hash() and cifs_free_hash(). | |
12 | * make smb2/3 crypto allocation independent from each other. | |
13 | ||
14 | Signed-off-by: Aurelien Aptel <aaptel@suse.com> | |
15 | Signed-off-by: Steve French <smfrench@gmail.com> | |
16 | Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com> | |
17 | CC: Stable <stable@vger.kernel.org> | |
18 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
19 | ||
20 | --- | |
21 | fs/cifs/cifsencrypt.c | 78 ++++-------------------------------------------- | |
22 | fs/cifs/cifsproto.h | 5 +++ | |
23 | fs/cifs/link.c | 25 +++------------ | |
24 | fs/cifs/misc.c | 54 +++++++++++++++++++++++++++++++++ | |
25 | fs/cifs/smb2transport.c | 75 +++++++++------------------------------------- | |
26 | fs/cifs/smbencrypt.c | 25 +++------------ | |
27 | 6 files changed, 91 insertions(+), 171 deletions(-) | |
28 | ||
29 | --- a/fs/cifs/cifsencrypt.c | |
30 | +++ b/fs/cifs/cifsencrypt.c | |
31 | @@ -36,37 +36,6 @@ | |
32 | #include <crypto/skcipher.h> | |
33 | #include <crypto/aead.h> | |
34 | ||
35 | -static int | |
36 | -cifs_crypto_shash_md5_allocate(struct TCP_Server_Info *server) | |
37 | -{ | |
38 | - int rc; | |
39 | - unsigned int size; | |
40 | - | |
41 | - if (server->secmech.sdescmd5 != NULL) | |
42 | - return 0; /* already allocated */ | |
43 | - | |
44 | - server->secmech.md5 = crypto_alloc_shash("md5", 0, 0); | |
45 | - if (IS_ERR(server->secmech.md5)) { | |
46 | - cifs_dbg(VFS, "could not allocate crypto md5\n"); | |
47 | - rc = PTR_ERR(server->secmech.md5); | |
48 | - server->secmech.md5 = NULL; | |
49 | - return rc; | |
50 | - } | |
51 | - | |
52 | - size = sizeof(struct shash_desc) + | |
53 | - crypto_shash_descsize(server->secmech.md5); | |
54 | - server->secmech.sdescmd5 = kmalloc(size, GFP_KERNEL); | |
55 | - if (!server->secmech.sdescmd5) { | |
56 | - crypto_free_shash(server->secmech.md5); | |
57 | - server->secmech.md5 = NULL; | |
58 | - return -ENOMEM; | |
59 | - } | |
60 | - server->secmech.sdescmd5->shash.tfm = server->secmech.md5; | |
61 | - server->secmech.sdescmd5->shash.flags = 0x0; | |
62 | - | |
63 | - return 0; | |
64 | -} | |
65 | - | |
66 | int __cifs_calc_signature(struct smb_rqst *rqst, | |
67 | struct TCP_Server_Info *server, char *signature, | |
68 | struct shash_desc *shash) | |
69 | @@ -132,13 +101,10 @@ static int cifs_calc_signature(struct sm | |
70 | if (!rqst->rq_iov || !signature || !server) | |
71 | return -EINVAL; | |
72 | ||
73 | - if (!server->secmech.sdescmd5) { | |
74 | - rc = cifs_crypto_shash_md5_allocate(server); | |
75 | - if (rc) { | |
76 | - cifs_dbg(VFS, "%s: Can't alloc md5 crypto\n", __func__); | |
77 | - return -1; | |
78 | - } | |
79 | - } | |
80 | + rc = cifs_alloc_hash("md5", &server->secmech.md5, | |
81 | + &server->secmech.sdescmd5); | |
82 | + if (rc) | |
83 | + return -1; | |
84 | ||
85 | rc = crypto_shash_init(&server->secmech.sdescmd5->shash); | |
86 | if (rc) { | |
87 | @@ -663,37 +629,6 @@ CalcNTLMv2_response(const struct cifs_se | |
88 | return rc; | |
89 | } | |
90 | ||
91 | -static int crypto_hmacmd5_alloc(struct TCP_Server_Info *server) | |
92 | -{ | |
93 | - int rc; | |
94 | - unsigned int size; | |
95 | - | |
96 | - /* check if already allocated */ | |
97 | - if (server->secmech.sdeschmacmd5) | |
98 | - return 0; | |
99 | - | |
100 | - server->secmech.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0); | |
101 | - if (IS_ERR(server->secmech.hmacmd5)) { | |
102 | - cifs_dbg(VFS, "could not allocate crypto hmacmd5\n"); | |
103 | - rc = PTR_ERR(server->secmech.hmacmd5); | |
104 | - server->secmech.hmacmd5 = NULL; | |
105 | - return rc; | |
106 | - } | |
107 | - | |
108 | - size = sizeof(struct shash_desc) + | |
109 | - crypto_shash_descsize(server->secmech.hmacmd5); | |
110 | - server->secmech.sdeschmacmd5 = kmalloc(size, GFP_KERNEL); | |
111 | - if (!server->secmech.sdeschmacmd5) { | |
112 | - crypto_free_shash(server->secmech.hmacmd5); | |
113 | - server->secmech.hmacmd5 = NULL; | |
114 | - return -ENOMEM; | |
115 | - } | |
116 | - server->secmech.sdeschmacmd5->shash.tfm = server->secmech.hmacmd5; | |
117 | - server->secmech.sdeschmacmd5->shash.flags = 0x0; | |
118 | - | |
119 | - return 0; | |
120 | -} | |
121 | - | |
122 | int | |
123 | setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp) | |
124 | { | |
125 | @@ -757,9 +692,10 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, c | |
126 | ||
127 | mutex_lock(&ses->server->srv_mutex); | |
128 | ||
129 | - rc = crypto_hmacmd5_alloc(ses->server); | |
130 | + rc = cifs_alloc_hash("hmac(md5)", | |
131 | + &ses->server->secmech.hmacmd5, | |
132 | + &ses->server->secmech.sdeschmacmd5); | |
133 | if (rc) { | |
134 | - cifs_dbg(VFS, "could not crypto alloc hmacmd5 rc %d\n", rc); | |
135 | goto unlock; | |
136 | } | |
137 | ||
138 | --- a/fs/cifs/cifsproto.h | |
139 | +++ b/fs/cifs/cifsproto.h | |
140 | @@ -542,4 +542,9 @@ enum securityEnum cifs_select_sectype(st | |
141 | struct cifs_aio_ctx *cifs_aio_ctx_alloc(void); | |
142 | void cifs_aio_ctx_release(struct kref *refcount); | |
143 | int setup_aio_ctx_iter(struct cifs_aio_ctx *ctx, struct iov_iter *iter, int rw); | |
144 | + | |
145 | +int cifs_alloc_hash(const char *name, struct crypto_shash **shash, | |
146 | + struct sdesc **sdesc); | |
147 | +void cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc); | |
148 | + | |
149 | #endif /* _CIFSPROTO_H */ | |
150 | --- a/fs/cifs/link.c | |
151 | +++ b/fs/cifs/link.c | |
152 | @@ -50,25 +50,12 @@ static int | |
153 | symlink_hash(unsigned int link_len, const char *link_str, u8 *md5_hash) | |
154 | { | |
155 | int rc; | |
156 | - unsigned int size; | |
157 | - struct crypto_shash *md5; | |
158 | - struct sdesc *sdescmd5; | |
159 | + struct crypto_shash *md5 = NULL; | |
160 | + struct sdesc *sdescmd5 = NULL; | |
161 | ||
162 | - md5 = crypto_alloc_shash("md5", 0, 0); | |
163 | - if (IS_ERR(md5)) { | |
164 | - rc = PTR_ERR(md5); | |
165 | - cifs_dbg(VFS, "%s: Crypto md5 allocation error %d\n", | |
166 | - __func__, rc); | |
167 | - return rc; | |
168 | - } | |
169 | - size = sizeof(struct shash_desc) + crypto_shash_descsize(md5); | |
170 | - sdescmd5 = kmalloc(size, GFP_KERNEL); | |
171 | - if (!sdescmd5) { | |
172 | - rc = -ENOMEM; | |
173 | + rc = cifs_alloc_hash("md5", &md5, &sdescmd5); | |
174 | + if (rc) | |
175 | goto symlink_hash_err; | |
176 | - } | |
177 | - sdescmd5->shash.tfm = md5; | |
178 | - sdescmd5->shash.flags = 0x0; | |
179 | ||
180 | rc = crypto_shash_init(&sdescmd5->shash); | |
181 | if (rc) { | |
182 | @@ -85,9 +72,7 @@ symlink_hash(unsigned int link_len, cons | |
183 | cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__); | |
184 | ||
185 | symlink_hash_err: | |
186 | - crypto_free_shash(md5); | |
187 | - kfree(sdescmd5); | |
188 | - | |
189 | + cifs_free_hash(&md5, &sdescmd5); | |
190 | return rc; | |
191 | } | |
192 | ||
193 | --- a/fs/cifs/misc.c | |
194 | +++ b/fs/cifs/misc.c | |
195 | @@ -848,3 +848,57 @@ setup_aio_ctx_iter(struct cifs_aio_ctx * | |
196 | iov_iter_bvec(&ctx->iter, ITER_BVEC | rw, ctx->bv, npages, ctx->len); | |
197 | return 0; | |
198 | } | |
199 | + | |
200 | +/** | |
201 | + * cifs_alloc_hash - allocate hash and hash context together | |
202 | + * | |
203 | + * The caller has to make sure @sdesc is initialized to either NULL or | |
204 | + * a valid context. Both can be freed via cifs_free_hash(). | |
205 | + */ | |
206 | +int | |
207 | +cifs_alloc_hash(const char *name, | |
208 | + struct crypto_shash **shash, struct sdesc **sdesc) | |
209 | +{ | |
210 | + int rc = 0; | |
211 | + size_t size; | |
212 | + | |
213 | + if (*sdesc != NULL) | |
214 | + return 0; | |
215 | + | |
216 | + *shash = crypto_alloc_shash(name, 0, 0); | |
217 | + if (IS_ERR(*shash)) { | |
218 | + cifs_dbg(VFS, "could not allocate crypto %s\n", name); | |
219 | + rc = PTR_ERR(*shash); | |
220 | + *shash = NULL; | |
221 | + *sdesc = NULL; | |
222 | + return rc; | |
223 | + } | |
224 | + | |
225 | + size = sizeof(struct shash_desc) + crypto_shash_descsize(*shash); | |
226 | + *sdesc = kmalloc(size, GFP_KERNEL); | |
227 | + if (*sdesc == NULL) { | |
228 | + cifs_dbg(VFS, "no memory left to allocate crypto %s\n", name); | |
229 | + crypto_free_shash(*shash); | |
230 | + *shash = NULL; | |
231 | + return -ENOMEM; | |
232 | + } | |
233 | + | |
234 | + (*sdesc)->shash.tfm = *shash; | |
235 | + (*sdesc)->shash.flags = 0x0; | |
236 | + return 0; | |
237 | +} | |
238 | + | |
239 | +/** | |
240 | + * cifs_free_hash - free hash and hash context together | |
241 | + * | |
242 | + * Freeing a NULL hash or context is safe. | |
243 | + */ | |
244 | +void | |
245 | +cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc) | |
246 | +{ | |
247 | + kfree(*sdesc); | |
248 | + *sdesc = NULL; | |
249 | + if (*shash) | |
250 | + crypto_free_shash(*shash); | |
251 | + *shash = NULL; | |
252 | +} | |
253 | --- a/fs/cifs/smb2transport.c | |
254 | +++ b/fs/cifs/smb2transport.c | |
255 | @@ -43,76 +43,31 @@ | |
256 | static int | |
257 | smb2_crypto_shash_allocate(struct TCP_Server_Info *server) | |
258 | { | |
259 | - int rc; | |
260 | - unsigned int size; | |
261 | - | |
262 | - if (server->secmech.sdeschmacsha256 != NULL) | |
263 | - return 0; /* already allocated */ | |
264 | - | |
265 | - server->secmech.hmacsha256 = crypto_alloc_shash("hmac(sha256)", 0, 0); | |
266 | - if (IS_ERR(server->secmech.hmacsha256)) { | |
267 | - cifs_dbg(VFS, "could not allocate crypto hmacsha256\n"); | |
268 | - rc = PTR_ERR(server->secmech.hmacsha256); | |
269 | - server->secmech.hmacsha256 = NULL; | |
270 | - return rc; | |
271 | - } | |
272 | - | |
273 | - size = sizeof(struct shash_desc) + | |
274 | - crypto_shash_descsize(server->secmech.hmacsha256); | |
275 | - server->secmech.sdeschmacsha256 = kmalloc(size, GFP_KERNEL); | |
276 | - if (!server->secmech.sdeschmacsha256) { | |
277 | - crypto_free_shash(server->secmech.hmacsha256); | |
278 | - server->secmech.hmacsha256 = NULL; | |
279 | - return -ENOMEM; | |
280 | - } | |
281 | - server->secmech.sdeschmacsha256->shash.tfm = server->secmech.hmacsha256; | |
282 | - server->secmech.sdeschmacsha256->shash.flags = 0x0; | |
283 | - | |
284 | - return 0; | |
285 | + return cifs_alloc_hash("hmac(sha256)", | |
286 | + &server->secmech.hmacsha256, | |
287 | + &server->secmech.sdeschmacsha256); | |
288 | } | |
289 | ||
290 | static int | |
291 | smb3_crypto_shash_allocate(struct TCP_Server_Info *server) | |
292 | { | |
293 | - unsigned int size; | |
294 | + struct cifs_secmech *p = &server->secmech; | |
295 | int rc; | |
296 | ||
297 | - if (server->secmech.sdesccmacaes != NULL) | |
298 | - return 0; /* already allocated */ | |
299 | - | |
300 | - rc = smb2_crypto_shash_allocate(server); | |
301 | + rc = cifs_alloc_hash("hmac(sha256)", | |
302 | + &p->hmacsha256, | |
303 | + &p->sdeschmacsha256); | |
304 | if (rc) | |
305 | - return rc; | |
306 | - | |
307 | - server->secmech.cmacaes = crypto_alloc_shash("cmac(aes)", 0, 0); | |
308 | - if (IS_ERR(server->secmech.cmacaes)) { | |
309 | - cifs_dbg(VFS, "could not allocate crypto cmac-aes"); | |
310 | - kfree(server->secmech.sdeschmacsha256); | |
311 | - server->secmech.sdeschmacsha256 = NULL; | |
312 | - crypto_free_shash(server->secmech.hmacsha256); | |
313 | - server->secmech.hmacsha256 = NULL; | |
314 | - rc = PTR_ERR(server->secmech.cmacaes); | |
315 | - server->secmech.cmacaes = NULL; | |
316 | - return rc; | |
317 | - } | |
318 | + goto err; | |
319 | ||
320 | - size = sizeof(struct shash_desc) + | |
321 | - crypto_shash_descsize(server->secmech.cmacaes); | |
322 | - server->secmech.sdesccmacaes = kmalloc(size, GFP_KERNEL); | |
323 | - if (!server->secmech.sdesccmacaes) { | |
324 | - cifs_dbg(VFS, "%s: Can't alloc cmacaes\n", __func__); | |
325 | - kfree(server->secmech.sdeschmacsha256); | |
326 | - server->secmech.sdeschmacsha256 = NULL; | |
327 | - crypto_free_shash(server->secmech.hmacsha256); | |
328 | - crypto_free_shash(server->secmech.cmacaes); | |
329 | - server->secmech.hmacsha256 = NULL; | |
330 | - server->secmech.cmacaes = NULL; | |
331 | - return -ENOMEM; | |
332 | - } | |
333 | - server->secmech.sdesccmacaes->shash.tfm = server->secmech.cmacaes; | |
334 | - server->secmech.sdesccmacaes->shash.flags = 0x0; | |
335 | + rc = cifs_alloc_hash("cmac(aes)", &p->cmacaes, &p->sdesccmacaes); | |
336 | + if (rc) | |
337 | + goto err; | |
338 | ||
339 | return 0; | |
340 | +err: | |
341 | + cifs_free_hash(&p->hmacsha256, &p->sdeschmacsha256); | |
342 | + return rc; | |
343 | } | |
344 | ||
345 | static struct cifs_ses * | |
346 | @@ -457,7 +412,7 @@ smb3_calc_signature(struct smb_rqst *rqs | |
347 | cifs_dbg(VFS, "%s: Could not init cmac aes\n", __func__); | |
348 | return rc; | |
349 | } | |
350 | - | |
351 | + | |
352 | rc = __cifs_calc_signature(rqst, server, sigptr, | |
353 | &server->secmech.sdesccmacaes->shash); | |
354 | ||
355 | --- a/fs/cifs/smbencrypt.c | |
356 | +++ b/fs/cifs/smbencrypt.c | |
357 | @@ -121,25 +121,12 @@ int | |
358 | mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len) | |
359 | { | |
360 | int rc; | |
361 | - unsigned int size; | |
362 | - struct crypto_shash *md4; | |
363 | - struct sdesc *sdescmd4; | |
364 | + struct crypto_shash *md4 = NULL; | |
365 | + struct sdesc *sdescmd4 = NULL; | |
366 | ||
367 | - md4 = crypto_alloc_shash("md4", 0, 0); | |
368 | - if (IS_ERR(md4)) { | |
369 | - rc = PTR_ERR(md4); | |
370 | - cifs_dbg(VFS, "%s: Crypto md4 allocation error %d\n", | |
371 | - __func__, rc); | |
372 | - return rc; | |
373 | - } | |
374 | - size = sizeof(struct shash_desc) + crypto_shash_descsize(md4); | |
375 | - sdescmd4 = kmalloc(size, GFP_KERNEL); | |
376 | - if (!sdescmd4) { | |
377 | - rc = -ENOMEM; | |
378 | + rc = cifs_alloc_hash("md4", &md4, &sdescmd4); | |
379 | + if (rc) | |
380 | goto mdfour_err; | |
381 | - } | |
382 | - sdescmd4->shash.tfm = md4; | |
383 | - sdescmd4->shash.flags = 0x0; | |
384 | ||
385 | rc = crypto_shash_init(&sdescmd4->shash); | |
386 | if (rc) { | |
387 | @@ -156,9 +143,7 @@ mdfour(unsigned char *md4_hash, unsigned | |
388 | cifs_dbg(VFS, "%s: Could not generate md4 hash\n", __func__); | |
389 | ||
390 | mdfour_err: | |
391 | - crypto_free_shash(md4); | |
392 | - kfree(sdescmd4); | |
393 | - | |
394 | + cifs_free_hash(&md4, &sdescmd4); | |
395 | return rc; | |
396 | } | |
397 |