summaryrefslogtreecommitdiff
path: root/fs/cifs/misc.c
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2005-10-10 22:48:26 +0400
committerSteve French <sfrench@us.ibm.com>2005-10-10 22:48:26 +0400
commit190fdeb84499a2dc046adae2eebfdda49e315e96 (patch)
treea8a84acaeabf0e92d965faf415702a3c37646fe7 /fs/cifs/misc.c
parent0ae0efada36219024e4e3008f16c993d5d091280 (diff)
downloadlinux-190fdeb84499a2dc046adae2eebfdda49e315e96.tar.xz
[CIFS] Fix byte range locking to Windows when Windows server returns
illegal RFC1001 length (which had caused the lock to block forever until killed).
Diffstat (limited to 'fs/cifs/misc.c')
-rw-r--r--fs/cifs/misc.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 8a0edd695f84..eba1de917f2a 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -420,6 +420,7 @@ int
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));
@@ -440,20 +441,27 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length)
cERROR(1,
("smb_buf_length greater than MaxBufSize"));
cERROR(1,
- ("bad smb detected. Illegal length. The mid=%d",
+ ("bad smb detected. Illegal length. mid=%d",
smb->Mid));
return 1;
}
if (checkSMBhdr(smb, mid))
return 1;
-
- if ((4 + len != smbCalcSize_LE(smb))
+ clc_len = smbCalcSize_LE(smb);
+ if ((4 + len != clc_len)
|| (4 + len != (unsigned int)length)) {
- cERROR(1, ("smbCalcSize %x ", smbCalcSize_LE(smb)));
- cERROR(1,
- ("bad smb size detected. The Mid=%d", smb->Mid));
- return 1;
+ 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));
+ /* Windows XP can return a few bytes too much, presumably
+ an illegal pad, at the end of byte range lock responses
+ so we allow for up to eight byte pad, as long as actual
+ received length is as long or longer than calculated length */
+ if((4+len > clc_len) && (len <= clc_len + 3))
+ return 0;
+ else
+ return 1;
}
return 0;
}