From: Pali Rohár Date: Mon, 6 Jul 2026 18:48:09 +0000 (+0200) Subject: cifs: Fix and improve cifs_is_path_accessible() function X-Git-Tag: v7.2-rc3~22^2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=90dd1415a158b99ca16f5fe5862c07683e9ddcec;p=thirdparty%2Fkernel%2Flinux.git cifs: Fix and improve cifs_is_path_accessible() function Do not call SMBQueryInformation() command for path with SMB wildcard characters on non-UNICODE connection because server expands wildcards. Function cifs_is_path_accessible() needs to check if the real path exists and must not expand wildcard characters. Do not dynamically allocate memory for small FILE_ALL_INFO structure and instead allocate it on the stack. This structure is allocated on stack by all other functions. When CAP_NT_SMBS was not negotiated then do not issue CIFSSMBQPathInfo() command. This command returns failure by non-NT Win9x SMB servers, so there is no need try it. The purpose of cifs_is_path_accessible() function is just to check if the path is accessible, so SMBQueryInformation() for old servers is enough. Signed-off-by: Pali Rohár Signed-off-by: Steve French --- diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c index f72879af12c9..dc5a8c1da623 100644 --- a/fs/smb/client/smb1ops.c +++ b/fs/smb/client/smb1ops.c @@ -505,21 +505,27 @@ static int cifs_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon, struct cifs_sb_info *cifs_sb, const char *full_path) { - int rc; - FILE_ALL_INFO *file_info; + int rc = -EOPNOTSUPP; + FILE_ALL_INFO file_info; - file_info = kmalloc_obj(FILE_ALL_INFO); - if (file_info == NULL) - return -ENOMEM; + if (tcon->ses->capabilities & CAP_NT_SMBS) + rc = CIFSSMBQPathInfo(xid, tcon, full_path, &file_info, + 0 /* not legacy */, cifs_sb->local_nls, + cifs_remap(cifs_sb)); - rc = CIFSSMBQPathInfo(xid, tcon, full_path, file_info, - 0 /* not legacy */, cifs_sb->local_nls, - cifs_remap(cifs_sb)); + /* + * Non-UNICODE variant of fallback functions below expands wildcards, + * so they cannot be used for querying paths with wildcard characters. + * Therefore for such paths returns -ENOENT as they cannot exist. + */ + if ((rc == -EOPNOTSUPP || rc == -EINVAL) && + !(tcon->ses->capabilities & CAP_UNICODE) && + strpbrk(full_path, "*?\"><")) + rc = -ENOENT; if (rc == -EOPNOTSUPP || rc == -EINVAL) - rc = SMBQueryInformation(xid, tcon, full_path, file_info, + rc = SMBQueryInformation(xid, tcon, full_path, &file_info, cifs_sb->local_nls, cifs_remap(cifs_sb)); - kfree(file_info); return rc; }