Re: [PATCH v3] Convert MessageID in smb2_hdr to LE

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



merged into cifs-2.6.git

On Tue, Dec 9, 2014 at 11:37 AM, Sachin Prabhu <sprabhu@xxxxxxxxxx> wrote:
> 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@xxxxxxxxxx>
> ---
>  fs/cifs/cifsglob.h      |  6 +++---
>  fs/cifs/smb2misc.c      | 12 +++++++-----
>  fs/cifs/smb2ops.c       |  3 ++-
>  fs/cifs/smb2pdu.h       |  2 +-
>  fs/cifs/smb2transport.c |  2 +-
>  5 files changed, 14 insertions(+), 11 deletions(-)
>
> diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
> index 02a33e5..41ec69d 100644
> --- a/fs/cifs/cifsglob.h
> +++ b/fs/cifs/cifsglob.h
> @@ -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.
> diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c
> index 1a08a34..6e01933 100644
> --- a/fs/cifs/smb2misc.c
> +++ b/fs/cifs/smb2misc.c
> @@ -32,12 +32,14 @@
>  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;
> diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
> index c5f521b..9e7c86c 100644
> --- a/fs/cifs/smb2ops.c
> +++ b/fs/cifs/smb2ops.c
> @@ -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);
> diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h
> index e3188ab..2d4914e 100644
> --- a/fs/cifs/smb2pdu.h
> +++ b/fs/cifs/smb2pdu.h
> @@ -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 */
> diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c
> index 5111e72..d4c5b6f 100644
> --- a/fs/cifs/smb2transport.c
> +++ b/fs/cifs/smb2transport.c
> @@ -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;
> --
> 2.1.0
>



-- 
Thanks,

Steve
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux