* [PATCH v2 2/2] cifs: quirk for STATUS_OBJECT_NAME_INVALID returned for non-ASCII dfs refs
@ 2022-01-14 19:53 Eugene Korenevsky
2022-01-17 19:33 ` Steve French
2022-01-17 21:14 ` Enzo Matsumiya
0 siblings, 2 replies; 5+ messages in thread
From: Eugene Korenevsky @ 2022-01-14 19:53 UTC (permalink / raw)
To: linux-cifs; +Cc: Steve French
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
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v2 2/2] cifs: quirk for STATUS_OBJECT_NAME_INVALID returned for non-ASCII dfs refs
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
2022-01-17 21:14 ` Enzo Matsumiya
1 sibling, 0 replies; 5+ messages in thread
From: Steve French @ 2022-01-17 19:33 UTC (permalink / raw)
To: Eugene Korenevsky; +Cc: CIFS
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
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v2 2/2] cifs: quirk for STATUS_OBJECT_NAME_INVALID returned for non-ASCII dfs refs
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
@ 2022-01-17 21:14 ` Enzo Matsumiya
2022-01-18 17:24 ` Eugene Korenevsky
1 sibling, 1 reply; 5+ messages in thread
From: Enzo Matsumiya @ 2022-01-17 21:14 UTC (permalink / raw)
To: Eugene Korenevsky; +Cc: linux-cifs, Steve French
On 01/14, Eugene Korenevsky 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>
The patch fixes the initial issue (mount and listing files) as per
reported in the mentioned bugzilla, but it still fails to create files:
% echo "test" | sudo tee myfile
tee: myfile: No such file or directory
test
% dmesg
...
[20510.826644] CIFS: fs/cifs/dfs_cache.c: cache_refresh_path: search path: \w19-addc.mori.test\дфс\test
[20510.826653] CIFS: fs/cifs/dfs_cache.c: get_dfs_referral: get an DFS referral for \w19-addc.mori.test\дфс\test [45/504]
[20510.826658] CIFS: fs/cifs/smb2ops.c: smb2_get_dfs_refer: path: \w19-addc.mori.test\дфс\test
[20510.826665] CIFS: fs/cifs/smb2pdu.c: SMB2 IOCTL
[20510.826670] CIFS: fs/cifs/transport.c: wait_for_free_credits: remove 1 credits total=577
[20510.826690] CIFS: fs/cifs/transport.c: Sending smb: smb_len=184
[20510.828315] CIFS: fs/cifs/connect.c: RFC1002 header 0x12a
[20510.828331] CIFS: fs/cifs/smb2misc.c: SMB2 data length 186 offset 112
[20510.828336] CIFS: fs/cifs/smb2misc.c: SMB2 len 298
[20510.828342] CIFS: fs/cifs/smb2ops.c: smb2_add_credits: added 10 credits total=587
[20510.828364] CIFS: fs/cifs/transport.c: cifs_sync_mid_result: cmd=11 mid=41 state=4
[20510.828397] CIFS: fs/cifs/misc.c: Null buffer passed to cifs_small_buf_release
[20510.828406] CIFS: fs/cifs/misc.c: num_referrals: 1 dfs flags: 0x3 ...
[20510.828432] CIFS: fs/cifs/misc.c: DFS ref '\w19-addc.mori.test\дфс\test' is not found, emulate -ENOENT
...
Cheers,
Enzo
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v2 2/2] cifs: quirk for STATUS_OBJECT_NAME_INVALID returned for non-ASCII dfs refs
2022-01-17 21:14 ` Enzo Matsumiya
@ 2022-01-18 17:24 ` Eugene Korenevsky
2022-01-20 19:18 ` Steve French
0 siblings, 1 reply; 5+ messages in thread
From: Eugene Korenevsky @ 2022-01-18 17:24 UTC (permalink / raw)
To: Enzo Matsumiya; +Cc: linux-cifs
On Mon, Jan 17, 2022 at 06:14:05PM -0300, Enzo Matsumiya wrote:
> The patch fixes the initial issue (mount and listing files) as per
> reported in the mentioned bugzilla, but it still fails to create files:
>
> % echo "test" | sudo tee myfile
> tee: myfile: No such file or directory
> test
Sorry, cannot reproduce.
```
# mount
...
//192.168.57.14/дфс on /tmp/x type cifs (rw,relatime,vers=default,cache=strict,username=user,domain=WIN-TCIN4O86A6M,uid=0,noforceuid,gid=0,noforcegid,addr=192.168.57.14,file_mode=0755,dir_mode=0755,soft,nounix,mapposix,rsize=4194304,wsize=4194304,bsize=1048576,echo_interval=60,actimeo=1)
//WIN-TCIN4O86A6M/дфс/temp on /tmp/x/temp type cifs (rw,relatime,vers=3.1.1,cache=strict,username=user,domain=WIN-TCIN4O86A6M,uid=0,noforceuid,gid=0,noforcegid,addr=192.168.57.4,file_mode=0755,dir_mode=0755,soft,nounix,mapposix,rsize=4194304,wsize=4194304,bsize=1048576,echo_interval=60,actimeo=1)
# pwd
/tmp/x/temp
# echo test | tee myfile
test
# rm myfile
# echo test | tee myfile
test
# cat myfile
test
# rm myfile && echo ok
ok
```
Could you provide your 'mount' output as well?
--
Eugene
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v2 2/2] cifs: quirk for STATUS_OBJECT_NAME_INVALID returned for non-ASCII dfs refs
2022-01-18 17:24 ` Eugene Korenevsky
@ 2022-01-20 19:18 ` Steve French
0 siblings, 0 replies; 5+ messages in thread
From: Steve French @ 2022-01-20 19:18 UTC (permalink / raw)
To: Eugene Korenevsky; +Cc: Enzo Matsumiya, CIFS
we can do a followon to this if you find any problems with it later in the week.
On Thu, Jan 20, 2022 at 1:16 PM Eugene Korenevsky
<ekorenevsky@astralinux.ru> wrote:
>
> On Mon, Jan 17, 2022 at 06:14:05PM -0300, Enzo Matsumiya wrote:
>
> > The patch fixes the initial issue (mount and listing files) as per
> > reported in the mentioned bugzilla, but it still fails to create files:
> >
> > % echo "test" | sudo tee myfile
> > tee: myfile: No such file or directory
> > test
>
>
> Sorry, cannot reproduce.
>
> ```
> # mount
> ...
> //192.168.57.14/дфс on /tmp/x type cifs (rw,relatime,vers=default,cache=strict,username=user,domain=WIN-TCIN4O86A6M,uid=0,noforceuid,gid=0,noforcegid,addr=192.168.57.14,file_mode=0755,dir_mode=0755,soft,nounix,mapposix,rsize=4194304,wsize=4194304,bsize=1048576,echo_interval=60,actimeo=1)
> //WIN-TCIN4O86A6M/дфс/temp on /tmp/x/temp type cifs (rw,relatime,vers=3.1.1,cache=strict,username=user,domain=WIN-TCIN4O86A6M,uid=0,noforceuid,gid=0,noforcegid,addr=192.168.57.4,file_mode=0755,dir_mode=0755,soft,nounix,mapposix,rsize=4194304,wsize=4194304,bsize=1048576,echo_interval=60,actimeo=1)
> # pwd
> /tmp/x/temp
> # echo test | tee myfile
> test
> # rm myfile
> # echo test | tee myfile
> test
> # cat myfile
> test
> # rm myfile && echo ok
> ok
> ```
>
> Could you provide your 'mount' output as well?
>
>
> --
> Eugene
--
Thanks,
Steve
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2022-01-20 19:18 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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
2022-01-17 21:14 ` Enzo Matsumiya
2022-01-18 17:24 ` Eugene Korenevsky
2022-01-20 19:18 ` Steve French
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.