Skip to content

Commit 82fb82b

Browse files
aaptelSteve French
authored andcommitted
CIFS: refactor crypto shash/sdesc allocation&free
shash and sdesc and always allocated and freed together. * abstract this in new functions cifs_alloc_hash() and cifs_free_hash(). * make smb2/3 crypto allocation independent from each other. Signed-off-by: Aurelien Aptel <[email protected]> Signed-off-by: Steve French <[email protected]> Reviewed-by: Ronnie Sahlberg <[email protected]> CC: Stable <[email protected]>
1 parent f30e414 commit 82fb82b

File tree

6 files changed

+93
-173
lines changed

6 files changed

+93
-173
lines changed

fs/cifs/cifsencrypt.c

Lines changed: 7 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -36,37 +36,6 @@
3636
#include <crypto/skcipher.h>
3737
#include <crypto/aead.h>
3838

39-
static int
40-
cifs_crypto_shash_md5_allocate(struct TCP_Server_Info *server)
41-
{
42-
int rc;
43-
unsigned int size;
44-
45-
if (server->secmech.sdescmd5 != NULL)
46-
return 0; /* already allocated */
47-
48-
server->secmech.md5 = crypto_alloc_shash("md5", 0, 0);
49-
if (IS_ERR(server->secmech.md5)) {
50-
cifs_dbg(VFS, "could not allocate crypto md5\n");
51-
rc = PTR_ERR(server->secmech.md5);
52-
server->secmech.md5 = NULL;
53-
return rc;
54-
}
55-
56-
size = sizeof(struct shash_desc) +
57-
crypto_shash_descsize(server->secmech.md5);
58-
server->secmech.sdescmd5 = kmalloc(size, GFP_KERNEL);
59-
if (!server->secmech.sdescmd5) {
60-
crypto_free_shash(server->secmech.md5);
61-
server->secmech.md5 = NULL;
62-
return -ENOMEM;
63-
}
64-
server->secmech.sdescmd5->shash.tfm = server->secmech.md5;
65-
server->secmech.sdescmd5->shash.flags = 0x0;
66-
67-
return 0;
68-
}
69-
7039
int __cifs_calc_signature(struct smb_rqst *rqst,
7140
struct TCP_Server_Info *server, char *signature,
7241
struct shash_desc *shash)
@@ -132,13 +101,10 @@ static int cifs_calc_signature(struct smb_rqst *rqst,
132101
if (!rqst->rq_iov || !signature || !server)
133102
return -EINVAL;
134103

135-
if (!server->secmech.sdescmd5) {
136-
rc = cifs_crypto_shash_md5_allocate(server);
137-
if (rc) {
138-
cifs_dbg(VFS, "%s: Can't alloc md5 crypto\n", __func__);
139-
return -1;
140-
}
141-
}
104+
rc = cifs_alloc_hash("md5", &server->secmech.md5,
105+
&server->secmech.sdescmd5);
106+
if (rc)
107+
return -1;
142108

143109
rc = crypto_shash_init(&server->secmech.sdescmd5->shash);
144110
if (rc) {
@@ -663,37 +629,6 @@ CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash)
663629
return rc;
664630
}
665631

