]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
[CIFS] Fix large (ie over 64K for MaxCIFSBufSize) buffer case for wrapping
authorSteve French <sfrench@us.ibm.com>
Fri, 24 Feb 2006 06:15:11 +0000 (06:15 +0000)
committerSteve French <sfrench@us.ibm.com>
Fri, 24 Feb 2006 06:15:11 +0000 (06:15 +0000)
bcc on read response and for wrapping sessionsetup maxbufsize field

Signed-off-by: Steve French <sfrench@us.ibm.com>
fs/cifs/CHANGES
fs/cifs/connect.c
fs/cifs/misc.c

index a9cf779cf35ea862e12fe3f1134e788657803e0e..cf846c73bc69751678d3561c2cf9b3084cc615ff 100644 (file)
@@ -2,7 +2,11 @@ Version 1.41
 ------------
 Fix NTLMv2 security (can be enabled in /proc/fs/cifs) so customers can
 configure stronger authentication.  Fix sfu symlinks so they can
-be followed (not just recognized).
+be followed (not just recognized).  Fix wraparound of bcc on
+read responses when buffer size over 64K and also fix wrap of
+max smb buffer size when CIFSMaxBufSize over 64K.  Fix oops in
+cifs_user_read and cifs_readpages (when EAGAIN on send of smb
+on socket is returned over and over)
 
 Version 1.40
 ------------
index 16535b510a968f66e9426180da1b76fcbddc9b07..cf4bcf3a45e68e3d781576efe7fcfdf6822a5ccf 100644 (file)
@@ -564,7 +564,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
        
 
                dump_smb(smb_buffer, length);
-               if (checkSMB (smb_buffer, smb_buffer->Mid, total_read+4)) {
+               if (checkSMB(smb_buffer, smb_buffer->Mid, total_read+4)) {
                        cifs_dump_mem("Bad SMB: ", smb_buffer, 48);
                        continue;
                }
@@ -2278,6 +2278,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
        smb_buffer->Mid = GetNextMid(ses->server);
        pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
        pSMB->req.AndXCommand = 0xFF;
+       if(ses->server->maxBuf > 64*1024)
+               ses->server->maxBuf = (64*1023);
        pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
        pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
 
index 0f3ebad09d3efa3c5679a64bb59ede2e8c6ede70..988b8cec856850bc7518b47883c24ea1d455aa4f 100644 (file)
@@ -421,9 +421,7 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length)
 {
        __u32 len = smb->smb_buf_length;
        __u32 clc_len;  /* calculated length */
-       cFYI(0,
-            ("Entering checkSMB with Length: %x, smb_buf_length: %x",
-             length, len));
+       cFYI(0, ("checkSMB Length: 0x%x, smb_buf_length: 0x%x", length, len));
        if (((unsigned int)length < 2 + sizeof (struct smb_hdr)) ||
            (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)) {
                if ((unsigned int)length < 2 + sizeof (struct smb_hdr)) {
@@ -435,22 +433,29 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length)
                        } else {
                                cERROR(1, ("Length less than smb header size"));
                        }
-
                }
                if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)
-                       cERROR(1,
-                              ("smb_buf_length greater than MaxBufSize"));
-               cERROR(1,
-                      ("bad smb detected. Illegal length. mid=%d",
-                       smb->Mid));
+                       cERROR(1, ("smb length greater than MaxBufSize, mid=%d",
+                                  smb->Mid));
                return 1;
        }
 
        if (checkSMBhdr(smb, mid))
                return 1;
        clc_len = smbCalcSize_LE(smb);
-       if ((4 + len != clc_len)
-           || (4 + len != (unsigned int)length)) {
+
+       if(4 + len != (unsigned int)length) {
+               cERROR(1, ("Length read does not match RFC1001 length %d",len));
+               return 1;
+       }
+
+       if (4 + len != clc_len) {
+               /* check if bcc wrapped around for large read responses */
+               if((len > 64 * 1024) && (len > clc_len)) {
+                       /* check if lengths match mod 64K */
+                       if(((4 + len) & 0xFFFF) == (clc_len & 0xFFFF))
+                               return 0; /* bcc wrapped */                     
+               }
                cERROR(1, ("Calculated size 0x%x vs actual length 0x%x",
                                clc_len, 4 + len));
                cERROR(1, ("bad smb size detected for Mid=%d", smb->Mid));