Commit be8e3b00 authored by Steve French's avatar Steve French

consistently use smb_buf_length as be32 for cifs (try 3)

       There is one big endian field in the cifs protocol, the RFC1001
       length, which cifs code (unlike in the smb2 code) had been handling as
       u32 until the last possible moment, when it was converted to be32 (its
       native form) before sending on the wire.   To remove the last sparse
       endian warning, and to make this consistent with the smb2
       implementation  (which always treats the fields in their
       native size and endianness), convert all uses of smb_buf_length to
       be32.

       This version incorporates Christoph's comment about
       using be32_add_cpu, and fixes a typo in the second
       version of the patch.
Signed-off-by: default avatarSteve French <sfrench@us.ibm.com>
Signed-off-by: default avatarPavel Shilovsky <piastry@etersoft.ru>
Signed-off-by: default avatarSteve French <sfrench@us.ibm.com>
parent 9409ae58
......@@ -60,7 +60,7 @@ static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu,
server->session_key.response, server->session_key.len);
crypto_shash_update(&server->secmech.sdescmd5->shash,
cifs_pdu->Protocol, cifs_pdu->smb_buf_length);
cifs_pdu->Protocol, be32_to_cpu(cifs_pdu->smb_buf_length));
rc = crypto_shash_final(&server->secmech.sdescmd5->shash, signature);
......
......@@ -397,9 +397,9 @@
#define GETU32(var) (*((__u32 *)var)) /* BB check for endian issues */
struct smb_hdr {
__u32 smb_buf_length; /* big endian on wire *//* BB length is only two
or three bytes - with one or two byte type preceding it that are
zero - we could mask the type byte off just in case BB */
__be32 smb_buf_length; /* BB length is only two (rarely three) bytes,
with one or two byte "type" preceding it that will be
zero - we could mask the type byte off */
__u8 Protocol[4];
__u8 Command;
union {
......
This diff is collapsed.
......@@ -324,12 +324,12 @@ static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
return -EPROTO;
put_bcc_le(byte_count, pTargetSMB);
byte_count = pTargetSMB->smb_buf_length;
byte_count = be32_to_cpu(pTargetSMB->smb_buf_length);
byte_count += total_in_buf2;
/* don't allow buffer to overflow */
if (byte_count > CIFSMaxBufSize)
return -ENOBUFS;
pTargetSMB->smb_buf_length = byte_count;
pTargetSMB->smb_buf_length = cpu_to_be32(byte_count);
memcpy(data_area_of_target, data_area_of_buf2, total_in_buf2);
......@@ -496,8 +496,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
/* Note that FC 1001 length is big endian on the wire,
but we convert it here so it is always manipulated
as host byte order */
pdu_length = be32_to_cpu((__force __be32)smb_buffer->smb_buf_length);
smb_buffer->smb_buf_length = pdu_length;
pdu_length = be32_to_cpu(smb_buffer->smb_buf_length);
cFYI(1, "rfc1002 length 0x%x", pdu_length+4);
......@@ -2297,7 +2296,7 @@ ip_rfc1001_connect(struct TCP_Server_Info *server)
smb_buf = (struct smb_hdr *)ses_init_buf;
/* sizeof RFC1002_SESSION_REQUEST with no scope */
smb_buf->smb_buf_length = 0x81000044;
smb_buf->smb_buf_length = cpu_to_be32(0x81000044);
rc = smb_send(server, smb_buf, 0x44);
kfree(ses_init_buf);
/*
......@@ -3100,7 +3099,8 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
bcc_ptr += strlen("?????");
bcc_ptr += 1;
count = bcc_ptr - &pSMB->Password[0];
pSMB->hdr.smb_buf_length += count;
pSMB->hdr.smb_buf_length = cpu_to_be32(be32_to_cpu(
pSMB->hdr.smb_buf_length) + count);
pSMB->ByteCount = cpu_to_le16(count);
rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
......
......@@ -304,12 +304,10 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
memset(temp, 0, 256); /* bigger than MAX_CIFS_HDR_SIZE */
buffer->smb_buf_length =
buffer->smb_buf_length = cpu_to_be32(
(2 * word_count) + sizeof(struct smb_hdr) -
4 /* RFC 1001 length field does not count */ +
2 /* for bcc field itself */ ;
/* Note that this is the only network field that has to be converted
to big endian and it is done just before we send it */
2 /* for bcc field itself */) ;
buffer->Protocol[0] = 0xFF;
buffer->Protocol[1] = 'S';
......@@ -424,7 +422,7 @@ check_smb_hdr(struct smb_hdr *smb, __u16 mid)
int
checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length)
{
__u32 len = smb->smb_buf_length;
__u32 len = be32_to_cpu(smb->smb_buf_length);
__u32 clc_len; /* calculated length */
cFYI(0, "checkSMB Length: 0x%x, smb_buf_length: 0x%x", length, len);
......
......@@ -621,7 +621,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
and rest of bcc area. This allows us to avoid
a large buffer 17K allocation */
iov[0].iov_base = (char *)pSMB;
iov[0].iov_len = smb_buf->smb_buf_length + 4;
iov[0].iov_len = be32_to_cpu(smb_buf->smb_buf_length) + 4;
/* setting this here allows the code at the end of the function
to free the request buffer if there's an error */
......@@ -859,7 +859,8 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
iov[2].iov_len = (long) bcc_ptr - (long) str_area;
count = iov[1].iov_len + iov[2].iov_len;
smb_buf->smb_buf_length += count;
smb_buf->smb_buf_length =
cpu_to_be32(be32_to_cpu(smb_buf->smb_buf_length) + count);
put_bcc_le(count, smb_buf);
......
......@@ -129,7 +129,7 @@ smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
unsigned int len = iov[0].iov_len;
unsigned int total_len;
int first_vec = 0;
unsigned int smb_buf_length = smb_buffer->smb_buf_length;
unsigned int smb_buf_length = be32_to_cpu(smb_buffer->smb_buf_length);
struct socket *ssocket = server->ssocket;
if (ssocket == NULL)
......@@ -144,17 +144,10 @@ smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
else
smb_msg.msg_flags = MSG_NOSIGNAL;
/* smb header is converted in header_assemble. bcc and rest of SMB word
area, and byte area if necessary, is converted to littleendian in
cifssmb.c and RFC1001 len is converted to bigendian in smb_send
Flags2 is converted in SendReceive */
total_len = 0;
for (i = 0; i < n_vec; i++)
total_len += iov[i].iov_len;
smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length);
cFYI(1, "Sending smb: total_len %d", total_len);
dump_smb(smb_buffer, len);
......@@ -243,7 +236,7 @@ smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
/* Don't want to modify the buffer as a
side effect of this call. */
smb_buffer->smb_buf_length = smb_buf_length;
smb_buffer->smb_buf_length = cpu_to_be32(smb_buf_length);
return rc;
}
......@@ -387,7 +380,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_hdr *in_buf,
#ifdef CONFIG_CIFS_STATS2
atomic_inc(&server->inSend);
#endif
rc = smb_send(server, in_buf, in_buf->smb_buf_length);
rc = smb_send(server, in_buf, be32_to_cpu(in_buf->smb_buf_length));
#ifdef CONFIG_CIFS_STATS2
atomic_dec(&server->inSend);
mid->when_sent = jiffies;
......@@ -422,7 +415,7 @@ SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses,
int resp_buf_type;
iov[0].iov_base = (char *)in_buf;
iov[0].iov_len = in_buf->smb_buf_length + 4;
iov[0].iov_len = be32_to_cpu(in_buf->smb_buf_length) + 4;
flags |= CIFS_NO_RESP;
rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags);
cFYI(DBG2, "SendRcvNoRsp flags %d rc %d", flags, rc);
......@@ -488,7 +481,7 @@ send_nt_cancel(struct TCP_Server_Info *server, struct smb_hdr *in_buf,
int rc = 0;
/* -4 for RFC1001 length and +2 for BCC field */
in_buf->smb_buf_length = sizeof(struct smb_hdr) - 4 + 2;
in_buf->smb_buf_length = cpu_to_be32(sizeof(struct smb_hdr) - 4 + 2);
in_buf->Command = SMB_COM_NT_CANCEL;
in_buf->WordCount = 0;
put_bcc_le(0, in_buf);
......@@ -499,7 +492,7 @@ send_nt_cancel(struct TCP_Server_Info *server, struct smb_hdr *in_buf,
mutex_unlock(&server->srv_mutex);
return rc;
}
rc = smb_send(server, in_buf, in_buf->smb_buf_length);
rc = smb_send(server, in_buf, be32_to_cpu(in_buf->smb_buf_length));
mutex_unlock(&server->srv_mutex);
cFYI(1, "issued NT_CANCEL for mid %u, rc = %d",
......@@ -612,7 +605,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
return rc;
}
receive_len = midQ->resp_buf->smb_buf_length;
receive_len = be32_to_cpu(midQ->resp_buf->smb_buf_length);
if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
cERROR(1, "Frame too large received. Length: %d Xid: %d",
......@@ -698,9 +691,10 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
to the same server. We may make this configurable later or
use ses->maxReq */
if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
if (be32_to_cpu(in_buf->smb_buf_length) > CIFSMaxBufSize +
MAX_CIFS_HDR_SIZE - 4) {
cERROR(1, "Illegal length, greater than maximum frame, %d",
in_buf->smb_buf_length);
be32_to_cpu(in_buf->smb_buf_length));
return -EIO;
}
......@@ -733,7 +727,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
#ifdef CONFIG_CIFS_STATS2
atomic_inc(&ses->server->inSend);
#endif
rc = smb_send(ses->server, in_buf, in_buf->smb_buf_length);
rc = smb_send(ses->server, in_buf, be32_to_cpu(in_buf->smb_buf_length));
#ifdef CONFIG_CIFS_STATS2
atomic_dec(&ses->server->inSend);
midQ->when_sent = jiffies;
......@@ -768,7 +762,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
return rc;
}
receive_len = midQ->resp_buf->smb_buf_length;
receive_len = be32_to_cpu(midQ->resp_buf->smb_buf_length);
if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
cERROR(1, "Frame too large received. Length: %d Xid: %d",
......@@ -781,7 +775,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
if (midQ->resp_buf && out_buf
&& (midQ->midState == MID_RESPONSE_RECEIVED)) {
out_buf->smb_buf_length = receive_len;
out_buf->smb_buf_length = cpu_to_be32(receive_len);
memcpy((char *)out_buf + 4,
(char *)midQ->resp_buf + 4,
receive_len);
......@@ -800,7 +794,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
}
}
*pbytes_returned = out_buf->smb_buf_length;
*pbytes_returned = be32_to_cpu(out_buf->smb_buf_length);
/* BB special case reconnect tid and uid here? */
rc = map_smb_to_linux_error(out_buf, 0 /* no log */ );
......@@ -877,9 +871,10 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
to the same server. We may make this configurable later or
use ses->maxReq */
if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
if (be32_to_cpu(in_buf->smb_buf_length) > CIFSMaxBufSize +
MAX_CIFS_HDR_SIZE - 4) {
cERROR(1, "Illegal length, greater than maximum frame, %d",
in_buf->smb_buf_length);
be32_to_cpu(in_buf->smb_buf_length));
return -EIO;
}
......@@ -910,7 +905,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
#ifdef CONFIG_CIFS_STATS2
atomic_inc(&ses->server->inSend);
#endif
rc = smb_send(ses->server, in_buf, in_buf->smb_buf_length);
rc = smb_send(ses->server, in_buf, be32_to_cpu(in_buf->smb_buf_length));
#ifdef CONFIG_CIFS_STATS2
atomic_dec(&ses->server->inSend);
midQ->when_sent = jiffies;
......@@ -977,7 +972,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
if (rc != 0)
return rc;
receive_len = midQ->resp_buf->smb_buf_length;
receive_len = be32_to_cpu(midQ->resp_buf->smb_buf_length);
if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
cERROR(1, "Frame too large received. Length: %d Xid: %d",
receive_len, xid);
......@@ -993,7 +988,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
goto out;
}
out_buf->smb_buf_length = receive_len;
out_buf->smb_buf_length = cpu_to_be32(receive_len);
memcpy((char *)out_buf + 4,
(char *)midQ->resp_buf + 4,
receive_len);
......@@ -1012,7 +1007,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
}
}
*pbytes_returned = out_buf->smb_buf_length;
*pbytes_returned = be32_to_cpu(out_buf->smb_buf_length);
/* BB special case reconnect tid and uid here? */
rc = map_smb_to_linux_error(out_buf, 0 /* no log */ );
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment