]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
smb: client: fix chmod(2) regression with ATTR_READONLY
authorPaulo Alcantara <pc@manguebit.com>
Sun, 16 Feb 2025 21:02:47 +0000 (18:02 -0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 27 Feb 2025 12:34:20 +0000 (04:34 -0800)
commit 654292a0b264e9b8c51b98394146218a21612aa1 upstream.

When the user sets a file or directory as read-only (e.g. ~S_IWUGO),
the client will set the ATTR_READONLY attribute by sending an
SMB2_SET_INFO request to the server in cifs_setattr_{,nounix}(), but
cifsInodeInfo::cifsAttrs will be left unchanged as the client will
only update the new file attributes in the next call to
{smb311_posix,cifs}_get_inode_info() with the new metadata filled in
@data parameter.

Commit a18280e7fdea ("smb: cilent: set reparse mount points as
automounts") mistakenly removed the @data NULL check when calling
is_inode_cache_good(), which broke the above case as the new
ATTR_READONLY attribute would end up not being updated on files with a
read lease.

Fix this by updating the inode whenever we have cached metadata in
@data parameter.

Reported-by: Horst Reiterer <horst.reiterer@fabasoft.com>
Closes: https://lore.kernel.org/r/85a16504e09147a195ac0aac1c801280@fabasoft.com
Fixes: a18280e7fdea ("smb: cilent: set reparse mount points as automounts")
Cc: stable@vger.kernel.org
Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/smb/client/inode.c

index f146e06c97eb694c18646590fd695c9f9cc6b244..0d149b315a832eefa68e6ee6ed69d103d2c893c3 100644 (file)
@@ -1403,7 +1403,7 @@ int cifs_get_inode_info(struct inode **inode,
        struct cifs_fattr fattr = {};
        int rc;
 
-       if (is_inode_cache_good(*inode)) {
+       if (!data && is_inode_cache_good(*inode)) {
                cifs_dbg(FYI, "No need to revalidate cached inode sizes\n");
                return 0;
        }
@@ -1502,7 +1502,7 @@ int smb311_posix_get_inode_info(struct inode **inode,
        struct cifs_fattr fattr = {};
        int rc;
 
-       if (is_inode_cache_good(*inode)) {
+       if (!data && is_inode_cache_good(*inode)) {
                cifs_dbg(FYI, "No need to revalidate cached inode sizes\n");
                return 0;
        }