aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2006-02-24 01:15:11 -0500
committerSteve French <sfrench@us.ibm.com>2006-02-24 01:15:11 -0500
commit184ed2110ae6bfdb8dc91085149f04f2f4d2169e (patch)
treee36ae13694fb922cc2244ef6fffad7f93a6c90e0
parent5d2f248a5f3acac4b763439327c92091be7abb1c (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>
-rw-r--r--fs/cifs/CHANGES6
-rw-r--r--fs/cifs/connect.c4
-rw-r--r--fs/cifs/misc.c27
3 files changed, 24 insertions, 13 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index a9cf779cf35e..cf846c73bc69 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -2,7 +2,11 @@ Version 1.41
2------------ 2------------
3Fix NTLMv2 security (can be enabled in /proc/fs/cifs) so customers can 3Fix NTLMv2 security (can be enabled in /proc/fs/cifs) so customers can
4configure stronger authentication. Fix sfu symlinks so they can 4configure stronger authentication. Fix sfu symlinks so they can
5be followed (not just recognized). 5be followed (not just recognized). Fix wraparound of bcc on
6read responses when buffer size over 64K and also fix wrap of
7max smb buffer size when CIFSMaxBufSize over 64K. Fix oops in
8cifs_user_read and cifs_readpages (when EAGAIN on send of smb
9on socket is returned over and over)
6 10
7Version 1.40 11Version 1.40
8------------ 12------------
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 16535b510a96..cf4bcf3a45e6 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -564,7 +564,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
564 564
565 565
566 dump_smb(smb_buffer, length); 566 dump_smb(smb_buffer, length);
567 if (checkSMB (smb_buffer, smb_buffer->Mid, total_read+4)) { 567 if (checkSMB(smb_buffer, smb_buffer->Mid, total_read+4)) {
568 cifs_dump_mem("Bad SMB: ", smb_buffer, 48); 568 cifs_dump_mem("Bad SMB: ", smb_buffer, 48);
569 continue; 569 continue;
570 } 570 }
@@ -2278,6 +2278,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2278 smb_buffer->Mid = GetNextMid(ses->server); 2278 smb_buffer->Mid = GetNextMid(ses->server);
2279 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; 2279 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2280 pSMB->req.AndXCommand = 0xFF; 2280 pSMB->req.AndXCommand = 0xFF;
2281 if(ses->server->maxBuf > 64*1024)
2282 ses->server->maxBuf = (64*1023);
2281 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); 2283 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2282 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq); 2284 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2283 2285
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 0f3ebad09d3e..988b8cec8568 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));