diff options
| author | Alexander Viro <viro@www.linux.org.uk> | 2004-09-21 02:52:59 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-09-21 02:52:59 -0700 |
| commit | 77615fa9ee9782267902dd760ecaf9ba8c0c2b41 (patch) | |
| tree | 0766c3bfa2d800937f50b0e887536ae753fc7d5c | |
| parent | 0c5ba019854381bc30401fa435302933663655fa (diff) | |
[PATCH] cifs: assorted endianness bugfixes
a) Flags2 left little-endian. SMBFLG2_... definitions switched to
cpu_to_le16(...), which kills the need of conversions in ->Flags2.
b) FILE_SYSTEM_UNIX_INFO (never used anywhere) is left little-endian;
when users appear, they can convert themselves.
c) bugfix: in CIFSSessSetup() we used SecurityBlobLength of response
without conversion. That would screw bigendian clients with servers that
give wcnt=4.
d) bugfix: in CIFSNTLMSSPNegotiateSessSetup() we use
SecurityBlob2->NegotiateFlags without conversion. Again, problem on
big-endian.
e) bugfix: SecurityBlob->MessageType is *not* host-endian.
f) bugfix: ->sendmsg() expects its last argument to be equal to sum
of iovec lengths, so the value passed to kernel_sendmsg()/sock_sendmsg()
would better be correct...
Signed-off-by: Al Viro <viro@parcelfarce.linux.org.uk>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
| -rw-r--r-- | fs/cifs/cifsencrypt.c | 2 | ||||
| -rw-r--r-- | fs/cifs/cifspdu.h | 20 | ||||
| -rw-r--r-- | fs/cifs/cifssmb.c | 8 | ||||
| -rw-r--r-- | fs/cifs/connect.c | 13 | ||||
| -rw-r--r-- | fs/cifs/misc.c | 4 | ||||
| -rw-r--r-- | fs/cifs/ntlmssp.h | 8 | ||||
| -rw-r--r-- | fs/cifs/transport.c | 29 |
7 files changed, 36 insertions, 48 deletions
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index 123b64eafc33..17823106208d 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c @@ -61,7 +61,7 @@ int cifs_sign_smb(struct smb_hdr * cifs_pdu, struct cifsSesInfo * ses, if((cifs_pdu == NULL) || (ses == NULL)) return -EINVAL; - if((le32_to_cpu(cifs_pdu->Flags2) & SMBFLG2_SECURITY_SIGNATURE) == 0) + if((cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) == 0) return rc; spin_lock(&GlobalMid_Lock); diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index 63f3fbfa754b..20430a2d2016 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h @@ -137,15 +137,15 @@ /* * SMB flag2 definitions */ -#define SMBFLG2_KNOWS_LONG_NAMES 0x0001 /* can send long (non-8.3) path names in response */ -#define SMBFLG2_KNOWS_EAS 0x0002 -#define SMBFLG2_SECURITY_SIGNATURE 0x0004 -#define SMBFLG2_IS_LONG_NAME 0x0040 -#define SMBFLG2_EXT_SEC 0x0800 -#define SMBFLG2_DFS 0x1000 -#define SMBFLG2_PAGING_IO 0x2000 -#define SMBFLG2_ERR_STATUS 0x4000 -#define SMBFLG2_UNICODE 0x8000 +#define SMBFLG2_KNOWS_LONG_NAMES cpu_to_le16(1) /* can send long (non-8.3) path names in response */ +#define SMBFLG2_KNOWS_EAS cpu_to_le16(2) +#define SMBFLG2_SECURITY_SIGNATURE cpu_to_le16(4) +#define SMBFLG2_IS_LONG_NAME cpu_to_le16(0x40) +#define SMBFLG2_EXT_SEC cpu_to_le16(0x80) +#define SMBFLG2_DFS cpu_to_le16(0x1000) +#define SMBFLG2_PAGING_IO cpu_to_le16(0x2000) +#define SMBFLG2_ERR_STATUS cpu_to_le16(0x4000) +#define SMBFLG2_UNICODE cpu_to_le16(0x8000) /* * These are the file access permission bits defined in CIFS for the @@ -308,7 +308,7 @@ struct smb_hdr { __le32 CifsError; } Status; __u8 Flags; - __u16 Flags2; /* note: le */ + __le16 Flags2; /* note: le */ __le16 PidHigh; union { struct { diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index de302b51a462..8e17185383f0 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -811,7 +811,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, pSMB->Timeout = 0; } else if (waitFlag == TRUE) { timeout = 3; /* blocking operation, no timeout */ - pSMB->Timeout = -1; /* blocking - do not time out */ + pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */ } else { pSMB->Timeout = 0; } @@ -2485,12 +2485,6 @@ QFSUnixRetry: (FILE_SYSTEM_UNIX_INFO *) (((char *) &pSMBr->hdr.Protocol) + data_offset); - response_data->MajorVersionNumber = - le16_to_cpu(response_data->MajorVersionNumber); - response_data->MinorVersionNumber = - le16_to_cpu(response_data->MinorVersionNumber); - response_data->Capability = - le64_to_cpu(response_data->Capability); memcpy(&tcon->fsUnixInfo, response_data, sizeof (FILE_SYSTEM_UNIX_INFO)); } diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 0e407ae531e9..1f4919ee2897 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -1634,6 +1634,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, } else if ((smb_buffer_response->WordCount == 3) || (smb_buffer_response->WordCount == 4)) { __u16 action = le16_to_cpu(pSMBr->resp.Action); + __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength); if (action & GUEST_LOGIN) cFYI(1, (" Guest login")); /* do we want to mark SesInfo struct ? */ ses->Suid = smb_buffer_response->Uid; /* UID left in wire format (le) */ @@ -1642,11 +1643,9 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, bcc_ptr = pByteArea(smb_buffer_response); if ((pSMBr->resp.hdr.WordCount == 3) || ((pSMBr->resp.hdr.WordCount == 4) - && (pSMBr->resp.SecurityBlobLength < - pSMBr->resp.ByteCount))) { + && (blob_len < pSMBr->resp.ByteCount))) { if (pSMBr->resp.hdr.WordCount == 4) - bcc_ptr += - pSMBr->resp.SecurityBlobLength; + bcc_ptr += blob_len; if (smb_buffer->Flags2 & SMBFLG2_UNICODE) { if ((long) (bcc_ptr) % 2) { @@ -2201,16 +2200,16 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, memcpy(ses->server->cryptKey, SecurityBlob2->Challenge, CIFS_CRYPTO_KEY_SIZE); - if(SecurityBlob2->NegotiateFlags & NTLMSSP_NEGOTIATE_NTLMV2) + if(SecurityBlob2->NegotiateFlags & cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2)) *pNTLMv2_flag = TRUE; if((SecurityBlob2->NegotiateFlags & - NTLMSSP_NEGOTIATE_ALWAYS_SIGN) + cpu_to_le32(NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) || (sign_CIFS_PDUs > 1)) ses->server->secMode |= SECMODE_SIGN_REQUIRED; if ((SecurityBlob2->NegotiateFlags & - NTLMSSP_NEGOTIATE_SIGN) && (sign_CIFS_PDUs)) + cpu_to_le32(NTLMSSP_NEGOTIATE_SIGN)) && (sign_CIFS_PDUs)) ses->server->secMode |= SECMODE_SIGN_ENABLED; diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 92a6ef7831d5..fedb455af33f 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -289,7 +289,7 @@ checkSMBhdr(struct smb_hdr *smb, __u16 mid) { /* Make sure that this really is an SMB, that it is a response, and that the message ids match */ - if ((*(unsigned int *) smb->Protocol == cpu_to_le32(0x424d53ff)) && + if ((*(__le32 *) smb->Protocol == cpu_to_le32(0x424d53ff)) && (mid == smb->Mid)) { if(smb->Flags & SMBFLG_RESPONSE) return 0; @@ -301,7 +301,7 @@ checkSMBhdr(struct smb_hdr *smb, __u16 mid) cERROR(1, ("Rcvd Request not response ")); } } else { /* bad signature or mid */ - if (*(unsigned int *) smb->Protocol != cpu_to_le32(0x424d53ff)) + if (*(__le32 *) smb->Protocol != cpu_to_le32(0x424d53ff)) cERROR(1, ("Bad protocol string signature header %x ", *(unsigned int *) smb->Protocol)); diff --git a/fs/cifs/ntlmssp.h b/fs/cifs/ntlmssp.h index 9d88cc9ddd05..5b15cee2ca2a 100644 --- a/fs/cifs/ntlmssp.h +++ b/fs/cifs/ntlmssp.h @@ -23,10 +23,10 @@ #define NTLMSSP_SIGNATURE "NTLMSSP" /* Message Types */ -#define NtLmNegotiate 1 -#define NtLmChallenge 2 -#define NtLmAuthenticate 3 -#define UnknownMessage 8 +#define NtLmNegotiate cpu_to_le32(1) +#define NtLmChallenge cpu_to_le32(2) +#define NtLmAuthenticate cpu_to_le32(3) +#define UnknownMessage cpu_to_le32(8) /* Negotiate Flags */ #define NTLMSSP_NEGOTIATE_UNICODE 0x01 // Text strings are in unicode diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 9e1842b5ff34..a19f4a9c9841 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -123,11 +123,12 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer, int i = 0; struct msghdr smb_msg; struct kvec iov; + unsigned len = smb_buf_length + 4; if(ssocket == NULL) return -ENOTSOCK; /* BB eventually add reconnect code here */ iov.iov_base = smb_buffer; - iov.iov_len = smb_buf_length + 4; + iov.iov_len = len; smb_msg.msg_name = sin; smb_msg.msg_namelen = sizeof (struct sockaddr); @@ -142,10 +143,10 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer, smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length); cFYI(1, ("Sending smb of length %d ", smb_buf_length)); - dump_smb(smb_buffer, smb_buf_length + 4); + dump_smb(smb_buffer, len); - while(iov.iov_len > 0) { - rc = kernel_sendmsg(ssocket, &smb_msg, &iov, 1, smb_buf_length + 4); + while (len > 0) { + rc = kernel_sendmsg(ssocket, &smb_msg, &iov, 1, len); if ((rc == -ENOSPC) || (rc == -EAGAIN)) { i++; if(i > 60) { @@ -163,6 +164,7 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer, break; iov.iov_base += rc; iov.iov_len -= rc; + len -= rc; } if (rc < 0) { @@ -272,9 +274,6 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, return -EIO; } - if (in_buf->smb_buf_length > 12) - in_buf->Flags2 = cpu_to_le16(in_buf->Flags2); - rc = cifs_sign_smb(in_buf, ses, &midQ->sequence_number); midQ->midState = MID_REQUEST_SUBMITTED; @@ -329,7 +328,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, spin_lock(&GlobalMid_Lock); if (midQ->resp_buf) { spin_unlock(&GlobalMid_Lock); - receive_len = be32_to_cpu(midQ->resp_buf->smb_buf_length); + receive_len = be32_to_cpu(*(__be32 *)midQ->resp_buf); } else { cERROR(1,("No response buffer")); if(midQ->midState == MID_REQUEST_SUBMITTED) { @@ -368,24 +367,20 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, if (midQ->resp_buf && out_buf && (midQ->midState == MID_RESPONSE_RECEIVED)) { - memcpy(out_buf, midQ->resp_buf, - receive_len + - 4 /* include 4 byte RFC1001 header */ ); + out_buf->smb_buf_length = receive_len; + memcpy((char *)out_buf + 4, + (char *)midQ->resp_buf + 4, + receive_len); dump_smb(out_buf, 92); /* convert the length into a more usable form */ - out_buf->smb_buf_length = - be32_to_cpu(out_buf->smb_buf_length); - if((out_buf->smb_buf_length > 24) && + if((receive_len > 24) && (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))) { rc = cifs_verify_signature(out_buf, ses->mac_signing_key,midQ->sequence_number); /* BB fix BB */ if(rc) cFYI(1,("Unexpected signature received from server")); } - if (out_buf->smb_buf_length > 12) - out_buf->Flags2 = le16_to_cpu(out_buf->Flags2); - *pbytes_returned = out_buf->smb_buf_length; /* BB special case reconnect tid and reconnect uid here? */ |
