Commit 184ed211 authored by Steve French's avatar Steve French

[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: default avatarSteve French <sfrench@us.ibm.com>
parent 5d2f248a
...@@ -2,7 +2,11 @@ Version 1.41 ...@@ -2,7 +2,11 @@ Version 1.41
------------ ------------
Fix NTLMv2 security (can be enabled in /proc/fs/cifs) so customers can Fix NTLMv2 security (can be enabled in /proc/fs/cifs) so customers can
configure stronger authentication. Fix sfu symlinks so they 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 Version 1.40
------------ ------------
......
...@@ -564,7 +564,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) ...@@ -564,7 +564,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
dump_smb(smb_buffer, length); 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); cifs_dump_mem("Bad SMB: ", smb_buffer, 48);
continue; continue;
} }
...@@ -2278,6 +2278,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, ...@@ -2278,6 +2278,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
smb_buffer->Mid = GetNextMid(ses->server); smb_buffer->Mid = GetNextMid(ses->server);
pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
pSMB->req.AndXCommand = 0xFF; 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.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq); pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
......
...@@ -421,9 +421,7 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length) ...@@ -421,9 +421,7 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length)
{ {
__u32 len = smb->smb_buf_length; __u32 len = smb->smb_buf_length;
__u32 clc_len; /* calculated length */ __u32 clc_len; /* calculated length */
cFYI(0, cFYI(0, ("checkSMB Length: 0x%x, smb_buf_length: 0x%x", length, len));
("Entering checkSMB with Length: %x, smb_buf_length: %x",
length, len));
if (((unsigned int)length < 2 + sizeof (struct smb_hdr)) || if (((unsigned int)length < 2 + sizeof (struct smb_hdr)) ||
(len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)) { (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)) {
if ((unsigned int)length < 2 + sizeof (struct smb_hdr)) { if ((unsigned int)length < 2 + sizeof (struct smb_hdr)) {
...@@ -435,13 +433,9 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length) ...@@ -435,13 +433,9 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length)
} else { } else {
cERROR(1, ("Length less than smb header size")); cERROR(1, ("Length less than smb header size"));
} }
} }
if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)
cERROR(1, cERROR(1, ("smb length greater than MaxBufSize, mid=%d",
("smb_buf_length greater than MaxBufSize"));
cERROR(1,
("bad smb detected. Illegal length. mid=%d",
smb->Mid)); smb->Mid));
return 1; return 1;
} }
...@@ -449,8 +443,19 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length) ...@@ -449,8 +443,19 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length)
if (checkSMBhdr(smb, mid)) if (checkSMBhdr(smb, mid))
return 1; return 1;
clc_len = smbCalcSize_LE(smb); 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", cERROR(1, ("Calculated size 0x%x vs actual length 0x%x",
clc_len, 4 + len)); clc_len, 4 + len));
cERROR(1, ("bad smb size detected for Mid=%d", smb->Mid)); cERROR(1, ("bad smb size detected for Mid=%d", smb->Mid));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment