Re: [PATCH] cifs: fix mount on old smb servers

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

 



Very nice cleanup.

Reviewed-by: Ronnie Sahlberg <lsahlber@xxxxxxxxxx>

On Fri, 17 Feb 2023 at 04:44, Paulo Alcantara <pc@xxxxxxxxxxxxx> wrote:
>
> The client was sending rfc1002 session request packet with a wrong
> length field set, therefore failing to mount shares against old SMB
> servers over port 139.
>
> Fix this by calculating the correct length as specified in rfc1002.
>
> Fixes: d7173623bf0b ("cifs: use ALIGN() and round_up() macros")
> Signed-off-by: Paulo Alcantara (SUSE) <pc@xxxxxxxxxxxxx>
> ---
>  fs/cifs/connect.c | 100 ++++++++++++++++++----------------------------
>  1 file changed, 38 insertions(+), 62 deletions(-)
>
> diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
> index b2a04b4e89a5..af49ae53aaf4 100644
> --- a/fs/cifs/connect.c
> +++ b/fs/cifs/connect.c
> @@ -2843,72 +2843,48 @@ ip_rfc1001_connect(struct TCP_Server_Info *server)
>          * negprot - BB check reconnection in case where second
>          * sessinit is sent but no second negprot
>          */
> -       struct rfc1002_session_packet *ses_init_buf;
> -       unsigned int req_noscope_len;
> -       struct smb_hdr *smb_buf;
> +       struct rfc1002_session_packet req = {};
> +       struct smb_hdr *smb_buf = (struct smb_hdr *)&req;
> +       unsigned int len;
> +
> +       req.trailer.session_req.called_len = sizeof(req.trailer.session_req.called_name);
> +
> +       if (server->server_RFC1001_name[0] != 0)
> +               rfc1002mangle(req.trailer.session_req.called_name,
> +                             server->server_RFC1001_name,
> +                             RFC1001_NAME_LEN_WITH_NULL);
> +       else
> +               rfc1002mangle(req.trailer.session_req.called_name,
> +                             DEFAULT_CIFS_CALLED_NAME,
> +                             RFC1001_NAME_LEN_WITH_NULL);
> +
> +       req.trailer.session_req.calling_len = sizeof(req.trailer.session_req.calling_name);
> +
> +       /* calling name ends in null (byte 16) from old smb convention */
> +       if (server->workstation_RFC1001_name[0] != 0)
> +               rfc1002mangle(req.trailer.session_req.calling_name,
> +                             server->workstation_RFC1001_name,
> +                             RFC1001_NAME_LEN_WITH_NULL);
> +       else
> +               rfc1002mangle(req.trailer.session_req.calling_name,
> +                             "LINUX_CIFS_CLNT",
> +                             RFC1001_NAME_LEN_WITH_NULL);
>
> -       ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
> -                              GFP_KERNEL);
> -
> -       if (ses_init_buf) {
> -               ses_init_buf->trailer.session_req.called_len = 32;
> -
> -               if (server->server_RFC1001_name[0] != 0)
> -                       rfc1002mangle(ses_init_buf->trailer.
> -                                     session_req.called_name,
> -                                     server->server_RFC1001_name,
> -                                     RFC1001_NAME_LEN_WITH_NULL);
> -               else
> -                       rfc1002mangle(ses_init_buf->trailer.
> -                                     session_req.called_name,
> -                                     DEFAULT_CIFS_CALLED_NAME,
> -                                     RFC1001_NAME_LEN_WITH_NULL);
> -
> -               ses_init_buf->trailer.session_req.calling_len = 32;
> -
> -               /*
> -                * calling name ends in null (byte 16) from old smb
> -                * convention.
> -                */
> -               if (server->workstation_RFC1001_name[0] != 0)
> -                       rfc1002mangle(ses_init_buf->trailer.
> -                                     session_req.calling_name,
> -                                     server->workstation_RFC1001_name,
> -                                     RFC1001_NAME_LEN_WITH_NULL);
> -               else
> -                       rfc1002mangle(ses_init_buf->trailer.
> -                                     session_req.calling_name,
> -                                     "LINUX_CIFS_CLNT",
> -                                     RFC1001_NAME_LEN_WITH_NULL);
> -
> -               ses_init_buf->trailer.session_req.scope1 = 0;
> -               ses_init_buf->trailer.session_req.scope2 = 0;
> -               smb_buf = (struct smb_hdr *)ses_init_buf;
> -
> -               /* sizeof RFC1002_SESSION_REQUEST with no scopes */
> -               req_noscope_len = sizeof(struct rfc1002_session_packet) - 2;
> +       /*
> +        * As per rfc1002, @len must be the number of bytes that follows the
> +        * length field of a rfc1002 session request payload.
> +        */
> +       len = sizeof(req) - offsetof(struct rfc1002_session_packet, trailer.session_req);
>
> -               /* == cpu_to_be32(0x81000044) */
> -               smb_buf->smb_buf_length =
> -                       cpu_to_be32((RFC1002_SESSION_REQUEST << 24) | req_noscope_len);
> -               rc = smb_send(server, smb_buf, 0x44);
> -               kfree(ses_init_buf);
> -               /*
> -                * RFC1001 layer in at least one server
> -                * requires very short break before negprot
> -                * presumably because not expecting negprot
> -                * to follow so fast.  This is a simple
> -                * solution that works without
> -                * complicating the code and causes no
> -                * significant slowing down on mount
> -                * for everyone else
> -                */
> -               usleep_range(1000, 2000);
> -       }
> +       smb_buf->smb_buf_length = cpu_to_be32((RFC1002_SESSION_REQUEST << 24) | len);
> +       rc = smb_send(server, smb_buf, len);
>         /*
> -        * else the negprot may still work without this
> -        * even though malloc failed
> +        * RFC1001 layer in at least one server requires very short break before
> +        * negprot presumably because not expecting negprot to follow so fast.
> +        * This is a simple solution that works without complicating the code
> +        * and causes no significant slowing down on mount for everyone else
>          */
> +       usleep_range(1000, 2000);
>
>         return rc;
>  }
> --
> 2.39.1
>



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

  Powered by Linux