summaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-07-26 14:11:28 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-26 14:11:28 -0400
commit1d87c28e680ce4ecb8c260d8ce070b8339d52abb (patch)
tree84d145886c982d1193418bb9e43de774beb21d3b /fs/cifs
parentaebdd82e18c38258fe84ea080a43c098e826ef63 (diff)
parent14cae3243b555afda69a57778069ddca65532c06 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6: cifs: Cleanup: check return codes of crypto api calls CIFS: Fix oops while mounting with prefixpath [CIFS] Redundant null check after dereference cifs: use cifs_dirent in cifs_save_resume_key cifs: use cifs_dirent to replace cifs_get_name_from_search_buf cifs: introduce cifs_dirent cifs: cleanup cifs_filldir
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/cifsencrypt.c110
-rw-r--r--fs/cifs/cifsglob.h2
-rw-r--r--fs/cifs/dir.c5
-rw-r--r--fs/cifs/link.c8
-rw-r--r--fs/cifs/readdir.c427
-rw-r--r--fs/cifs/smbencrypt.c8
6 files changed, 286 insertions, 274 deletions
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index 5a0ee7f2af06..259991bd2112 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -52,19 +52,29 @@ static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu,
52 52
53 rc = crypto_shash_init(&server->secmech.sdescmd5->shash); 53 rc = crypto_shash_init(&server->secmech.sdescmd5->shash);
54 if (rc) { 54 if (rc) {
55 cERROR(1, "%s: Oould not init md5\n", __func__); 55 cERROR(1, "%s: Could not init md5\n", __func__);
56 return rc; 56 return rc;
57 } 57 }
58 58
59 crypto_shash_update(&server->secmech.sdescmd5->shash, 59 rc = crypto_shash_update(&server->secmech.sdescmd5->shash,
60 server->session_key.response, server->session_key.len); 60 server->session_key.response, server->session_key.len);
61 if (rc) {
62 cERROR(1, "%s: Could not update with response\n", __func__);
63 return rc;
64 }
61 65
62 crypto_shash_update(&server->secmech.sdescmd5->shash, 66 rc = crypto_shash_update(&server->secmech.sdescmd5->shash,
63 cifs_pdu->Protocol, be32_to_cpu(cifs_pdu->smb_buf_length)); 67 cifs_pdu->Protocol, be32_to_cpu(cifs_pdu->smb_buf_length));
68 if (rc) {
69 cERROR(1, "%s: Could not update with payload\n", __func__);
70 return rc;
71 }
64 72
65 rc = crypto_shash_final(&server->secmech.sdescmd5->shash, signature); 73 rc = crypto_shash_final(&server->secmech.sdescmd5->shash, signature);
74 if (rc)
75 cERROR(1, "%s: Could not generate md5 hash\n", __func__);
66 76
67 return 0; 77 return rc;
68} 78}
69 79
70/* must be called with server->srv_mutex held */ 80/* must be called with server->srv_mutex held */
@@ -112,12 +122,16 @@ static int cifs_calc_signature2(const struct kvec *iov, int n_vec,
112 122
113 rc = crypto_shash_init(&server->secmech.sdescmd5->shash); 123 rc = crypto_shash_init(&server->secmech.sdescmd5->shash);
114 if (rc) { 124 if (rc) {
115 cERROR(1, "%s: Oould not init md5\n", __func__); 125 cERROR(1, "%s: Could not init md5\n", __func__);
116 return rc; 126 return rc;
117 } 127 }
118 128
119 crypto_shash_update(&server->secmech.sdescmd5->shash, 129 rc = crypto_shash_update(&server->secmech.sdescmd5->shash,
120 server->session_key.response, server->session_key.len); 130 server->session_key.response, server->session_key.len);
131 if (rc) {
132 cERROR(1, "%s: Could not update with response\n", __func__);
133 return rc;
134 }
121 135
122 for (i = 0; i < n_vec; i++) { 136 for (i = 0; i < n_vec; i++) {
123 if (iov[i].iov_len == 0) 137 if (iov[i].iov_len == 0)
@@ -131,14 +145,24 @@ static int cifs_calc_signature2(const struct kvec *iov, int n_vec,
131 if (i == 0) { 145 if (i == 0) {
132 if (iov[0].iov_len <= 8) /* cmd field at offset 9 */ 146 if (iov[0].iov_len <= 8) /* cmd field at offset 9 */
133 break; /* nothing to sign or corrupt header */ 147 break; /* nothing to sign or corrupt header */
148 rc =
134 crypto_shash_update(&server->secmech.sdescmd5->shash, 149 crypto_shash_update(&server->secmech.sdescmd5->shash,
135 iov[i].iov_base + 4, iov[i].iov_len - 4); 150 iov[i].iov_base + 4, iov[i].iov_len - 4);
136 } else 151 } else {
152 rc =
137 crypto_shash_update(&server->secmech.sdescmd5->shash, 153 crypto_shash_update(&server->secmech.sdescmd5->shash,
138 iov[i].iov_base, iov[i].iov_len); 154 iov[i].iov_base, iov[i].iov_len);
155 }
156 if (rc) {
157 cERROR(1, "%s: Could not update with payload\n",
158 __func__);
159 return rc;
160 }
139 } 161 }
140 162
141 rc = crypto_shash_final(&server->secmech.sdescmd5->shash, signature); 163 rc = crypto_shash_final(&server->secmech.sdescmd5->shash, signature);
164 if (rc)
165 cERROR(1, "%s: Could not generate md5 hash\n", __func__);
142 166
143 return rc; 167 return rc;
144} 168}
@@ -463,8 +487,12 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
463 /* calculate md4 hash of password */ 487 /* calculate md4 hash of password */
464 E_md4hash(ses->password, nt_hash); 488 E_md4hash(ses->password, nt_hash);
465 489
466 crypto_shash_setkey(ses->server->secmech.hmacmd5, nt_hash, 490 rc = crypto_shash_setkey(ses->server->secmech.hmacmd5, nt_hash,
467 CIFS_NTHASH_SIZE); 491 CIFS_NTHASH_SIZE);
492 if (rc) {
493 cERROR(1, "%s: Could not set NT Hash as a key", __func__);
494 return rc;
495 }
468 496
469 rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash); 497 rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
470 if (rc) { 498 if (rc) {
@@ -478,13 +506,18 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
478 if (user == NULL) { 506 if (user == NULL) {
479 cERROR(1, "calc_ntlmv2_hash: user mem alloc failure\n"); 507 cERROR(1, "calc_ntlmv2_hash: user mem alloc failure\n");
480 rc = -ENOMEM; 508 rc = -ENOMEM;
481 goto calc_exit_2; 509 return rc;
482 } 510 }
483 len = cifs_strtoUCS((__le16 *)user, ses->user_name, len, nls_cp); 511 len = cifs_strtoUCS((__le16 *)user, ses->user_name, len, nls_cp);
484 UniStrupr(user); 512 UniStrupr(user);
485 513
486 crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, 514 rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
487 (char *)user, 2 * len); 515 (char *)user, 2 * len);
516 kfree(user);
517 if (rc) {
518 cERROR(1, "%s: Could not update with user\n", __func__);
519 return rc;
520 }
488 521
489 /* convert ses->domainName to unicode and uppercase */ 522 /* convert ses->domainName to unicode and uppercase */
490 if (ses->domainName) { 523 if (ses->domainName) {
@@ -494,13 +527,19 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
494 if (domain == NULL) { 527 if (domain == NULL) {
495 cERROR(1, "calc_ntlmv2_hash: domain mem alloc failure"); 528 cERROR(1, "calc_ntlmv2_hash: domain mem alloc failure");
496 rc = -ENOMEM; 529 rc = -ENOMEM;
497 goto calc_exit_1; 530 return rc;
498 } 531 }
499 len = cifs_strtoUCS((__le16 *)domain, ses->domainName, len, 532 len = cifs_strtoUCS((__le16 *)domain, ses->domainName, len,
500 nls_cp); 533 nls_cp);
534 rc =
501 crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, 535 crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
502 (char *)domain, 2 * len); 536 (char *)domain, 2 * len);
503 kfree(domain); 537 kfree(domain);
538 if (rc) {
539 cERROR(1, "%s: Could not update with domain\n",
540 __func__);
541 return rc;
542 }
504 } else if (ses->serverName) { 543 } else if (ses->serverName) {
505 len = strlen(ses->serverName); 544 len = strlen(ses->serverName);
506 545
@@ -508,21 +547,26 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
508 if (server == NULL) { 547 if (server == NULL) {
509 cERROR(1, "calc_ntlmv2_hash: server mem alloc failure"); 548 cERROR(1, "calc_ntlmv2_hash: server mem alloc failure");
510 rc = -ENOMEM; 549 rc = -ENOMEM;
511 goto calc_exit_1; 550 return rc;
512 } 551 }
513 len = cifs_strtoUCS((__le16 *)server, ses->serverName, len, 552 len = cifs_strtoUCS((__le16 *)server, ses->serverName, len,
514 nls_cp); 553 nls_cp);
554 rc =
515 crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, 555 crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
516 (char *)server, 2 * len); 556 (char *)server, 2 * len);
517 kfree(server); 557 kfree(server);
558 if (rc) {
559 cERROR(1, "%s: Could not update with server\n",
560 __func__);
561 return rc;
562 }
518 } 563 }
519 564
520 rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash, 565 rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
521 ntlmv2_hash); 566 ntlmv2_hash);
567 if (rc)
568 cERROR(1, "%s: Could not generate md5 hash\n", __func__);
522 569
523calc_exit_1:
524 kfree(user);
525calc_exit_2:
526 return rc; 570 return rc;
527} 571}
528 572
@@ -537,8 +581,12 @@ CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash)
537 return -1; 581 return -1;
538 } 582 }
539 583
540 crypto_shash_setkey(ses->server->secmech.hmacmd5, 584 rc = crypto_shash_setkey(ses->server->secmech.hmacmd5,
541 ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE); 585 ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
586 if (rc) {
587 cERROR(1, "%s: Could not set NTLMV2 Hash as a key", __func__);
588 return rc;
589 }
542 590
543 rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash); 591 rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
544 if (rc) { 592 if (rc) {
@@ -552,11 +600,17 @@ CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash)
552 else 600 else
553 memcpy(ses->auth_key.response + offset, 601 memcpy(ses->auth_key.response + offset,
554 ses->server->cryptkey, CIFS_SERVER_CHALLENGE_SIZE); 602 ses->server->cryptkey, CIFS_SERVER_CHALLENGE_SIZE);
555 crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, 603 rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
556 ses->auth_key.response + offset, ses->auth_key.len - offset); 604 ses->auth_key.response + offset, ses->auth_key.len - offset);
605 if (rc) {
606 cERROR(1, "%s: Could not update with response\n", __func__);
607 return rc;
608 }
557 609
558 rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash, 610 rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
559 ses->auth_key.response + CIFS_SESS_KEY_SIZE); 611 ses->auth_key.response + CIFS_SESS_KEY_SIZE);
612 if (rc)
613 cERROR(1, "%s: Could not generate md5 hash\n", __func__);
560 614
561 return rc; 615 return rc;
562} 616}
@@ -626,8 +680,12 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
626 } 680 }
627 681
628 /* now calculate the session key for NTLMv2 */ 682 /* now calculate the session key for NTLMv2 */
629 crypto_shash_setkey(ses->server->secmech.hmacmd5, 683 rc = crypto_shash_setkey(ses->server->secmech.hmacmd5,
630 ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE); 684 ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
685 if (rc) {
686 cERROR(1, "%s: Could not set NTLMV2 Hash as a key", __func__);
687 goto setup_ntlmv2_rsp_ret;
688 }
631 689
632 rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash); 690 rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
633 if (rc) { 691 if (rc) {
@@ -635,12 +693,18 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
635 goto setup_ntlmv2_rsp_ret; 693 goto setup_ntlmv2_rsp_ret;
636 } 694 }
637 695
638 crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, 696 rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
639 ses->auth_key.response + CIFS_SESS_KEY_SIZE, 697 ses->auth_key.response + CIFS_SESS_KEY_SIZE,
640 CIFS_HMAC_MD5_HASH_SIZE); 698 CIFS_HMAC_MD5_HASH_SIZE);
699 if (rc) {
700 cERROR(1, "%s: Could not update with response\n", __func__);
701 goto setup_ntlmv2_rsp_ret;
702 }
641 703
642 rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash, 704 rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
643 ses->auth_key.response); 705 ses->auth_key.response);
706 if (rc)
707 cERROR(1, "%s: Could not generate md5 hash\n", __func__);
644 708
645setup_ntlmv2_rsp_ret: 709setup_ntlmv2_rsp_ret:
646 kfree(tiblob); 710 kfree(tiblob);
@@ -668,8 +732,12 @@ calc_seckey(struct cifs_ses *ses)
668 732
669 desc.tfm = tfm_arc4; 733 desc.tfm = tfm_arc4;
670 734
671 crypto_blkcipher_setkey(tfm_arc4, ses->auth_key.response, 735 rc = crypto_blkcipher_setkey(tfm_arc4, ses->auth_key.response,
672 CIFS_SESS_KEY_SIZE); 736 CIFS_SESS_KEY_SIZE);
737 if (rc) {
738 cERROR(1, "%s: Could not set response as a key", __func__);
739 return rc;
740 }
673 741
674 sg_init_one(&sgin, sec_key, CIFS_SESS_KEY_SIZE); 742 sg_init_one(&sgin, sec_key, CIFS_SESS_KEY_SIZE);
675 sg_init_one(&sgout, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE); 743 sg_init_one(&sgout, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE);
@@ -688,7 +756,7 @@ calc_seckey(struct cifs_ses *ses)
688 756
689 crypto_free_blkcipher(tfm_arc4); 757 crypto_free_blkcipher(tfm_arc4);
690 758
691 return 0; 759 return rc;
692} 760}
693 761
694void 762void
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 6255fa812c7a..1fcf4e5b3112 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -501,7 +501,7 @@ struct cifs_search_info {
501 char *ntwrk_buf_start; 501 char *ntwrk_buf_start;
502 char *srch_entries_start; 502 char *srch_entries_start;
503 char *last_entry; 503 char *last_entry;
504 char *presume_name; 504 const char *presume_name;
505 unsigned int resume_name_len; 505 unsigned int resume_name_len;
506 bool endOfSearch:1; 506 bool endOfSearch:1;
507 bool emptyDir:1; 507 bool emptyDir:1;
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 499f27fc8576..ae576fbb5142 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -57,11 +57,6 @@ build_path_from_dentry(struct dentry *direntry)
57 struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); 57 struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
58 unsigned seq; 58 unsigned seq;
59 59
60 if (direntry == NULL)
61 return NULL; /* not much we can do if dentry is freed and
62 we need to reopen the file after it was closed implicitly
63 when the server crashed */
64
65 dirsep = CIFS_DIR_SEP(cifs_sb); 60 dirsep = CIFS_DIR_SEP(cifs_sb);
66 if (tcon->Flags & SMB_SHARE_IS_IN_DFS) 61 if (tcon->Flags & SMB_SHARE_IS_IN_DFS)
67 dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1); 62 dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1);
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 556b1a0b54de..db3f18cdf024 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -74,8 +74,14 @@ symlink_hash(unsigned int link_len, const char *link_str, u8 *md5_hash)
74 cERROR(1, "%s: Could not init md5 shash\n", __func__); 74 cERROR(1, "%s: Could not init md5 shash\n", __func__);
75 goto symlink_hash_err; 75 goto symlink_hash_err;
76 } 76 }
77 crypto_shash_update(&sdescmd5->shash, link_str, link_len); 77 rc = crypto_shash_update(&sdescmd5->shash, link_str, link_len);
78 if (rc) {
79 cERROR(1, "%s: Could not update iwth link_str\n", __func__);
80 goto symlink_hash_err;
81 }
78 rc = crypto_shash_final(&sdescmd5->shash, md5_hash); 82 rc = crypto_shash_final(&sdescmd5->shash, md5_hash);
83 if (rc)
84 cERROR(1, "%s: Could not generate md5 hash\n", __func__);
79 85
80symlink_hash_err: 86symlink_hash_err:
81 crypto_free_shash(md5); 87 crypto_free_shash(md5);
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 965a3af186a1..5de03ec20144 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -4,6 +4,7 @@
4 * Directory search handling 4 * Directory search handling
5 * 5 *
6 * Copyright (C) International Business Machines Corp., 2004, 2008 6 * Copyright (C) International Business Machines Corp., 2004, 2008
7 * Copyright (C) Red Hat, Inc., 2011
7 * Author(s): Steve French (sfrench@us.ibm.com) 8 * Author(s): Steve French (sfrench@us.ibm.com)
8 * 9 *
9 * This library is free software; you can redistribute it and/or modify 10 * This library is free software; you can redistribute it and/or modify
@@ -290,10 +291,10 @@ error_exit:
290} 291}
291 292
292/* return length of unicode string in bytes */ 293/* return length of unicode string in bytes */
293static int cifs_unicode_bytelen(char *str) 294static int cifs_unicode_bytelen(const char *str)
294{ 295{
295 int len; 296 int len;
296 __le16 *ustr = (__le16 *)str; 297 const __le16 *ustr = (const __le16 *)str;
297 298
298 for (len = 0; len <= PATH_MAX; len++) { 299 for (len = 0; len <= PATH_MAX; len++) {
299 if (ustr[len] == 0) 300 if (ustr[len] == 0)
@@ -334,78 +335,128 @@ static char *nxt_dir_entry(char *old_entry, char *end_of_smb, int level)
334 335
335} 336}
336 337
338struct cifs_dirent {
339 const char *name;
340 size_t namelen;
341 u32 resume_key;
342 u64 ino;
343};
344
345static void cifs_fill_dirent_unix(struct cifs_dirent *de,
346 const FILE_UNIX_INFO *info, bool is_unicode)
347{
348 de->name = &info->FileName[0];
349 if (is_unicode)
350 de->namelen = cifs_unicode_bytelen(de->name);
351 else
352 de->namelen = strnlen(de->name, PATH_MAX);
353 de->resume_key = info->ResumeKey;
354 de->ino = le64_to_cpu(info->basic.UniqueId);
355}
356
357static void cifs_fill_dirent_dir(struct cifs_dirent *de,
358 const FILE_DIRECTORY_INFO *info)
359{
360 de->name = &info->FileName[0];
361 de->namelen = le32_to_cpu(info->FileNameLength);
362 de->resume_key = info->FileIndex;
363}
364
365static void cifs_fill_dirent_full(struct cifs_dirent *de,
366 const FILE_FULL_DIRECTORY_INFO *info)
367{
368 de->name = &info->FileName[0];
369 de->namelen = le32_to_cpu(info->FileNameLength);
370 de->resume_key = info->FileIndex;
371}
372
373static void cifs_fill_dirent_search(struct cifs_dirent *de,
374 const SEARCH_ID_FULL_DIR_INFO *info)
375{
376 de->name = &info->FileName[0];
377 de->namelen = le32_to_cpu(info->FileNameLength);
378 de->resume_key = info->FileIndex;
379 de->ino = le64_to_cpu(info->UniqueId);
380}
381
382static void cifs_fill_dirent_both(struct cifs_dirent *de,
383 const FILE_BOTH_DIRECTORY_INFO *info)
384{
385 de->name = &info->FileName[0];
386 de->namelen = le32_to_cpu(info->FileNameLength);
387 de->resume_key = info->FileIndex;
388}
389
390static void cifs_fill_dirent_std(struct cifs_dirent *de,
391 const FIND_FILE_STANDARD_INFO *info)
392{
393 de->name = &info->FileName[0];
394 /* one byte length, no endianess conversion */
395 de->namelen = info->FileNameLength;
396 de->resume_key = info->ResumeKey;
397}
398
399static int cifs_fill_dirent(struct cifs_dirent *de, const void *info,
400 u16 level, bool is_unicode)
401{
402 memset(de, 0, sizeof(*de));
403
404 switch (level) {
405 case SMB_FIND_FILE_UNIX:
406 cifs_fill_dirent_unix(de, info, is_unicode);
407 break;
408 case SMB_FIND_FILE_DIRECTORY_INFO:
409 cifs_fill_dirent_dir(de, info);
410 break;
411 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
412 cifs_fill_dirent_full(de, info);
413 break;
414 case SMB_FIND_FILE_ID_FULL_DIR_INFO:
415 cifs_fill_dirent_search(de, info);
416 break;
417 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
418 cifs_fill_dirent_both(de, info);
419 break;
420 case SMB_FIND_FILE_INFO_STANDARD:
421 cifs_fill_dirent_std(de, info);
422 break;
423 default:
424 cFYI(1, "Unknown findfirst level %d", level);
425 return -EINVAL;
426 }
427
428 return 0;
429}
430
337#define UNICODE_DOT cpu_to_le16(0x2e) 431#define UNICODE_DOT cpu_to_le16(0x2e)
338 432
339/* return 0 if no match and 1 for . (current directory) and 2 for .. (parent) */ 433/* return 0 if no match and 1 for . (current directory) and 2 for .. (parent) */
340static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile) 434static int cifs_entry_is_dot(struct cifs_dirent *de, bool is_unicode)
341{ 435{
342 int rc = 0; 436 int rc = 0;
343 char *filename = NULL;
344 int len = 0;
345
346 if (cfile->srch_inf.info_level == SMB_FIND_FILE_UNIX) {
347 FILE_UNIX_INFO *pFindData = (FILE_UNIX_INFO *)current_entry;
348 filename = &pFindData->FileName[0];
349 if (cfile->srch_inf.unicode) {
350 len = cifs_unicode_bytelen(filename);
351 } else {
352 /* BB should we make this strnlen of PATH_MAX? */
353 len = strnlen(filename, 5);
354 }
355 } else if (cfile->srch_inf.info_level == SMB_FIND_FILE_DIRECTORY_INFO) {
356 FILE_DIRECTORY_INFO *pFindData =
357 (FILE_DIRECTORY_INFO *)current_entry;
358 filename = &pFindData->FileName[0];
359 len = le32_to_cpu(pFindData->FileNameLength);
360 } else if (cfile->srch_inf.info_level ==
361 SMB_FIND_FILE_FULL_DIRECTORY_INFO) {
362 FILE_FULL_DIRECTORY_INFO *pFindData =
363 (FILE_FULL_DIRECTORY_INFO *)current_entry;
364 filename = &pFindData->FileName[0];
365 len = le32_to_cpu(pFindData->FileNameLength);
366 } else if (cfile->srch_inf.info_level ==
367 SMB_FIND_FILE_ID_FULL_DIR_INFO) {
368 SEARCH_ID_FULL_DIR_INFO *pFindData =
369 (SEARCH_ID_FULL_DIR_INFO *)current_entry;
370 filename = &pFindData->FileName[0];
371 len = le32_to_cpu(pFindData->FileNameLength);
372 } else if (cfile->srch_inf.info_level ==
373 SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
374 FILE_BOTH_DIRECTORY_INFO *pFindData =
375 (FILE_BOTH_DIRECTORY_INFO *)current_entry;
376 filename = &pFindData->FileName[0];
377 len = le32_to_cpu(pFindData->FileNameLength);
378 } else if (cfile->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD) {
379 FIND_FILE_STANDARD_INFO *pFindData =
380 (FIND_FILE_STANDARD_INFO *)current_entry;
381 filename = &pFindData->FileName[0];
382 len = pFindData->FileNameLength;
383 } else {
384 cFYI(1, "Unknown findfirst level %d",
385 cfile->srch_inf.info_level);
386 }
387 437
388 if (filename) { 438 if (!de->name)
389 if (cfile->srch_inf.unicode) { 439 return 0;
390 __le16 *ufilename = (__le16 *)filename; 440
391 if (len == 2) { 441 if (is_unicode) {
392 /* check for . */ 442 __le16 *ufilename = (__le16 *)de->name;
393 if (ufilename[0] == UNICODE_DOT) 443 if (de->namelen == 2) {
394 rc = 1; 444 /* check for . */
395 } else if (len == 4) { 445 if (ufilename[0] == UNICODE_DOT)
396 /* check for .. */ 446 rc = 1;
397 if ((ufilename[0] == UNICODE_DOT) 447 } else if (de->namelen == 4) {
398 && (ufilename[1] == UNICODE_DOT)) 448 /* check for .. */
399 rc = 2; 449 if (ufilename[0] == UNICODE_DOT &&
400 } 450 ufilename[1] == UNICODE_DOT)
401 } else /* ASCII */ { 451 rc = 2;
402 if (len == 1) { 452 }
403 if (filename[0] == '.') 453 } else /* ASCII */ {
404 rc = 1; 454 if (de->namelen == 1) {
405 } else if (len == 2) { 455 if (de->name[0] == '.')
406 if ((filename[0] == '.') && (filename[1] == '.')) 456 rc = 1;
407 rc = 2; 457 } else if (de->namelen == 2) {
408 } 458 if (de->name[0] == '.' && de->name[1] == '.')
459 rc = 2;
409 } 460 }
410 } 461 }
411 462
@@ -427,66 +478,18 @@ static int is_dir_changed(struct file *file)
427} 478}
428 479
429static int cifs_save_resume_key(const char *current_entry, 480static int cifs_save_resume_key(const char *current_entry,
430 struct cifsFileInfo *cifsFile) 481 struct cifsFileInfo *file_info)
431{ 482{
432 int rc = 0; 483 struct cifs_dirent de;
433 unsigned int len = 0; 484 int rc;
434 __u16 level;
435 char *filename;
436
437 if ((cifsFile == NULL) || (current_entry == NULL))
438 return -EINVAL;
439
440 level = cifsFile->srch_inf.info_level;
441
442 if (level == SMB_FIND_FILE_UNIX) {
443 FILE_UNIX_INFO *pFindData = (FILE_UNIX_INFO *)current_entry;
444 485
445 filename = &pFindData->FileName[0]; 486 rc = cifs_fill_dirent(&de, current_entry, file_info->srch_inf.info_level,
446 if (cifsFile->srch_inf.unicode) { 487 file_info->srch_inf.unicode);
447 len = cifs_unicode_bytelen(filename); 488 if (!rc) {
448 } else { 489 file_info->srch_inf.presume_name = de.name;
449 /* BB should we make this strnlen of PATH_MAX? */ 490 file_info->srch_inf.resume_name_len = de.namelen;
450 len = strnlen(filename, PATH_MAX); 491 file_info->srch_inf.resume_key = de.resume_key;
451 }
452 cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
453 } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) {
454 FILE_DIRECTORY_INFO *pFindData =
455 (FILE_DIRECTORY_INFO *)current_entry;
456 filename = &pFindData->FileName[0];
457 len = le32_to_cpu(pFindData->FileNameLength);
458 cifsFile->srch_inf.resume_key = pFindData->FileIndex;
459 } else if (level == SMB_FIND_FILE_FULL_DIRECTORY_INFO) {
460 FILE_FULL_DIRECTORY_INFO *pFindData =
461 (FILE_FULL_DIRECTORY_INFO *)current_entry;
462 filename = &pFindData->FileName[0];
463 len = le32_to_cpu(pFindData->FileNameLength);
464 cifsFile->srch_inf.resume_key = pFindData->FileIndex;
465 } else if (level == SMB_FIND_FILE_ID_FULL_DIR_INFO) {
466 SEARCH_ID_FULL_DIR_INFO *pFindData =
467 (SEARCH_ID_FULL_DIR_INFO *)current_entry;
468 filename = &pFindData->FileName[0];
469 len = le32_to_cpu(pFindData->FileNameLength);
470 cifsFile->srch_inf.resume_key = pFindData->FileIndex;
471 } else if (level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
472 FILE_BOTH_DIRECTORY_INFO *pFindData =
473 (FILE_BOTH_DIRECTORY_INFO *)current_entry;
474 filename = &pFindData->FileName[0];
475 len = le32_to_cpu(pFindData->FileNameLength);
476 cifsFile->srch_inf.resume_key = pFindData->FileIndex;
477 } else if (level == SMB_FIND_FILE_INFO_STANDARD) {
478 FIND_FILE_STANDARD_INFO *pFindData =
479 (FIND_FILE_STANDARD_INFO *)current_entry;
480 filename = &pFindData->FileName[0];
481 /* one byte length, no name conversion */
482 len = (unsigned int)pFindData->FileNameLength;
483 cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
484 } else {
485 cFYI(1, "Unknown findfirst level %d", level);
486 return -EINVAL;
487 } 492 }
488 cifsFile->srch_inf.resume_name_len = len;
489 cifsFile->srch_inf.presume_name = filename;
490 return rc; 493 return rc;
491} 494}
492 495
@@ -605,136 +608,70 @@ static int find_cifs_entry(const int xid, struct cifs_tcon *pTcon,
605 return rc; 608 return rc;
606} 609}
607 610
608/* inode num, inode type and filename returned */ 611static int cifs_filldir(char *find_entry, struct file *file, filldir_t filldir,
609static int cifs_get_name_from_search_buf(struct qstr *pqst, 612 void *dirent, char *scratch_buf, unsigned int max_len)
610 char *current_entry, __u16 level, unsigned int unicode,
611 struct cifs_sb_info *cifs_sb, unsigned int max_len, __u64 *pinum)
612{ 613{
614 struct cifsFileInfo *file_info = file->private_data;
615 struct super_block *sb = file->f_path.dentry->d_sb;
616 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
617 struct cifs_dirent de = { NULL, };
618 struct cifs_fattr fattr;
619 struct dentry *dentry;
620 struct qstr name;
613 int rc = 0; 621 int rc = 0;
614 unsigned int len = 0; 622 ino_t ino;
615 char *filename;
616 struct nls_table *nlt = cifs_sb->local_nls;
617
618 *pinum = 0;
619
620 if (level == SMB_FIND_FILE_UNIX) {
621 FILE_UNIX_INFO *pFindData = (FILE_UNIX_INFO *)current_entry;
622
623 filename = &pFindData->FileName[0];
624 if (unicode) {
625 len = cifs_unicode_bytelen(filename);
626 } else {
627 /* BB should we make this strnlen of PATH_MAX? */
628 len = strnlen(filename, PATH_MAX);
629 }
630 623
631 *pinum = le64_to_cpu(pFindData->basic.UniqueId); 624 rc = cifs_fill_dirent(&de, find_entry, file_info->srch_inf.info_level,
632 } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) { 625 file_info->srch_inf.unicode);
633 FILE_DIRECTORY_INFO *pFindData = 626 if (rc)
634 (FILE_DIRECTORY_INFO *)current_entry; 627 return rc;
635 filename = &pFindData->FileName[0];
636 len = le32_to_cpu(pFindData->FileNameLength);
637 } else if (level == SMB_FIND_FILE_FULL_DIRECTORY_INFO) {
638 FILE_FULL_DIRECTORY_INFO *pFindData =
639 (FILE_FULL_DIRECTORY_INFO *)current_entry;
640 filename = &pFindData->FileName[0];
641 len = le32_to_cpu(pFindData->FileNameLength);
642 } else if (level == SMB_FIND_FILE_ID_FULL_DIR_INFO) {
643 SEARCH_ID_FULL_DIR_INFO *pFindData =
644 (SEARCH_ID_FULL_DIR_INFO *)current_entry;
645 filename = &pFindData->FileName[0];
646 len = le32_to_cpu(pFindData->FileNameLength);
647 *pinum = le64_to_cpu(pFindData->UniqueId);
648 } else if (level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
649 FILE_BOTH_DIRECTORY_INFO *pFindData =
650 (FILE_BOTH_DIRECTORY_INFO *)current_entry;
651 filename = &pFindData->FileName[0];
652 len = le32_to_cpu(pFindData->FileNameLength);
653 } else if (level == SMB_FIND_FILE_INFO_STANDARD) {
654 FIND_FILE_STANDARD_INFO *pFindData =
655 (FIND_FILE_STANDARD_INFO *)current_entry;
656 filename = &pFindData->FileName[0];
657 /* one byte length, no name conversion */
658 len = (unsigned int)pFindData->FileNameLength;
659 } else {
660 cFYI(1, "Unknown findfirst level %d", level);
661 return -EINVAL;
662 }
663 628
664 if (len > max_len) { 629 if (de.namelen > max_len) {
665 cERROR(1, "bad search response length %d past smb end", len); 630 cERROR(1, "bad search response length %zd past smb end",
631 de.namelen);
666 return -EINVAL; 632 return -EINVAL;
667 } 633 }
668 634
669 if (unicode) {
670 pqst->len = cifs_from_ucs2((char *) pqst->name,
671 (__le16 *) filename,
672 UNICODE_NAME_MAX,
673 min(len, max_len), nlt,
674 cifs_sb->mnt_cifs_flags &
675 CIFS_MOUNT_MAP_SPECIAL_CHR);
676 pqst->len -= nls_nullsize(nlt);
677 } else {
678 pqst->name = filename;
679 pqst->len = len;
680 }
681 return rc;
682}
683
684static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir,
685 void *direntry, char *scratch_buf, unsigned int max_len)
686{
687 int rc = 0;
688 struct qstr qstring;
689 struct cifsFileInfo *pCifsF;
690 u64 inum;
691 ino_t ino;
692 struct super_block *sb;
693 struct cifs_sb_info *cifs_sb;
694 struct dentry *tmp_dentry;
695 struct cifs_fattr fattr;
696
697 /* get filename and len into qstring */
698 /* get dentry */
699 /* decide whether to create and populate ionde */
700 if ((direntry == NULL) || (file == NULL))
701 return -EINVAL;
702
703 pCifsF = file->private_data;
704
705 if ((scratch_buf == NULL) || (pfindEntry == NULL) || (pCifsF == NULL))
706 return -ENOENT;
707
708 rc = cifs_entry_is_dot(pfindEntry, pCifsF);
709 /* skip . and .. since we added them first */ 635 /* skip . and .. since we added them first */
710 if (rc != 0) 636 if (cifs_entry_is_dot(&de, file_info->srch_inf.unicode))
711 return 0; 637 return 0;
712 638
713 sb = file->f_path.dentry->d_sb; 639 if (file_info->srch_inf.unicode) {
714 cifs_sb = CIFS_SB(sb); 640 struct nls_table *nlt = cifs_sb->local_nls;
715
716 qstring.name = scratch_buf;
717 rc = cifs_get_name_from_search_buf(&qstring, pfindEntry,
718 pCifsF->srch_inf.info_level,
719 pCifsF->srch_inf.unicode, cifs_sb,
720 max_len, &inum /* returned */);
721 641
722 if (rc) 642 name.name = scratch_buf;
723 return rc; 643 name.len =
644 cifs_from_ucs2((char *)name.name, (__le16 *)de.name,
645 UNICODE_NAME_MAX,
646 min(de.namelen, (size_t)max_len), nlt,
647 cifs_sb->mnt_cifs_flags &
648 CIFS_MOUNT_MAP_SPECIAL_CHR);
649 name.len -= nls_nullsize(nlt);
650 } else {
651 name.name = de.name;
652 name.len = de.namelen;
653 }
724 654
725 if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX) 655 switch (file_info->srch_inf.info_level) {
656 case SMB_FIND_FILE_UNIX:
726 cifs_unix_basic_to_fattr(&fattr, 657 cifs_unix_basic_to_fattr(&fattr,
727 &((FILE_UNIX_INFO *) pfindEntry)->basic, 658 &((FILE_UNIX_INFO *)find_entry)->basic,
728 cifs_sb); 659 cifs_sb);
729 else if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD) 660 break;
730 cifs_std_info_to_fattr(&fattr, (FIND_FILE_STANDARD_INFO *) 661 case SMB_FIND_FILE_INFO_STANDARD:
731 pfindEntry, cifs_sb); 662 cifs_std_info_to_fattr(&fattr,
732 else 663 (FIND_FILE_STANDARD_INFO *)find_entry,
733 cifs_dir_info_to_fattr(&fattr, (FILE_DIRECTORY_INFO *) 664 cifs_sb);
734 pfindEntry, cifs_sb); 665 break;
666 default:
667 cifs_dir_info_to_fattr(&fattr,
668 (FILE_DIRECTORY_INFO *)find_entry,
669 cifs_sb);
670 break;
671 }
735 672
736 if (inum && (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) { 673 if (de.ino && (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) {
737 fattr.cf_uniqueid = inum; 674 fattr.cf_uniqueid = de.ino;
738 } else { 675 } else {
739 fattr.cf_uniqueid = iunique(sb, ROOT_I); 676 fattr.cf_uniqueid = iunique(sb, ROOT_I);
740 cifs_autodisable_serverino(cifs_sb); 677 cifs_autodisable_serverino(cifs_sb);
@@ -750,12 +687,12 @@ static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir,
750 fattr.cf_flags |= CIFS_FATTR_NEED_REVAL; 687 fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;
751 688
752 ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid); 689 ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid);
753 tmp_dentry = cifs_readdir_lookup(file->f_dentry, &qstring, &fattr); 690 dentry = cifs_readdir_lookup(file->f_dentry, &name, &fattr);
754 691
755 rc = filldir(direntry, qstring.name, qstring.len, file->f_pos, 692 rc = filldir(dirent, name.name, name.len, file->f_pos, ino,
756 ino, fattr.cf_dtype); 693 fattr.cf_dtype);
757 694
758 dput(tmp_dentry); 695 dput(dentry);
759 return rc; 696 return rc;
760} 697}
761 698
diff --git a/fs/cifs/smbencrypt.c b/fs/cifs/smbencrypt.c
index 1c5b770c3141..42b9fff48751 100644
--- a/fs/cifs/smbencrypt.c
+++ b/fs/cifs/smbencrypt.c
@@ -157,8 +157,14 @@ mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len)
157 cERROR(1, "%s: Could not init md4 shash\n", __func__); 157 cERROR(1, "%s: Could not init md4 shash\n", __func__);
158 goto mdfour_err; 158 goto mdfour_err;
159 } 159 }
160 crypto_shash_update(&sdescmd4->shash, link_str, link_len); 160 rc = crypto_shash_update(&sdescmd4->shash, link_str, link_len);
161 if (rc) {
162 cERROR(1, "%s: Could not update with link_str\n", __func__);
163 goto mdfour_err;
164 }
161 rc = crypto_shash_final(&sdescmd4->shash, md4_hash); 165 rc = crypto_shash_final(&sdescmd4->shash, md4_hash);
166 if (rc)
167 cERROR(1, "%s: Could not genereate md4 hash\n", __func__);
162 168
163mdfour_err: 169mdfour_err:
164 crypto_free_shash(md4); 170 crypto_free_shash(md4);