diff options
Diffstat (limited to 'fs/cifs/misc.c')
-rw-r--r-- | fs/cifs/misc.c | 46 |
1 files changed, 26 insertions, 20 deletions
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 432ba15e2c2d..fafd056426e4 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c | |||
@@ -72,10 +72,9 @@ sesInfoAlloc(void) | |||
72 | struct cifsSesInfo *ret_buf; | 72 | struct cifsSesInfo *ret_buf; |
73 | 73 | ||
74 | ret_buf = | 74 | ret_buf = |
75 | (struct cifsSesInfo *) kmalloc(sizeof (struct cifsSesInfo), | 75 | (struct cifsSesInfo *) kzalloc(sizeof (struct cifsSesInfo), |
76 | GFP_KERNEL); | 76 | GFP_KERNEL); |
77 | if (ret_buf) { | 77 | if (ret_buf) { |
78 | memset(ret_buf, 0, sizeof (struct cifsSesInfo)); | ||
79 | write_lock(&GlobalSMBSeslock); | 78 | write_lock(&GlobalSMBSeslock); |
80 | atomic_inc(&sesInfoAllocCount); | 79 | atomic_inc(&sesInfoAllocCount); |
81 | ret_buf->status = CifsNew; | 80 | ret_buf->status = CifsNew; |
@@ -110,10 +109,9 @@ tconInfoAlloc(void) | |||
110 | { | 109 | { |
111 | struct cifsTconInfo *ret_buf; | 110 | struct cifsTconInfo *ret_buf; |
112 | ret_buf = | 111 | ret_buf = |
113 | (struct cifsTconInfo *) kmalloc(sizeof (struct cifsTconInfo), | 112 | (struct cifsTconInfo *) kzalloc(sizeof (struct cifsTconInfo), |
114 | GFP_KERNEL); | 113 | GFP_KERNEL); |
115 | if (ret_buf) { | 114 | if (ret_buf) { |
116 | memset(ret_buf, 0, sizeof (struct cifsTconInfo)); | ||
117 | write_lock(&GlobalSMBSeslock); | 115 | write_lock(&GlobalSMBSeslock); |
118 | atomic_inc(&tconInfoAllocCount); | 116 | atomic_inc(&tconInfoAllocCount); |
119 | list_add(&ret_buf->cifsConnectionList, | 117 | list_add(&ret_buf->cifsConnectionList, |
@@ -423,9 +421,7 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length) | |||
423 | { | 421 | { |
424 | __u32 len = smb->smb_buf_length; | 422 | __u32 len = smb->smb_buf_length; |
425 | __u32 clc_len; /* calculated length */ | 423 | __u32 clc_len; /* calculated length */ |
426 | cFYI(0, | 424 | cFYI(0, ("checkSMB Length: 0x%x, smb_buf_length: 0x%x", length, len)); |
427 | ("Entering checkSMB with Length: %x, smb_buf_length: %x", | ||
428 | length, len)); | ||
429 | if (((unsigned int)length < 2 + sizeof (struct smb_hdr)) || | 425 | if (((unsigned int)length < 2 + sizeof (struct smb_hdr)) || |
430 | (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)) { | 426 | (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)) { |
431 | if ((unsigned int)length < 2 + sizeof (struct smb_hdr)) { | 427 | if ((unsigned int)length < 2 + sizeof (struct smb_hdr)) { |
@@ -433,29 +429,36 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length) | |||
433 | sizeof (struct smb_hdr) - 1) | 429 | sizeof (struct smb_hdr) - 1) |
434 | && (smb->Status.CifsError != 0)) { | 430 | && (smb->Status.CifsError != 0)) { |
435 | smb->WordCount = 0; | 431 | smb->WordCount = 0; |
436 | return 0; /* some error cases do not return wct and bcc */ | 432 | /* some error cases do not return wct and bcc */ |
433 | return 0; | ||
437 | } else { | 434 | } else { |
438 | cERROR(1, ("Length less than smb header size")); | 435 | cERROR(1, ("Length less than smb header size")); |
439 | } | 436 | } |
440 | |||
441 | } | 437 | } |
442 | if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) | 438 | if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) |
443 | cERROR(1, | 439 | cERROR(1, ("smb length greater than MaxBufSize, mid=%d", |
444 | ("smb_buf_length greater than MaxBufSize")); | 440 | smb->Mid)); |
445 | cERROR(1, | ||
446 | ("bad smb detected. Illegal length. mid=%d", | ||
447 | smb->Mid)); | ||
448 | return 1; | 441 | return 1; |
449 | } | 442 | } |
450 | 443 | ||
451 | if (checkSMBhdr(smb, mid)) | 444 | if (checkSMBhdr(smb, mid)) |
452 | return 1; | 445 | return 1; |
453 | clc_len = smbCalcSize_LE(smb); | 446 | clc_len = smbCalcSize_LE(smb); |
454 | if ((4 + len != clc_len) | 447 | |
455 | || (4 + len != (unsigned int)length)) { | 448 | if(4 + len != (unsigned int)length) { |
456 | cERROR(1, ("Calculated size 0x%x vs actual length 0x%x", | 449 | cERROR(1, ("Length read does not match RFC1001 length %d",len)); |
457 | clc_len, 4 + len)); | 450 | return 1; |
458 | cERROR(1, ("bad smb size detected for Mid=%d", smb->Mid)); | 451 | } |
452 | |||
453 | if (4 + len != clc_len) { | ||
454 | /* check if bcc wrapped around for large read responses */ | ||
455 | if((len > 64 * 1024) && (len > clc_len)) { | ||
456 | /* check if lengths match mod 64K */ | ||
457 | if(((4 + len) & 0xFFFF) == (clc_len & 0xFFFF)) | ||
458 | return 0; /* bcc wrapped */ | ||
459 | } | ||
460 | cFYI(1, ("Calculated size %d vs length %d mismatch for mid %d", | ||
461 | clc_len, 4 + len, smb->Mid)); | ||
459 | /* Windows XP can return a few bytes too much, presumably | 462 | /* Windows XP can return a few bytes too much, presumably |
460 | an illegal pad, at the end of byte range lock responses | 463 | an illegal pad, at the end of byte range lock responses |
461 | so we allow for that three byte pad, as long as actual | 464 | so we allow for that three byte pad, as long as actual |
@@ -469,8 +472,11 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length) | |||
469 | wct and bcc to minimum size and drop the t2 parms and data */ | 472 | wct and bcc to minimum size and drop the t2 parms and data */ |
470 | if((4+len > clc_len) && (len <= clc_len + 512)) | 473 | if((4+len > clc_len) && (len <= clc_len + 512)) |
471 | return 0; | 474 | return 0; |
472 | else | 475 | else { |
476 | cERROR(1, ("RFC1001 size %d bigger than SMB for Mid=%d", | ||
477 | len, smb->Mid)); | ||
473 | return 1; | 478 | return 1; |
479 | } | ||
474 | } | 480 | } |
475 | return 0; | 481 | return 0; |
476 | } | 482 | } |