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 <pali@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
Pali Rohár
2026-07-06 20:48:09 +02:00
committed by Steve French
parent e3d9c7160d
commit 90dd1415a1

View File

@@ -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;
}