diff options
author | Steve French <sfrench@us.ibm.com> | 2006-02-24 01:15:11 -0500 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2006-02-24 01:15:11 -0500 |
commit | 184ed2110ae6bfdb8dc91085149f04f2f4d2169e (patch) | |
tree | e36ae13694fb922cc2244ef6fffad7f93a6c90e0 /fs/cifs/misc.c | |
parent | 5d2f248a5f3acac4b763439327c92091be7abb1c (diff) |
[CIFS] Fix large (ie over 64K for MaxCIFSBufSize) buffer case for wrapping
bcc on read response and for wrapping sessionsetup maxbufsize field
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/misc.c')
-rw-r--r-- | fs/cifs/misc.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 0f3ebad09d3..988b8cec856 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c | |||
@@ -421,9 +421,7 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length) | |||
421 | { | 421 | { |
422 | __u32 len = smb->smb_buf_length; | 422 | __u32 len = smb->smb_buf_length; |
423 | __u32 clc_len; /* calculated length */ | 423 | __u32 clc_len; /* calculated length */ |
424 | cFYI(0, | 424 | cFYI(0, ("checkSMB Length: 0x%x, smb_buf_length: 0x%x", length, len)); |
425 | ("Entering checkSMB with Length: %x, smb_buf_length: %x", | ||
426 | length, len)); | ||
427 | if (((unsigned int)length < 2 + sizeof (struct smb_hdr)) || | 425 | if (((unsigned int)length < 2 + sizeof (struct smb_hdr)) || |
428 | (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)) { | 426 | (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)) { |
429 | if ((unsigned int)length < 2 + sizeof (struct smb_hdr)) { | 427 | if ((unsigned int)length < 2 + sizeof (struct smb_hdr)) { |
@@ -435,22 +433,29 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length) | |||
435 | } else { | 433 | } else { |
436 | cERROR(1, ("Length less than smb header size")); | 434 | cERROR(1, ("Length less than smb header size")); |
437 | } | 435 | } |
438 | |||
439 | } | 436 | } |
440 | if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) | 437 | if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) |
441 | cERROR(1, | 438 | cERROR(1, ("smb length greater than MaxBufSize, mid=%d", |
442 | ("smb_buf_length greater than MaxBufSize")); | 439 | smb->Mid)); |
443 | cERROR(1, | ||
444 | ("bad smb detected. Illegal length. mid=%d", | ||
445 | smb->Mid)); | ||
446 | return 1; | 440 | return 1; |
447 | } | 441 | } |
448 | 442 | ||
449 | if (checkSMBhdr(smb, mid)) | 443 | if (checkSMBhdr(smb, mid)) |
450 | return 1; | 444 | return 1; |
451 | clc_len = smbCalcSize_LE(smb); | 445 | clc_len = smbCalcSize_LE(smb); |
452 | if ((4 + len != clc_len) | 446 | |
453 | || (4 + len != (unsigned int)length)) { | 447 | if(4 + len != (unsigned int)length) { |
448 | cERROR(1, ("Length read does not match RFC1001 length %d",len)); | ||
449 | return 1; | ||
450 | } | ||
451 | |||
452 | if (4 + len != clc_len) { | ||
453 | /* check if bcc wrapped around for large read responses */ | ||
454 | if((len > 64 * 1024) && (len > clc_len)) { | ||
455 | /* check if lengths match mod 64K */ | ||
456 | if(((4 + len) & 0xFFFF) == (clc_len & 0xFFFF)) | ||
457 | return 0; /* bcc wrapped */ | ||
458 | } | ||
454 | cERROR(1, ("Calculated size 0x%x vs actual length 0x%x", | 459 | cERROR(1, ("Calculated size 0x%x vs actual length 0x%x", |
455 | clc_len, 4 + len)); | 460 | clc_len, 4 + len)); |
456 | cERROR(1, ("bad smb size detected for Mid=%d", smb->Mid)); | 461 | cERROR(1, ("bad smb size detected for Mid=%d", smb->Mid)); |