]> Git Repo - linux.git/commitdiff
smb3: fix incorrect mode displayed for read-only files
authorSteve French <[email protected]>
Sun, 22 Sep 2024 04:28:32 +0000 (23:28 -0500)
committerSteve French <[email protected]>
Wed, 25 Sep 2024 02:51:48 +0000 (21:51 -0500)
Commands like "chmod 0444" mark a file readonly via the attribute flag
(when mapping of mode bits into the ACL are not set, or POSIX extensions
are not negotiated), but they were not reported correctly for stat of
directories (they were reported ok for files and for "ls").  See example
below:

    root:~# ls /mnt2 -l
    total 12
    drwxr-xr-x 2 root root         0 Sep 21 18:03 normaldir
    -rwxr-xr-x 1 root root         0 Sep 21 23:24 normalfile
    dr-xr-xr-x 2 root root         0 Sep 21 17:55 readonly-dir
    -r-xr-xr-x 1 root root 209716224 Sep 21 18:15 readonly-file
    root:~# stat -c %a /mnt2/readonly-dir
    755
    root:~# stat -c %a /mnt2/readonly-file
    555

This fixes the stat of directories when ATTR_READONLY is set
(in cases where the mode can not be obtained other ways).

    root:~# stat -c %a /mnt2/readonly-dir
    555

Cc: [email protected]
Signed-off-by: Steve French <[email protected]>
fs/smb/client/inode.c

index 331a86074ae78ca12c69fcc6448e10e48089ad5a..647f9bedd9fc44c9225f2494c6913a795c2fd6ad 100644 (file)
@@ -834,10 +834,6 @@ static void cifs_open_info_to_fattr(struct cifs_fattr *fattr,
                fattr->cf_mode = S_IFREG | cifs_sb->ctx->file_mode;
                fattr->cf_dtype = DT_REG;
 
-               /* clear write bits if ATTR_READONLY is set */
-               if (fattr->cf_cifsattrs & ATTR_READONLY)
-                       fattr->cf_mode &= ~(S_IWUGO);
-
                /*
                 * Don't accept zero nlink from non-unix servers unless
                 * delete is pending.  Instead mark it as unknown.
@@ -850,6 +846,10 @@ static void cifs_open_info_to_fattr(struct cifs_fattr *fattr,
                }
        }
 
+       /* clear write bits if ATTR_READONLY is set */
+       if (fattr->cf_cifsattrs & ATTR_READONLY)
+               fattr->cf_mode &= ~(S_IWUGO);
+
 out_reparse:
        if (S_ISLNK(fattr->cf_mode)) {
                if (likely(data->symlink_target))
@@ -1267,11 +1267,14 @@ handle_mnt_opt:
                                 __func__, rc);
                        goto out;
                }
-       }
-
-       /* fill in remaining high mode bits e.g. SUID, VTX */
-       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
+       } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
+               /* fill in remaining high mode bits e.g. SUID, VTX */
                cifs_sfu_mode(fattr, full_path, cifs_sb, xid);
+       else if (!(tcon->posix_extensions))
+               /* clear write bits if ATTR_READONLY is set */
+               if (fattr->cf_cifsattrs & ATTR_READONLY)
+                       fattr->cf_mode &= ~(S_IWUGO);
+
 
        /* check for Minshall+French symlinks */
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) {
This page took 0.05607 seconds and 4 git commands to generate.