666-
static int crypto_hmacmd5_alloc(struct TCP_Server_Info *server)
667-
{
668-
int rc;
669-
unsigned int size;
670-
671-
/* check if already allocated */
672-
if (server->secmech.sdeschmacmd5)
673-
return 0;
674-
675-
server->secmech.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0);
676-
if (IS_ERR(server->secmech.hmacmd5)) {
677-
cifs_dbg(VFS, "could not allocate crypto hmacmd5\n");
678-
rc = PTR_ERR(server->secmech.hmacmd5);
679-
server->secmech.hmacmd5 = NULL;
680-
return rc;
681-
}
682-
683-
size = sizeof(struct shash_desc) +
684-
crypto_shash_descsize(server->secmech.hmacmd5);
685-
server->secmech.sdeschmacmd5 = kmalloc(size, GFP_KERNEL);
686-
if (!server->secmech.sdeschmacmd5) {
687-
crypto_free_shash(server->secmech.hmacmd5);
688-
server->secmech.hmacmd5 = NULL;
689-
return -ENOMEM;
690-
}
691-
server->secmech.sdeschmacmd5->shash.tfm = server->secmech.hmacmd5;
692-
server->secmech.sdeschmacmd5->shash.flags = 0x0;
693-
694-
return 0;
695-
}
696-
697632
int
698633
setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
699634
{
@@ -757,9 +692,10 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
757692

758693
mutex_lock(&ses->server->srv_mutex);
759694

760-
rc = crypto_hmacmd5_alloc(ses->server);
695+
rc = cifs_alloc_hash("hmac(md5)",
696+
&ses->server->secmech.hmacmd5,
697+
&ses->server->secmech.sdeschmacmd5);
761698
if (rc) {
762-
cifs_dbg(VFS, "could not crypto alloc hmacmd5 rc %d\n", rc);
763699
goto unlock;
764700
}
765701

fs/cifs/cifsproto.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,4 +542,9 @@ enum securityEnum cifs_select_sectype(struct TCP_Server_Info *,
542542
struct cifs_aio_ctx *cifs_aio_ctx_alloc(void);
543543
void cifs_aio_ctx_release(struct kref *refcount);
544544
int setup_aio_ctx_iter(struct cifs_aio_ctx *ctx, struct iov_iter *iter, int rw);
545+
546+
int cifs_alloc_hash(const char *name, struct crypto_shash **shash,
547+
struct sdesc **sdesc);
548+
void cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc);
549+
545550
#endif /* _CIFSPROTO_H */

fs/cifs/link.c

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -50,25 +50,12 @@ static int
5050
symlink_hash(unsigned int link_len, const char *link_str, u8 *md5_hash)
5151
{
5252
int rc;
53-
unsigned int size;
54-
struct crypto_shash *md5;
55-
struct sdesc *sdescmd5;
56-
57-
md5 = crypto_alloc_shash("md5", 0, 0);
58-
if (IS_ERR(md5)) {
59-
rc = PTR_ERR(md5);
60-
cifs_dbg(VFS, "%s: Crypto md5 allocation error %d\n",
61-
__func__, rc);
62-
return rc;
63-
}
64-
size = sizeof(struct shash_desc) + crypto_shash_descsize(md5);
65-
sdescmd5 = kmalloc(size, GFP_KERNEL);
66-
if (!sdescmd5) {
67-
rc = -ENOMEM;
53+
struct crypto_shash *md5 = NULL;
54+
struct sdesc *sdescmd5 = NULL;
55+
56+
rc = cifs_alloc_hash("md5", &md5, &sdescmd5);
57+
if (rc)
6858
goto symlink_hash_err;
69-
}
70-
sdescmd5->shash.tfm = md5;
71-
sdescmd5->shash.flags = 0x0;
7259

7360
rc = crypto_shash_init(&sdescmd5->shash);
7461
if (rc) {
@@ -85,9 +72,7 @@ symlink_hash(unsigned int link_len, const char *link_str, u8 *md5_hash)
8572
cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__);
8673

8774
symlink_hash_err:
88-
crypto_free_shash(md5);
89-
kfree(sdescmd5);
90-
75+
cifs_free_hash(&md5, &sdescmd5);
9176
return rc;
9277
}
9378

fs/cifs/misc.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -848,3 +848,57 @@ setup_aio_ctx_iter(struct cifs_aio_ctx *ctx, struct iov_iter *iter, int rw)
848848
iov_iter_bvec(&ctx->iter, ITER_BVEC | rw, ctx->bv, npages, ctx->len);
849849
return 0;
850850
}
851+
852+
/**
853+
* cifs_alloc_hash - allocate hash and hash context together
854+
*
855+
* The caller has to make sure @sdesc is initialized to either NULL or
856+
* a valid context. Both can be freed via cifs_free_hash().
857+
*/
858+
int
859+
cifs_alloc_hash(const char *name,
860+
struct crypto_shash **shash, struct sdesc **sdesc)
861+
{
862+
int rc = 0;
863+
size_t size;
864+
865+
if (*sdesc != NULL)
866+
return 0;
867+
868+
*shash = crypto_alloc_shash(name, 0, 0);
869+
if (IS_ERR(*shash)) {
870+
cifs_dbg(VFS, "could not allocate crypto %s\n", name);
871+
rc = PTR_ERR(*shash);
872+
*shash = NULL;
873+
*sdesc = NULL;
874+
return rc;
875+
}
876+
877+
size = sizeof(struct shash_desc) + crypto_shash_descsize(*shash);
878+
*sdesc = kmalloc(size, GFP_KERNEL);
879+
if (*sdesc == NULL) {
880+
cifs_dbg(VFS, "no memory left to allocate crypto %s\n", name);
881+
crypto_free_shash(*shash);
882+
*shash = NULL;
883+
return -ENOMEM;
884+
}
885+
886+
(*sdesc)->shash.tfm = *shash;
887+
(*sdesc)->shash.flags = 0x0;
888+
return 0;
889+
}
890+
891+
/**
892+
* cifs_free_hash - free hash and hash context together
893+
*
894+
* Freeing a NULL hash or context is safe.
895+
*/
896+
void
897+
cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc)
898+
{
899+
kfree(*sdesc);
900+
*sdesc = NULL;
901+
if (*shash)
902+
crypto_free_shash(*shash);
903+
*shash = NULL;
904+
}

