diff options
author | Steve French <sfrench@us.ibm.com> | 2005-10-10 14:48:26 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2005-10-10 14:48:26 -0400 |
commit | 190fdeb84499a2dc046adae2eebfdda49e315e96 (patch) | |
tree | a8a84acaeabf0e92d965faf415702a3c37646fe7 /fs/cifs/misc.c | |
parent | 0ae0efada36219024e4e3008f16c993d5d091280 (diff) |
[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.c | 22 |
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 | |||
420 | checkSMB(struct smb_hdr *smb, __u16 mid, int length) | 420 | 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 | cFYI(0, | 424 | cFYI(0, |
424 | ("Entering checkSMB with Length: %x, smb_buf_length: %x ", | 425 | ("Entering checkSMB with Length: %x, smb_buf_length: %x ", |
425 | length, len)); | 426 | length, len)); |
@@ -440,20 +441,27 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length) | |||
440 | cERROR(1, | 441 | cERROR(1, |
441 | ("smb_buf_length greater than MaxBufSize")); | 442 | ("smb_buf_length greater than MaxBufSize")); |
442 | cERROR(1, | 443 | cERROR(1, |
443 | ("bad smb detected. Illegal length. The mid=%d", | 444 | ("bad smb detected. Illegal length. mid=%d", |
444 | smb->Mid)); | 445 | smb->Mid)); |
445 | return 1; | 446 | return 1; |
446 | } | 447 | } |
447 | 448 | ||
448 | if (checkSMBhdr(smb, mid)) | 449 | if (checkSMBhdr(smb, mid)) |
449 | return 1; | 450 | return 1; |
450 | 451 | clc_len = smbCalcSize_LE(smb); | |
451 | if ((4 + len != smbCalcSize_LE(smb)) | 452 | if ((4 + len != clc_len) |
452 | || (4 + len != (unsigned int)length)) { | 453 | || (4 + len != (unsigned int)length)) { |
453 | cERROR(1, ("smbCalcSize %x ", smbCalcSize_LE(smb))); | 454 | cERROR(1, ("Calculated size 0x%x vs actual length 0x%x", |
454 | cERROR(1, | 455 | clc_len, 4 + len)); |
455 | ("bad smb size detected. The Mid=%d", smb->Mid)); | 456 | cERROR(1, ("bad smb size detected for Mid=%d", smb->Mid)); |
456 | return 1; | 457 | /* Windows XP can return a few bytes too much, presumably |
458 | an illegal pad, at the end of byte range lock responses | ||
459 | so we allow for up to eight byte pad, as long as actual | ||
460 | received length is as long or longer than calculated length */ | ||
461 | if((4+len > clc_len) && (len <= clc_len + 3)) | ||
462 | return 0; | ||
463 | else | ||
464 | return 1; | ||
457 | } | 465 | } |
458 | return 0; | 466 | return 0; |
459 | } | 467 | } |