Loading fs/cifs/cifsproto.h +1 −1 Original line number Original line Diff line number Diff line Loading @@ -55,7 +55,7 @@ extern int SendReceiveBlockingLock(const unsigned int /* xid */ , struct smb_hdr * /* input */ , struct smb_hdr * /* input */ , struct smb_hdr * /* out */ , struct smb_hdr * /* out */ , int * /* bytes returned */); int * /* bytes returned */); extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length); extern int checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length); extern int is_valid_oplock_break(struct smb_hdr *smb, struct TCP_Server_Info *); extern int is_valid_oplock_break(struct smb_hdr *smb, struct TCP_Server_Info *); extern int is_size_safe_to_change(struct cifsInodeInfo *); extern int is_size_safe_to_change(struct cifsInodeInfo *); extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *); extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *); Loading fs/cifs/misc.c +29 −13 Original line number Original line Diff line number Diff line Loading @@ -418,25 +418,41 @@ checkSMBhdr(struct smb_hdr *smb, __u16 mid) } } int int checkSMB(struct smb_hdr *smb, __u16 mid, int length) checkSMB(struct smb_hdr *smb, __u16 mid, unsigned 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, ("checkSMB Length: 0x%x, smb_buf_length: 0x%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 (length < 2 + sizeof (struct smb_hdr)) { if ((unsigned int)length < 2 + sizeof (struct smb_hdr)) { if ((length >= sizeof (struct smb_hdr) - 1) if (((unsigned int)length >= sizeof (struct smb_hdr) - 1) && (smb->Status.CifsError != 0)) { && (smb->Status.CifsError != 0)) { smb->WordCount = 0; smb->WordCount = 0; /* some error cases do not return wct and bcc */ /* some error cases do not return wct and bcc */ return 0; return 0; } else if ((length == sizeof(struct smb_hdr) + 1) && (smb->WordCount == 0)) { char * tmp = (char *)smb; /* Need to work around a bug in two servers here */ /* First, check if the part of bcc they sent was zero */ if (tmp[sizeof(struct smb_hdr)] == 0) { /* some servers return only half of bcc * on simple responses (wct, bcc both zero) * in particular have seen this on * ulogoffX and FindClose. This leaves * one byte of bcc potentially unitialized */ /* zero rest of bcc */ tmp[sizeof(struct smb_hdr)+1] = 0; return 0; } cERROR(1,("rcvd invalid byte count (bcc)")); } else { } else { cERROR(1, ("Length less than smb header size")); cERROR(1, ("Length less than smb header size")); } } return 1; } } if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { cERROR(1, ("smb length greater than MaxBufSize, mid=%d", cERROR(1, ("smb length greater than MaxBufSize, mid=%d", smb->Mid)); smb->Mid)); return 1; return 1; Loading @@ -446,7 +462,7 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length) return 1; return 1; clc_len = smbCalcSize_LE(smb); clc_len = smbCalcSize_LE(smb); if(4 + len != (unsigned int)length) { if(4 + len != length) { cERROR(1, ("Length read does not match RFC1001 length %d",len)); cERROR(1, ("Length read does not match RFC1001 length %d",len)); return 1; return 1; } } Loading Loading
fs/cifs/cifsproto.h +1 −1 Original line number Original line Diff line number Diff line Loading @@ -55,7 +55,7 @@ extern int SendReceiveBlockingLock(const unsigned int /* xid */ , struct smb_hdr * /* input */ , struct smb_hdr * /* input */ , struct smb_hdr * /* out */ , struct smb_hdr * /* out */ , int * /* bytes returned */); int * /* bytes returned */); extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length); extern int checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length); extern int is_valid_oplock_break(struct smb_hdr *smb, struct TCP_Server_Info *); extern int is_valid_oplock_break(struct smb_hdr *smb, struct TCP_Server_Info *); extern int is_size_safe_to_change(struct cifsInodeInfo *); extern int is_size_safe_to_change(struct cifsInodeInfo *); extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *); extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *); Loading
fs/cifs/misc.c +29 −13 Original line number Original line Diff line number Diff line Loading @@ -418,25 +418,41 @@ checkSMBhdr(struct smb_hdr *smb, __u16 mid) } } int int checkSMB(struct smb_hdr *smb, __u16 mid, int length) checkSMB(struct smb_hdr *smb, __u16 mid, unsigned 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, ("checkSMB Length: 0x%x, smb_buf_length: 0x%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 (length < 2 + sizeof (struct smb_hdr)) { if ((unsigned int)length < 2 + sizeof (struct smb_hdr)) { if ((length >= sizeof (struct smb_hdr) - 1) if (((unsigned int)length >= sizeof (struct smb_hdr) - 1) && (smb->Status.CifsError != 0)) { && (smb->Status.CifsError != 0)) { smb->WordCount = 0; smb->WordCount = 0; /* some error cases do not return wct and bcc */ /* some error cases do not return wct and bcc */ return 0; return 0; } else if ((length == sizeof(struct smb_hdr) + 1) && (smb->WordCount == 0)) { char * tmp = (char *)smb; /* Need to work around a bug in two servers here */ /* First, check if the part of bcc they sent was zero */ if (tmp[sizeof(struct smb_hdr)] == 0) { /* some servers return only half of bcc * on simple responses (wct, bcc both zero) * in particular have seen this on * ulogoffX and FindClose. This leaves * one byte of bcc potentially unitialized */ /* zero rest of bcc */ tmp[sizeof(struct smb_hdr)+1] = 0; return 0; } cERROR(1,("rcvd invalid byte count (bcc)")); } else { } else { cERROR(1, ("Length less than smb header size")); cERROR(1, ("Length less than smb header size")); } } return 1; } } if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { cERROR(1, ("smb length greater than MaxBufSize, mid=%d", cERROR(1, ("smb length greater than MaxBufSize, mid=%d", smb->Mid)); smb->Mid)); return 1; return 1; Loading @@ -446,7 +462,7 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length) return 1; return 1; clc_len = smbCalcSize_LE(smb); clc_len = smbCalcSize_LE(smb); if(4 + len != (unsigned int)length) { if(4 + len != length) { cERROR(1, ("Length read does not match RFC1001 length %d",len)); cERROR(1, ("Length read does not match RFC1001 length %d",len)); return 1; return 1; } } Loading