summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Viro <viro@www.linux.org.uk>2004-09-21 02:52:59 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-09-21 02:52:59 -0700
commit77615fa9ee9782267902dd760ecaf9ba8c0c2b41 (patch)
tree0766c3bfa2d800937f50b0e887536ae753fc7d5c
parent0c5ba019854381bc30401fa435302933663655fa (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.c2
-rw-r--r--fs/cifs/cifspdu.h20
-rw-r--r--fs/cifs/cifssmb.c8
-rw-r--r--fs/cifs/connect.c13
-rw-r--r--fs/cifs/misc.c4
-rw-r--r--fs/cifs/ntlmssp.h8
-rw-r--r--fs/cifs/transport.c29
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? */