From patchwork Fri Jan 14 19:53:00 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eugene Korenevsky X-Patchwork-Id: 12713939 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A1113C433F5 for ; Fri, 14 Jan 2022 19:53:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231156AbiANTxE (ORCPT ); Fri, 14 Jan 2022 14:53:04 -0500 Received: from mail.astralinux.ru ([217.74.38.119]:45486 "EHLO mail.astralinux.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229471AbiANTxE (ORCPT ); Fri, 14 Jan 2022 14:53:04 -0500 Received: from localhost (localhost [127.0.0.1]) by mail.astralinux.ru (Postfix) with ESMTP id 51CAA30637FA; Fri, 14 Jan 2022 22:53:02 +0300 (MSK) Received: from mail.astralinux.ru ([127.0.0.1]) by localhost (rbta-msk-vsrv-mail01.astralinux.ru [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id F6nfRJuoy1wj; Fri, 14 Jan 2022 22:53:01 +0300 (MSK) Received: from localhost (localhost [127.0.0.1]) by mail.astralinux.ru (Postfix) with ESMTP id D2CD630637FB; Fri, 14 Jan 2022 22:53:01 +0300 (MSK) X-Virus-Scanned: amavisd-new at astralinux.ru Received: from mail.astralinux.ru ([127.0.0.1]) by localhost (rbta-msk-vsrv-mail01.astralinux.ru [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id LJH32jIfEpYP; Fri, 14 Jan 2022 22:53:01 +0300 (MSK) Received: from himera.home (37-145-209-165.broadband.corbina.ru [37.145.209.165]) by mail.astralinux.ru (Postfix) with ESMTPSA id 96D1C30637F6; Fri, 14 Jan 2022 22:53:01 +0300 (MSK) Date: Fri, 14 Jan 2022 22:53:00 +0300 From: Eugene Korenevsky To: linux-cifs@vger.kernel.org Cc: Steve French Subject: [PATCH v2 1/2] cifs: alloc_path_with_tree_prefix: do not append sep. if the path is empty Message-ID: MIME-Version: 1.0 Content-Disposition: inline Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org alloc_path_with_tree_prefix() concatenates tree prefix and the path. Windows CIFS client does not add separator after the tree prefix if the path is empty. Let's do the same. This fixes mounting DFS namespaces with names containing non-ASCII symbols. BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=215440 Signed-off-by: Eugene Korenevsky --- v2: The patch is included in the patchset for #215440 fix fs/cifs/smb2pdu.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 8b3670388cda..88ea0163257c 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -2527,8 +2527,13 @@ alloc_path_with_tree_prefix(__le16 **out_path, int *out_size, int *out_len, cp = load_nls_default(); cifs_strtoUTF16(*out_path, treename, treename_len, cp); - UniStrcat(*out_path, sep); - UniStrcat(*out_path, path); + + /* Do not append the separator if the path is empty */ + if (path[0] != cpu_to_le16(0x0000)) { + UniStrcat(*out_path, sep); + UniStrcat(*out_path, path); + } + unload_nls(cp); return 0; From patchwork Fri Jan 14 19:53:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eugene Korenevsky X-Patchwork-Id: 12713940 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 080CCC433EF for ; Fri, 14 Jan 2022 19:53:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231603AbiANTxo (ORCPT ); Fri, 14 Jan 2022 14:53:44 -0500 Received: from mail.astralinux.ru ([217.74.38.119]:45618 "EHLO mail.astralinux.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229471AbiANTxo (ORCPT ); Fri, 14 Jan 2022 14:53:44 -0500 Received: from localhost (localhost [127.0.0.1]) by mail.astralinux.ru (Postfix) with ESMTP id DE63230637FC; Fri, 14 Jan 2022 22:53:42 +0300 (MSK) Received: from mail.astralinux.ru ([127.0.0.1]) by localhost (rbta-msk-vsrv-mail01.astralinux.ru [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id buaCsRl3SEOW; Fri, 14 Jan 2022 22:53:42 +0300 (MSK) Received: from localhost (localhost [127.0.0.1]) by mail.astralinux.ru (Postfix) with ESMTP id EBE2E30637FD; Fri, 14 Jan 2022 22:53:41 +0300 (MSK) X-Virus-Scanned: amavisd-new at astralinux.ru Received: from mail.astralinux.ru ([127.0.0.1]) by localhost (rbta-msk-vsrv-mail01.astralinux.ru [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id Ktjw8ZS20BOj; Fri, 14 Jan 2022 22:53:41 +0300 (MSK) Received: from himera.home (37-145-209-165.broadband.corbina.ru [37.145.209.165]) by mail.astralinux.ru (Postfix) with ESMTPSA id BD1A030637FB; Fri, 14 Jan 2022 22:53:41 +0300 (MSK) Date: Fri, 14 Jan 2022 22:53:40 +0300 From: Eugene Korenevsky To: linux-cifs@vger.kernel.org Cc: Steve French Subject: [PATCH v2 2/2] cifs: quirk for STATUS_OBJECT_NAME_INVALID returned for non-ASCII dfs refs Message-ID: MIME-Version: 1.0 Content-Disposition: inline Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Windows SMB server responds with STATUS_OBJECT_NAME_INVALID code to SMB2 QUERY_INFO request for "\\\" DFS reference, where 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 --- 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 "\\\" DFS reference, + * where 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