All of lore.kernel.org
 help / color / mirror / Atom feed
From: Steve French <smfrench@gmail.com>
To: Eugene Korenevsky <ekorenevsky@astralinux.ru>
Cc: CIFS <linux-cifs@vger.kernel.org>
Subject: Re: [PATCH v2 2/2] cifs: quirk for STATUS_OBJECT_NAME_INVALID returned for non-ASCII dfs refs
Date: Mon, 17 Jan 2022 13:33:15 -0600	[thread overview]
Message-ID: <CAH2r5mt75RnL7zhE8zaySj0Wp1ic5WFd+YOA3jtJv64EoV6vuw@mail.gmail.com> (raw)
In-Reply-To: <YeHUxJ9zTVNrKveF@himera.home>

tentatively merged into cifs-2.6.git for-next pending more testing

On Fri, Jan 14, 2022 at 5:04 PM Eugene Korenevsky
<ekorenevsky@astralinux.ru> wrote:
>
> Windows SMB server responds with STATUS_OBJECT_NAME_INVALID code to
> SMB2 QUERY_INFO request for "\<server>\<dfsname>\<linkpath>" DFS reference,
> where <dfsname> contains non-ASCII unicode symbols.
>
> Check such DFS reference and emulate -EREMOTE if it is actual.
>
> BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=215440
> Signed-off-by: Eugene Korenevsky <ekorenevsky@astralinux.ru>
> ---
> v2: No changes, this is a new patch in the patchset for #215440 fix
>
>  fs/cifs/cifsproto.h |  5 +++++
>  fs/cifs/connect.c   |  5 +++++
>  fs/cifs/inode.c     |  6 ++++++
>  fs/cifs/misc.c      | 49 +++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 65 insertions(+)
>
> diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
> index 4f5a3e857df4..b3a9cc0def2c 100644
> --- a/fs/cifs/cifsproto.h
> +++ b/fs/cifs/cifsproto.h
> @@ -626,6 +626,11 @@ static inline int get_dfs_path(const unsigned int xid, struct cifs_ses *ses,
>  int match_target_ip(struct TCP_Server_Info *server,
>                     const char *share, size_t share_len,
>                     bool *result);
> +
> +int cifs_dfs_query_info_nonascii_quirk(const unsigned int xid,
> +                                      struct cifs_tcon *tcon,
> +                                      struct cifs_sb_info *cifs_sb,
> +                                      const char *dfs_link_path);
>  #endif
>
>  static inline int cifs_create_options(struct cifs_sb_info *cifs_sb, int options)
> diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
> index 1060164b984a..db0f8a1c8fb5 100644
> --- a/fs/cifs/connect.c
> +++ b/fs/cifs/connect.c
> @@ -3322,6 +3322,11 @@ static int is_path_remote(struct mount_ctx *mnt_ctx)
>
>         rc = server->ops->is_path_accessible(xid, tcon, cifs_sb,
>                                              full_path);
> +#ifdef CONFIG_CIFS_DFS_UPCALL
> +       if (rc == -ENOENT && is_tcon_dfs(tcon))
> +               rc = cifs_dfs_query_info_nonascii_quirk(xid, tcon, cifs_sb,
> +                                                       full_path);
> +#endif
>         if (rc != 0 && rc != -EREMOTE) {
>                 kfree(full_path);
>                 return rc;
> diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
> index 279622e4eb1c..baa197edd8c5 100644
> --- a/fs/cifs/inode.c
> +++ b/fs/cifs/inode.c
> @@ -952,6 +952,12 @@ cifs_get_inode_info(struct inode **inode,
>                 rc = server->ops->query_path_info(xid, tcon, cifs_sb,
>                                                  full_path, tmp_data,
>                                                  &adjust_tz, &is_reparse_point);
> +#ifdef CONFIG_CIFS_DFS_UPCALL
> +               if (rc == -ENOENT && is_tcon_dfs(tcon))
> +                       rc = cifs_dfs_query_info_nonascii_quirk(xid, tcon,
> +                                                               cifs_sb,
> +                                                               full_path);
> +#endif
>                 data = tmp_data;
>         }
>
> diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
> index 5148d48d6a35..56598f7dbe00 100644
> --- a/fs/cifs/misc.c
> +++ b/fs/cifs/misc.c
> @@ -1302,4 +1302,53 @@ int cifs_update_super_prepath(struct cifs_sb_info *cifs_sb, char *prefix)
>         cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH;
>         return 0;
>  }
> +
> +/** cifs_dfs_query_info_nonascii_quirk
> + * Handle weird Windows SMB server behaviour. It responds with
> + * STATUS_OBJECT_NAME_INVALID code to SMB2 QUERY_INFO request
> + * for "\<server>\<dfsname>\<linkpath>" DFS reference,
> + * where <dfsname> contains non-ASCII unicode symbols.
> + *
> + * Check such DFS reference and emulate -ENOENT if it is actual.
> + */
> +int cifs_dfs_query_info_nonascii_quirk(const unsigned int xid,
> +                                      struct cifs_tcon *tcon,
> +                                      struct cifs_sb_info *cifs_sb,
> +                                      const char *linkpath)
> +{
> +       char *treename, *dfspath, sep;
> +       int treenamelen, linkpathlen, rc;
> +
> +       treename = tcon->treeName;
> +       /* MS-DFSC: All paths in REQ_GET_DFS_REFERRAL and RESP_GET_DFS_REFERRAL
> +        * messages MUST be encoded with exactly one leading backslash, not two
> +        * leading backslashes.
> +        */
> +       sep = CIFS_DIR_SEP(cifs_sb);
> +       if (treename[0] == sep && treename[1] == sep)
> +               treename++;
> +       linkpathlen = strlen(linkpath);
> +       treenamelen = strnlen(treename, MAX_TREE_SIZE + 1);
> +       dfspath = kzalloc(treenamelen + linkpathlen + 1, GFP_KERNEL);
> +       if (!dfspath)
> +               return -ENOMEM;
> +       if (treenamelen)
> +               memcpy(dfspath, treename, treenamelen);
> +       memcpy(dfspath + treenamelen, linkpath, linkpathlen);
> +       rc = dfs_cache_find(xid, tcon->ses, cifs_sb->local_nls,
> +                           cifs_remap(cifs_sb), dfspath, NULL, NULL);
> +       if (rc == 0) {
> +               cifs_dbg(FYI, "DFS ref '%s' is found, emulate -EREMOTE\n",
> +                        dfspath);
> +               rc = -EREMOTE;
> +       } else if (rc == -EEXIST) {
> +               cifs_dbg(FYI, "DFS ref '%s' is not found, emulate -ENOENT\n",
> +                        dfspath);
> +               rc = -ENOENT;
> +       } else {
> +               cifs_dbg(FYI, "%s: dfs_cache_find returned %d\n", __func__, rc);
> +       }
> +       kfree(dfspath);
> +       return rc;
> +}
>  #endif
> --
> 2.30.2
>


-- 
Thanks,

Steve

  reply	other threads:[~2022-01-17 19:33 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-14 19:53 [PATCH v2 2/2] cifs: quirk for STATUS_OBJECT_NAME_INVALID returned for non-ASCII dfs refs Eugene Korenevsky
2022-01-17 19:33 ` Steve French [this message]
2022-01-17 21:14 ` Enzo Matsumiya
2022-01-18 17:24   ` Eugene Korenevsky
2022-01-20 19:18     ` Steve French

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAH2r5mt75RnL7zhE8zaySj0Wp1ic5WFd+YOA3jtJv64EoV6vuw@mail.gmail.com \
    --to=smfrench@gmail.com \
    --cc=ekorenevsky@astralinux.ru \
    --cc=linux-cifs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.