aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/cifspdu.h47
-rw-r--r--fs/cifs/cifssmb.c14
-rw-r--r--fs/cifs/connect.c10
-rw-r--r--fs/cifs/netmisc.c4
-rw-r--r--fs/cifs/sess.c13
-rw-r--r--fs/cifs/transport.c9
6 files changed, 65 insertions, 32 deletions
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index ea205b4fcad2..b5c8cc5d7a7f 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -23,6 +23,7 @@
23#define _CIFSPDU_H 23#define _CIFSPDU_H
24 24
25#include <net/sock.h> 25#include <net/sock.h>
26#include <asm/unaligned.h>
26#include "smbfsctl.h" 27#include "smbfsctl.h"
27 28
28#ifdef CONFIG_CIFS_WEAK_PW_HASH 29#ifdef CONFIG_CIFS_WEAK_PW_HASH
@@ -426,11 +427,49 @@ struct smb_hdr {
426 __u16 Mid; 427 __u16 Mid;
427 __u8 WordCount; 428 __u8 WordCount;
428} __attribute__((packed)); 429} __attribute__((packed));
429/* given a pointer to an smb_hdr retrieve the value of byte count */ 430
430#define BCC(smb_var) (*(__u16 *)((char *)(smb_var) + sizeof(struct smb_hdr) + (2 * (smb_var)->WordCount))) 431/* given a pointer to an smb_hdr retrieve a char pointer to the byte count */
431#define BCC_LE(smb_var) (*(__le16 *)((char *)(smb_var) + sizeof(struct smb_hdr) + (2 * (smb_var)->WordCount))) 432#define BCC(smb_var) ((unsigned char *)(smb_var) + sizeof(struct smb_hdr) + \
433 (2 * (smb_var)->WordCount))
434
432/* given a pointer to an smb_hdr retrieve the pointer to the byte area */ 435/* given a pointer to an smb_hdr retrieve the pointer to the byte area */
433#define pByteArea(smb_var) ((unsigned char *)(smb_var) + sizeof(struct smb_hdr) + (2 * (smb_var)->WordCount) + 2) 436#define pByteArea(smb_var) (BCC(smb_var) + 2)
437
438/* get the converted ByteCount for a SMB packet and return it */
439static inline __u16
440get_bcc(struct smb_hdr *hdr)
441{
442 __u16 *bc_ptr = (__u16 *)BCC(hdr);
443
444 return get_unaligned(bc_ptr);
445}
446
447/* get the unconverted ByteCount for a SMB packet and return it */
448static inline __u16
449get_bcc_le(struct smb_hdr *hdr)
450{
451 __le16 *bc_ptr = (__le16 *)BCC(hdr);
452
453 return get_unaligned_le16(bc_ptr);
454}
455
456/* set the ByteCount for a SMB packet in host-byte order */
457static inline void
458put_bcc(__u16 count, struct smb_hdr *hdr)
459{
460 __u16 *bc_ptr = (__u16 *)BCC(hdr);
461
462 put_unaligned(count, bc_ptr);
463}
464
465/* set the ByteCount for a SMB packet in little-endian */
466static inline void
467put_bcc_le(__u16 count, struct smb_hdr *hdr)
468{
469 __le16 *bc_ptr = (__le16 *)BCC(hdr);
470
471 put_unaligned_le16(count, bc_ptr);
472}
434 473
435/* 474/*
436 * Computer Name Length (since Netbios name was length 16 with last byte 0x20) 475 * Computer Name Length (since Netbios name was length 16 with last byte 0x20)
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 5b1f6637f161..39cec0d9cd1b 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -333,7 +333,6 @@ static int validate_t2(struct smb_t2_rsp *pSMB)
333{ 333{
334 int rc = -EINVAL; 334 int rc = -EINVAL;
335 int total_size; 335 int total_size;
336 char *pBCC;
337 336
338 /* check for plausible wct, bcc and t2 data and parm sizes */ 337 /* check for plausible wct, bcc and t2 data and parm sizes */
339 /* check for parm and data offset going beyond end of smb */ 338 /* check for parm and data offset going beyond end of smb */
@@ -346,13 +345,9 @@ static int validate_t2(struct smb_t2_rsp *pSMB)
346 if (total_size < 512) { 345 if (total_size < 512) {
347 total_size += 346 total_size +=
348 le16_to_cpu(pSMB->t2_rsp.DataCount); 347 le16_to_cpu(pSMB->t2_rsp.DataCount);
349 /* BCC le converted in SendReceive */ 348 if (total_size <= get_bcc(&pSMB->hdr) &&
350 pBCC = (pSMB->hdr.WordCount * 2) + 349 total_size <
351 sizeof(struct smb_hdr) + 350 CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
352 (char *)pSMB;
353 if ((total_size <= (*(u16 *)pBCC)) &&
354 (total_size <
355 CIFSMaxBufSize+MAX_CIFS_HDR_SIZE)) {
356 return 0; 351 return 0;
357 } 352 }
358 } 353 }
@@ -362,6 +357,7 @@ static int validate_t2(struct smb_t2_rsp *pSMB)
362 sizeof(struct smb_t2_rsp) + 16); 357 sizeof(struct smb_t2_rsp) + 16);
363 return rc; 358 return rc;
364} 359}
360
365int 361int
366CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) 362CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
367{ 363{
@@ -5609,7 +5605,7 @@ QAllEAsRetry:
5609 } 5605 }
5610 5606
5611 /* make sure list_len doesn't go past end of SMB */ 5607 /* make sure list_len doesn't go past end of SMB */
5612 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + BCC(&pSMBr->hdr); 5608 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
5613 if ((char *)ea_response_data + list_len > end_of_smb) { 5609 if ((char *)ea_response_data + list_len > end_of_smb) {
5614 cFYI(1, "EA list appears to go beyond SMB"); 5610 cFYI(1, "EA list appears to go beyond SMB");
5615 rc = -EIO; 5611 rc = -EIO;
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 8d4657596301..ca20e813275d 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -318,9 +318,9 @@ static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
318 memcpy(data_area_of_target, data_area_of_buf2, total_in_buf2); 318 memcpy(data_area_of_target, data_area_of_buf2, total_in_buf2);
319 total_in_buf += total_in_buf2; 319 total_in_buf += total_in_buf2;
320 pSMBt->t2_rsp.DataCount = cpu_to_le16(total_in_buf); 320 pSMBt->t2_rsp.DataCount = cpu_to_le16(total_in_buf);
321 byte_count = le16_to_cpu(BCC_LE(pTargetSMB)); 321 byte_count = get_bcc_le(pTargetSMB);
322 byte_count += total_in_buf2; 322 byte_count += total_in_buf2;
323 BCC_LE(pTargetSMB) = cpu_to_le16(byte_count); 323 put_bcc_le(byte_count, pTargetSMB);
324 324
325 byte_count = pTargetSMB->smb_buf_length; 325 byte_count = pTargetSMB->smb_buf_length;
326 byte_count += total_in_buf2; 326 byte_count += total_in_buf2;
@@ -2937,8 +2937,8 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
2937 TCONX_RSP *pSMBr; 2937 TCONX_RSP *pSMBr;
2938 unsigned char *bcc_ptr; 2938 unsigned char *bcc_ptr;
2939 int rc = 0; 2939 int rc = 0;
2940 int length, bytes_left; 2940 int length;
2941 __u16 count; 2941 __u16 bytes_left, count;
2942 2942
2943 if (ses == NULL) 2943 if (ses == NULL)
2944 return -EIO; 2944 return -EIO;
@@ -3032,7 +3032,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3032 tcon->need_reconnect = false; 3032 tcon->need_reconnect = false;
3033 tcon->tid = smb_buffer_response->Tid; 3033 tcon->tid = smb_buffer_response->Tid;
3034 bcc_ptr = pByteArea(smb_buffer_response); 3034 bcc_ptr = pByteArea(smb_buffer_response);
3035 bytes_left = BCC(smb_buffer_response); 3035 bytes_left = get_bcc(smb_buffer_response);
3036 length = strnlen(bcc_ptr, bytes_left - 2); 3036 length = strnlen(bcc_ptr, bytes_left - 2);
3037 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) 3037 if (smb_buffer->Flags2 & SMBFLG2_UNICODE)
3038 is_unicode = true; 3038 is_unicode = true;
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
index 6783ce6cdc89..8d9189f64477 100644
--- a/fs/cifs/netmisc.c
+++ b/fs/cifs/netmisc.c
@@ -916,14 +916,14 @@ unsigned int
916smbCalcSize(struct smb_hdr *ptr) 916smbCalcSize(struct smb_hdr *ptr)
917{ 917{
918 return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) + 918 return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) +
919 2 /* size of the bcc field */ + BCC(ptr)); 919 2 /* size of the bcc field */ + get_bcc(ptr));
920} 920}
921 921
922unsigned int 922unsigned int
923smbCalcSize_LE(struct smb_hdr *ptr) 923smbCalcSize_LE(struct smb_hdr *ptr)
924{ 924{
925 return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) + 925 return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) +
926 2 /* size of the bcc field */ + le16_to_cpu(BCC_LE(ptr))); 926 2 /* size of the bcc field */ + get_bcc_le(ptr));
927} 927}
928 928
929/* The following are taken from fs/ntfs/util.c */ 929/* The following are taken from fs/ntfs/util.c */
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index 1cffd82c4f13..1adc9625a344 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -277,7 +277,7 @@ static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
277} 277}
278 278
279static void 279static void
280decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses, 280decode_unicode_ssetup(char **pbcc_area, __u16 bleft, struct cifsSesInfo *ses,
281 const struct nls_table *nls_cp) 281 const struct nls_table *nls_cp)
282{ 282{
283 int len; 283 int len;
@@ -323,7 +323,7 @@ decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses,
323 return; 323 return;
324} 324}
325 325
326static int decode_ascii_ssetup(char **pbcc_area, int bleft, 326static int decode_ascii_ssetup(char **pbcc_area, __u16 bleft,
327 struct cifsSesInfo *ses, 327 struct cifsSesInfo *ses,
328 const struct nls_table *nls_cp) 328 const struct nls_table *nls_cp)
329{ 329{
@@ -575,12 +575,11 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
575 char *str_area; 575 char *str_area;
576 SESSION_SETUP_ANDX *pSMB; 576 SESSION_SETUP_ANDX *pSMB;
577 __u32 capabilities; 577 __u32 capabilities;
578 int count; 578 __u16 count;
579 int resp_buf_type; 579 int resp_buf_type;
580 struct kvec iov[3]; 580 struct kvec iov[3];
581 enum securityEnum type; 581 enum securityEnum type;
582 __u16 action; 582 __u16 action, bytes_remaining;
583 int bytes_remaining;
584 struct key *spnego_key = NULL; 583 struct key *spnego_key = NULL;
585 __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */ 584 __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */
586 u16 blob_len; 585 u16 blob_len;
@@ -876,7 +875,7 @@ ssetup_ntlmssp_authenticate:
876 count = iov[1].iov_len + iov[2].iov_len; 875 count = iov[1].iov_len + iov[2].iov_len;
877 smb_buf->smb_buf_length += count; 876 smb_buf->smb_buf_length += count;
878 877
879 BCC_LE(smb_buf) = cpu_to_le16(count); 878 put_bcc_le(count, smb_buf);
880 879
881 rc = SendReceive2(xid, ses, iov, 3 /* num_iovecs */, &resp_buf_type, 880 rc = SendReceive2(xid, ses, iov, 3 /* num_iovecs */, &resp_buf_type,
882 CIFS_LOG_ERROR); 881 CIFS_LOG_ERROR);
@@ -910,7 +909,7 @@ ssetup_ntlmssp_authenticate:
910 cFYI(1, "UID = %d ", ses->Suid); 909 cFYI(1, "UID = %d ", ses->Suid);
911 /* response can have either 3 or 4 word count - Samba sends 3 */ 910 /* response can have either 3 or 4 word count - Samba sends 3 */
912 /* and lanman response is 3 */ 911 /* and lanman response is 3 */
913 bytes_remaining = BCC(smb_buf); 912 bytes_remaining = get_bcc(smb_buf);
914 bcc_ptr = pByteArea(smb_buf); 913 bcc_ptr = pByteArea(smb_buf);
915 914
916 if (smb_buf->WordCount == 4) { 915 if (smb_buf->WordCount == 4) {
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index c8e2808cd5e6..c1ccca1a933f 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -484,7 +484,7 @@ send_nt_cancel(struct TCP_Server_Info *server, struct smb_hdr *in_buf,
484 in_buf->smb_buf_length = sizeof(struct smb_hdr) - 4 + 2; 484 in_buf->smb_buf_length = sizeof(struct smb_hdr) - 4 + 2;
485 in_buf->Command = SMB_COM_NT_CANCEL; 485 in_buf->Command = SMB_COM_NT_CANCEL;
486 in_buf->WordCount = 0; 486 in_buf->WordCount = 0;
487 BCC_LE(in_buf) = 0; 487 put_bcc_le(0, in_buf);
488 488
489 mutex_lock(&server->srv_mutex); 489 mutex_lock(&server->srv_mutex);
490 rc = cifs_sign_smb(in_buf, server, &mid->sequence_number); 490 rc = cifs_sign_smb(in_buf, server, &mid->sequence_number);
@@ -632,8 +632,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
632 if (receive_len >= sizeof(struct smb_hdr) - 4 632 if (receive_len >= sizeof(struct smb_hdr) - 4
633 /* do not count RFC1001 header */ + 633 /* do not count RFC1001 header */ +
634 (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ ) 634 (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ )
635 BCC(midQ->resp_buf) = 635 put_bcc(get_bcc_le(midQ->resp_buf), midQ->resp_buf);
636 le16_to_cpu(BCC_LE(midQ->resp_buf));
637 if ((flags & CIFS_NO_RESP) == 0) 636 if ((flags & CIFS_NO_RESP) == 0)
638 midQ->resp_buf = NULL; /* mark it so buf will 637 midQ->resp_buf = NULL; /* mark it so buf will
639 not be freed by 638 not be freed by
@@ -776,7 +775,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
776 if (receive_len >= sizeof(struct smb_hdr) - 4 775 if (receive_len >= sizeof(struct smb_hdr) - 4
777 /* do not count RFC1001 header */ + 776 /* do not count RFC1001 header */ +
778 (2 * out_buf->WordCount) + 2 /* bcc */ ) 777 (2 * out_buf->WordCount) + 2 /* bcc */ )
779 BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf)); 778 put_bcc(get_bcc_le(midQ->resp_buf), midQ->resp_buf);
780 } else { 779 } else {
781 rc = -EIO; 780 rc = -EIO;
782 cERROR(1, "Bad MID state?"); 781 cERROR(1, "Bad MID state?");
@@ -977,7 +976,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
977 if (receive_len >= sizeof(struct smb_hdr) - 4 976 if (receive_len >= sizeof(struct smb_hdr) - 4
978 /* do not count RFC1001 header */ + 977 /* do not count RFC1001 header */ +
979 (2 * out_buf->WordCount) + 2 /* bcc */ ) 978 (2 * out_buf->WordCount) + 2 /* bcc */ )
980 BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf)); 979 put_bcc(get_bcc_le(out_buf), out_buf);
981 980
982out: 981out:
983 delete_mid(midQ); 982 delete_mid(midQ);