]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Convert MessageID in smb2_hdr to LE
authorSachin Prabhu <sprabhu@redhat.com>
Tue, 9 Dec 2014 17:37:00 +0000 (17:37 +0000)
committerSteve French <steve.french@primarydata.com>
Sun, 14 Dec 2014 20:55:45 +0000 (14:55 -0600)
We have encountered failures when When testing smb2 mounts on ppc64
machines when using both Samba as well as Windows 2012.

On poking around, the problem was determined to be caused by the
high endian MessageID passed in the header for smb2. On checking the
corresponding MID for smb1 is converted to LE before being sent on the
wire.

We have tested this patch successfully on a ppc64 machine.

Signed-off-by: Sachin Prabhu <sprabhu@redhat.com>
fs/cifs/cifsglob.h
fs/cifs/smb2misc.c
fs/cifs/smb2ops.c
fs/cifs/smb2pdu.h
fs/cifs/smb2transport.c

index 6e139111fdb250cc85f28d96d7d26fe0508850a4..22b289a3b1c4d3e12727cc0a005456fa9b295a00 100644 (file)
@@ -661,16 +661,16 @@ set_credits(struct TCP_Server_Info *server, const int val)
        server->ops->set_credits(server, val);
 }
 
-static inline __u64
+static inline __le64
 get_next_mid64(struct TCP_Server_Info *server)
 {
-       return server->ops->get_next_mid(server);
+       return cpu_to_le64(server->ops->get_next_mid(server));
 }
 
 static inline __le16
 get_next_mid(struct TCP_Server_Info *server)
 {
-       __u16 mid = get_next_mid64(server);
+       __u16 mid = server->ops->get_next_mid(server);
        /*
         * The value in the SMB header should be little endian for easy
         * on-the-wire decoding.
index f1cefc9763edaeb3115ee1868d9bc4f033b7e0f5..689f035915cf70f075d71fca5e281ec009c5420a 100644 (file)
 static int
 check_smb2_hdr(struct smb2_hdr *hdr, __u64 mid)
 {
+       __u64 wire_mid = le64_to_cpu(hdr->MessageId);
+
        /*
         * Make sure that this really is an SMB, that it is a response,
         * and that the message ids match.
         */
        if ((*(__le32 *)hdr->ProtocolId == SMB2_PROTO_NUMBER) &&
-           (mid == hdr->MessageId)) {
+           (mid == wire_mid)) {
                if (hdr->Flags & SMB2_FLAGS_SERVER_TO_REDIR)
                        return 0;
                else {
@@ -51,11 +53,11 @@ check_smb2_hdr(struct smb2_hdr *hdr, __u64 mid)
                if (*(__le32 *)hdr->ProtocolId != SMB2_PROTO_NUMBER)
                        cifs_dbg(VFS, "Bad protocol string signature header %x\n",
                                 *(unsigned int *) hdr->ProtocolId);
-               if (mid != hdr->MessageId)
+               if (mid != wire_mid)
                        cifs_dbg(VFS, "Mids do not match: %llu and %llu\n",
-                                mid, hdr->MessageId);
+                                mid, wire_mid);
        }
-       cifs_dbg(VFS, "Bad SMB detected. The Mid=%llu\n", hdr->MessageId);
+       cifs_dbg(VFS, "Bad SMB detected. The Mid=%llu\n", wire_mid);
        return 1;
 }
 
@@ -95,7 +97,7 @@ smb2_check_message(char *buf, unsigned int length)
 {
        struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
        struct smb2_pdu *pdu = (struct smb2_pdu *)hdr;
-       __u64 mid = hdr->MessageId;
+       __u64 mid = le64_to_cpu(hdr->MessageId);
        __u32 len = get_rfc1002_length(buf);
        __u32 clc_len;  /* calculated length */
        int command;
index 93fd0586f9ec6e661c17de59cb66535d80e7ff51..96b5d40a2ece611b27ed19668cc4b7b665605113 100644 (file)
@@ -176,10 +176,11 @@ smb2_find_mid(struct TCP_Server_Info *server, char *buf)
 {
        struct mid_q_entry *mid;
        struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
+       __u64 wire_mid = le64_to_cpu(hdr->MessageId);
 
        spin_lock(&GlobalMid_Lock);
        list_for_each_entry(mid, &server->pending_mid_q, qhead) {
-               if ((mid->mid == hdr->MessageId) &&
+               if ((mid->mid == wire_mid) &&
                    (mid->mid_state == MID_REQUEST_SUBMITTED) &&
                    (mid->command == hdr->Command)) {
                        spin_unlock(&GlobalMid_Lock);
index ce858477002a6148e31a85e9f28fc012968f52c9..70867d54fb8bf485cb5ff4dcb3049f67ca86cb45 100644 (file)
@@ -110,7 +110,7 @@ struct smb2_hdr {
        __le16 CreditRequest;  /* CreditResponse */
        __le32 Flags;
        __le32 NextCommand;
-       __u64  MessageId;       /* opaque - so can stay little endian */
+       __le64 MessageId;
        __le32 ProcessId;
        __u32  TreeId;          /* opaque - so do not make little endian */
        __u64  SessionId;       /* opaque - so do not make little endian */
index 5111e7272db62e718fcb3d968af48083d598bccf..d4c5b6f109a7feaa6f2c99f21ca332ff41a2673f 100644 (file)
@@ -490,7 +490,7 @@ smb2_mid_entry_alloc(const struct smb2_hdr *smb_buffer,
                return temp;
        else {
                memset(temp, 0, sizeof(struct mid_q_entry));
-               temp->mid = smb_buffer->MessageId;      /* always LE */
+               temp->mid = le64_to_cpu(smb_buffer->MessageId);
                temp->pid = current->pid;
                temp->command = smb_buffer->Command;    /* Always LE */
                temp->when_alloc = jiffies;