fs/cifs/smb2transport.c

Lines changed: 15 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -43,76 +43,31 @@
4343
static int
4444
smb2_crypto_shash_allocate(struct TCP_Server_Info *server)
4545
{
46-
int rc;
47-
unsigned int size;
48-
49-
if (server->secmech.sdeschmacsha256 != NULL)
50-
return 0; /* already allocated */
51-
52-
server->secmech.hmacsha256 = crypto_alloc_shash("hmac(sha256)", 0, 0);
53-
if (IS_ERR(server->secmech.hmacsha256)) {
54-
cifs_dbg(VFS, "could not allocate crypto hmacsha256\n");
55-
rc = PTR_ERR(server->secmech.hmacsha256);
56-
server->secmech.hmacsha256 = NULL;
57-
return rc;
58-
}
59-
60-
size = sizeof(struct shash_desc) +
61-
crypto_shash_descsize(server->secmech.hmacsha256);
62-
server->secmech.sdeschmacsha256 = kmalloc(size, GFP_KERNEL);
63-
if (!server->secmech.sdeschmacsha256) {
64-
crypto_free_shash(server->secmech.hmacsha256);
65-
server->secmech.hmacsha256 = NULL;
66-
return -ENOMEM;
67-
}
68-
server->secmech.sdeschmacsha256->shash.tfm = server->secmech.hmacsha256;
69-
server->secmech.sdeschmacsha256->shash.flags = 0x0;
70-
71-
return 0;
46+
return cifs_alloc_hash("hmac(sha256)",
47+
&server->secmech.hmacsha256,
48+
&server->secmech.sdeschmacsha256);
7249
}
7350

7451
static int
7552
smb3_crypto_shash_allocate(struct TCP_Server_Info *server)
7653
{
77-
unsigned int size;
54+
struct cifs_secmech *p = &server->secmech;
7855
int rc;
7956

80-
if (server->secmech.sdesccmacaes != NULL)
81-
return 0; /* already allocated */
82-
83-
rc = smb2_crypto_shash_allocate(server);
57+
rc = cifs_alloc_hash("hmac(sha256)",
58+
&p->hmacsha256,
59+
&p->sdeschmacsha256);
8460
if (rc)
85-
return rc;
86-
87-
server->secmech.cmacaes = crypto_alloc_shash("cmac(aes)", 0, 0);
88-
if (IS_ERR(server->secmech.cmacaes)) {
89-
cifs_dbg(VFS, "could not allocate crypto cmac-aes");
90-
kfree(server->secmech.sdeschmacsha256);
91-
server->secmech.sdeschmacsha256 = NULL;
92-
crypto_free_shash(server->secmech.hmacsha256);
93-
server->secmech.hmacsha256 = NULL;
94-
rc = PTR_ERR(server->secmech.cmacaes);
95-
server->secmech.cmacaes = NULL;
96-
return rc;
97-
}
61+
goto err;
9862

99-
size = sizeof(struct shash_desc) +
100-
crypto_shash_descsize(server->secmech.cmacaes);
101-
server->secmech.sdesccmacaes = kmalloc(size, GFP_KERNEL);
102-
if (!server->secmech.sdesccmacaes) {
103-
cifs_dbg(VFS, "%s: Can't alloc cmacaes\n", __func__);
104-
kfree(server->secmech.sdeschmacsha256);
105-
server->secmech.sdeschmacsha256 = NULL;
106-
crypto_free_shash(server->secmech.hmacsha256);
107-
crypto_free_shash(server->secmech.cmacaes);
108-
server->secmech.hmacsha256 = NULL;
109-
server->secmech.cmacaes = NULL;
110-
return -ENOMEM;
111-
}
112-
server->secmech.sdesccmacaes->shash.tfm = server->secmech.cmacaes;
113-
server->secmech.sdesccmacaes->shash.flags = 0x0;
63+
rc = cifs_alloc_hash("cmac(aes)", &p->cmacaes, &p->sdesccmacaes);
64+
if (rc)
65+
goto err;
11466

11567
return 0;
68+
err:
69+
cifs_free_hash(&p->hmacsha256, &p->sdeschmacsha256);
70+
return rc;
11671
}
11772

11873
static struct cifs_ses *
@@ -457,7 +412,7 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
457412
cifs_dbg(VFS, "%s: Could not init cmac aes\n", __func__);
458413
return rc;
459414
}
460-
415+
461416
rc = __cifs_calc_signature(rqst, server, sigptr,
462417
&server->secmech.sdesccmacaes->shash);
463418

fs/cifs/smbencrypt.c

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -121,25 +121,12 @@ int
121121
mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len)
122122
{
123123
int rc;
124-
unsigned int size;
125-
struct crypto_shash *md4;
126-
struct sdesc *sdescmd4;
127-
128-
md4 = crypto_alloc_shash("md4", 0, 0);
129-
if (IS_ERR(md4)) {
130-
rc = PTR_ERR(md4);
131-
cifs_dbg(VFS, "%s: Crypto md4 allocation error %d\n",
132-
__func__, rc);
133-
return rc;
134-
}
135-
size = sizeof(struct shash_desc) + crypto_shash_descsize(md4);
136-
sdescmd4 = kmalloc(size, GFP_KERNEL);
137-
if (!sdescmd4) {
138-
rc = -ENOMEM;
124+
struct crypto_shash *md4 = NULL;
125+
struct sdesc *sdescmd4 = NULL;
126+
127+
rc = cifs_alloc_hash("md4", &md4, &sdescmd4);
128+
if (rc)
139129
goto mdfour_err;
140-
}
141-
sdescmd4->shash.tfm = md4;
142-
sdescmd4->shash.flags = 0x0;
143130

144131
rc = crypto_shash_init(&sdescmd4->shash);
145132
if (rc) {
@@ -156,9 +143,7 @@ mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len)
156143
cifs_dbg(VFS, "%s: Could not generate md4 hash\n", __func__);
157144

158145
mdfour_err:
159-
crypto_free_shash(md4);
160-
kfree(sdescmd4);
161-
146+
cifs_free_hash(&md4, &sdescmd4);
162147
return rc;
163148
}
164149

0 commit comments

Comments
 (0)