]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.16.4/cifs-refactor-crypto-shash-sdesc-allocation-free.patch
Fixes for 4.19
[thirdparty/kernel/stable-queue.git] / releases / 4.16.4 / cifs-refactor-crypto-shash-sdesc-allocation-free.patch
CommitLineData
3681ac45
GKH
1From 82fb82be05585426405667dd5f0510aa953ba439 Mon Sep 17 00:00:00 2001
2From: Aurelien Aptel <aaptel@suse.com>
3Date: Fri, 16 Feb 2018 19:19:27 +0100
4Subject: CIFS: refactor crypto shash/sdesc allocation&free
5
6From: Aurelien Aptel <aaptel@suse.com>
7
8commit 82fb82be05585426405667dd5f0510aa953ba439 upstream.
9
10shash 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
14Signed-off-by: Aurelien Aptel <aaptel@suse.com>
15Signed-off-by: Steve French <smfrench@gmail.com>
16Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
17CC: Stable <stable@vger.kernel.org>
18Signed-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