aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/misc.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-04-01 00:27:53 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-04-01 00:27:53 -0500
commit547a77ae62091449e23b64a75b9c69e373613608 (patch)
tree63e1f03203570a9a7e9266ac10befc1716b256bd /fs/cifs/misc.c
parent4b75679f60d0ce780609cbff249769b669f4fb69 (diff)
parent06bcfedd05448e63cae8924074bfacdf82bb17d4 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/sfrench/cifs-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/sfrench/cifs-2.6: [CIFS] Fix typo in earlier cifs_unlink change and protect one [CIFS] Incorrect signature sent on SMB Read [CIFS] Fix unlink oops when indirectly called in rename error path [CIFS] Fix two remaining coverity scan tool warnings. [CIFS] Set correct lock type on new posix unlock call [CIFS] Upate cifs change log [CIFS] Fix slow oplock break response when mounts to different [CIFS] Workaround various server bugs found in testing at connectathon [CIFS] Allow fallback for setting file size to Procom SMB server when [CIFS] Make POSIX CIFS Extensions SetFSInfo match exactly what we want [CIFS] Move noisy debug message (triggerred by some older servers) from [CIFS] Use correct pid on new cifs posix byte range lock call [CIFS] Add posix (advisory) byte range locking support to cifs client [CIFS] CIFS readdir perf optimizations part 1 [CIFS] Free small buffers earlier so we exceed the cifs [CIFS] Fix large (ie over 64K for MaxCIFSBufSize) buffer case for wrapping [CIFS] Convert remaining places in fs/cifs from [CIFS] SessionSetup cleanup part 2 [CIFS] fix compile error (typo) and warning in cifssmb.c [CIFS] Cleanup NTLMSSP session setup handling
Diffstat (limited to 'fs/cifs/misc.c')
-rw-r--r--fs/cifs/misc.c46
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}