]> git.hungrycats.org Git - linux/commitdiff
smb: client: use actual path when queryfs
authorwangrong <wangrong@uniontech.com>
Thu, 20 Jun 2024 08:37:29 +0000 (16:37 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 10 Oct 2024 10:01:02 +0000 (12:01 +0200)
commit a421e3fe0e6abe27395078f4f0cec5daf466caea upstream.

Due to server permission control, the client does not have access to
the shared root directory, but can access subdirectories normally, so
users usually mount the shared subdirectories directly. In this case,
queryfs should use the actual path instead of the root directory to
avoid the call returning an error (EACCES).

Signed-off-by: wangrong <wangrong@uniontech.com>
Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
Cc: stable@vger.kernel.org
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/smb/client/cifsfs.c
fs/smb/client/cifsglob.h
fs/smb/client/smb1ops.c
fs/smb/client/smb2ops.c

index a1acf5bd1e3a4a1c3d845de2e7e6eb0d46d37c1d..5955e265b3958a0d98e88689fc65d6c586d49c10 100644 (file)
@@ -313,8 +313,17 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
        struct TCP_Server_Info *server = tcon->ses->server;
        unsigned int xid;
        int rc = 0;
+       const char *full_path;
+       void *page;
 
        xid = get_xid();
+       page = alloc_dentry_path();
+
+       full_path = build_path_from_dentry(dentry, page);
+       if (IS_ERR(full_path)) {
+               rc = PTR_ERR(full_path);
+               goto statfs_out;
+       }
 
        if (le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength) > 0)
                buf->f_namelen =
@@ -330,8 +339,10 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
        buf->f_ffree = 0;       /* unlimited */
 
        if (server->ops->queryfs)
-               rc = server->ops->queryfs(xid, tcon, cifs_sb, buf);
+               rc = server->ops->queryfs(xid, tcon, full_path, cifs_sb, buf);
 
+statfs_out:
+       free_dentry_path(page);
        free_xid(xid);
        return rc;
 }
index 552792f28122c0274ed5ec9949356314cbc9b462..0ac026cec830fffebaa37e236c8abae38c52d6af 100644 (file)
@@ -482,7 +482,7 @@ struct smb_version_operations {
                        __u16 net_fid, struct cifsInodeInfo *cifs_inode);
        /* query remote filesystem */
        int (*queryfs)(const unsigned int, struct cifs_tcon *,
-                      struct cifs_sb_info *, struct kstatfs *);
+                      const char *, struct cifs_sb_info *, struct kstatfs *);
        /* send mandatory brlock to the server */
        int (*mand_lock)(const unsigned int, struct cifsFileInfo *, __u64,
                         __u64, __u32, int, int, bool);
index e1f2feb56f45f6ac10ab50875689638da6b7712e..8c03250d85ae0c4d5bc1738143fb88989e213381 100644 (file)
@@ -909,7 +909,7 @@ cifs_oplock_response(struct cifs_tcon *tcon, __u64 persistent_fid,
 
 static int
 cifs_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
-            struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
+            const char *path, struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
 {
        int rc = -EOPNOTSUPP;
 
index 1d6e8eacdd742b98c0396466b65f5ec0bc2088ff..7ea02619e67340fde3bab0c62ab6b9b3729ee20c 100644 (file)
@@ -2816,7 +2816,7 @@ out_free_path:
 
 static int
 smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
-            struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
+            const char *path, struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
 {
        struct smb2_query_info_rsp *rsp;
        struct smb2_fs_full_size_info *info = NULL;
@@ -2825,7 +2825,7 @@ smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
        int rc;
 
 
-       rc = smb2_query_info_compound(xid, tcon, "",
+       rc = smb2_query_info_compound(xid, tcon, path,
                                      FILE_READ_ATTRIBUTES,
                                      FS_FULL_SIZE_INFORMATION,
                                      SMB2_O_INFO_FILESYSTEM,
@@ -2853,28 +2853,33 @@ qfs_exit:
 
 static int
 smb311_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
-              struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
+              const char *path, struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
 {
        int rc;
-       __le16 srch_path = 0; /* Null - open root of share */
+       __le16 *utf16_path = NULL;
        u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
        struct cifs_open_parms oparms;
        struct cifs_fid fid;
 
        if (!tcon->posix_extensions)
-               return smb2_queryfs(xid, tcon, cifs_sb, buf);
+               return smb2_queryfs(xid, tcon, path, cifs_sb, buf);
 
        oparms = (struct cifs_open_parms) {
                .tcon = tcon,
-               .path = "",
+               .path = path,
                .desired_access = FILE_READ_ATTRIBUTES,
                .disposition = FILE_OPEN,
                .create_options = cifs_create_options(cifs_sb, 0),
                .fid = &fid,
        };
 
-       rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL,
+       utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
+       if (utf16_path == NULL)
+               return -ENOMEM;
+
+       rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL,
                       NULL, NULL);
+       kfree(utf16_path);
        if (rc)
                return rc;