]> www.infradead.org Git - users/willy/pagecache.git/commitdiff
ksmbd: fix missing use of get_write in in smb2_set_ea()
authorNamjae Jeon <linkinjeon@kernel.org>
Tue, 11 Jun 2024 14:27:27 +0000 (23:27 +0900)
committerSteve French <stfrench@microsoft.com>
Wed, 12 Jun 2024 04:43:09 +0000 (23:43 -0500)
Fix an issue where get_write is not used in smb2_set_ea().

Fixes: 6fc0a265e1b9 ("ksmbd: fix potential circular locking issue in smb2_set_ea()")
Cc: stable@vger.kernel.org
Reported-by: Wang Zhaolong <wangzhaolong1@huawei.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/server/smb2pdu.c
fs/smb/server/vfs.c
fs/smb/server/vfs.h
fs/smb/server/vfs_cache.c

index f79d06d2d655cfecfcc8c49aaf33f828b0cad29f..e7e07891781b36a21db07ef3160de4300e969261 100644 (file)
@@ -2367,7 +2367,8 @@ static int smb2_set_ea(struct smb2_ea_info *eabuf, unsigned int buf_len,
                        if (rc > 0) {
                                rc = ksmbd_vfs_remove_xattr(idmap,
                                                            path,
-                                                           attr_name);
+                                                           attr_name,
+                                                           get_write);
 
                                if (rc < 0) {
                                        ksmbd_debug(SMB,
@@ -2382,7 +2383,7 @@ static int smb2_set_ea(struct smb2_ea_info *eabuf, unsigned int buf_len,
                } else {
                        rc = ksmbd_vfs_setxattr(idmap, path, attr_name, value,
                                                le16_to_cpu(eabuf->EaValueLength),
-                                               0, true);
+                                               0, get_write);
                        if (rc < 0) {
                                ksmbd_debug(SMB,
                                            "ksmbd_vfs_setxattr is failed(%d)\n",
@@ -2474,7 +2475,7 @@ static int smb2_remove_smb_xattrs(const struct path *path)
                    !strncmp(&name[XATTR_USER_PREFIX_LEN], STREAM_PREFIX,
                             STREAM_PREFIX_LEN)) {
                        err = ksmbd_vfs_remove_xattr(idmap, path,
-                                                    name);
+                                                    name, true);
                        if (err)
                                ksmbd_debug(SMB, "remove xattr failed : %s\n",
                                            name);
index 51b1b0bed616eea98a19e5e470f6aa929c8884b5..9e859ba010cf12ad3263c4cbf29accf6379567a1 100644 (file)
@@ -1058,16 +1058,21 @@ int ksmbd_vfs_fqar_lseek(struct ksmbd_file *fp, loff_t start, loff_t length,
 }
 
 int ksmbd_vfs_remove_xattr(struct mnt_idmap *idmap,
-                          const struct path *path, char *attr_name)
+                          const struct path *path, char *attr_name,
+                          bool get_write)
 {
        int err;
 
-       err = mnt_want_write(path->mnt);
-       if (err)
-               return err;
+       if (get_write == true) {
+               err = mnt_want_write(path->mnt);
+               if (err)
+                       return err;
+       }
 
        err = vfs_removexattr(idmap, path->dentry, attr_name);
-       mnt_drop_write(path->mnt);
+
+       if (get_write == true)
+               mnt_drop_write(path->mnt);
 
        return err;
 }
@@ -1380,7 +1385,7 @@ int ksmbd_vfs_remove_sd_xattrs(struct mnt_idmap *idmap, const struct path *path)
                ksmbd_debug(SMB, "%s, len %zd\n", name, strlen(name));
 
                if (!strncmp(name, XATTR_NAME_SD, XATTR_NAME_SD_LEN)) {
-                       err = ksmbd_vfs_remove_xattr(idmap, path, name);
+                       err = ksmbd_vfs_remove_xattr(idmap, path, name, true);
                        if (err)
                                ksmbd_debug(SMB, "remove xattr failed : %s\n", name);
                }
index cfe1c8092f2302f2cd0ea7cf5b42f1357160981f..cb76f4b5bafe8c15e6c0fd621b209ed4c63402a4 100644 (file)
@@ -114,7 +114,8 @@ int ksmbd_vfs_setxattr(struct mnt_idmap *idmap,
 int ksmbd_vfs_xattr_stream_name(char *stream_name, char **xattr_stream_name,
                                size_t *xattr_stream_name_size, int s_type);
 int ksmbd_vfs_remove_xattr(struct mnt_idmap *idmap,
-                          const struct path *path, char *attr_name);
+                          const struct path *path, char *attr_name,
+                          bool get_write);
 int ksmbd_vfs_kern_path_locked(struct ksmbd_work *work, char *name,
                               unsigned int flags, struct path *parent_path,
                               struct path *path, bool caseless);
index 6cb599cd287ee44153a8278d40fbcbd8d2f49cb7..8b2e37c8716ed70e3805ea2c309eef15a941c33e 100644 (file)
@@ -254,7 +254,8 @@ static void __ksmbd_inode_close(struct ksmbd_file *fp)
                ci->m_flags &= ~S_DEL_ON_CLS_STREAM;
                err = ksmbd_vfs_remove_xattr(file_mnt_idmap(filp),
                                             &filp->f_path,
-                                            fp->stream.name);
+                                            fp->stream.name,
+                                            true);
                if (err)
                        pr_err("remove xattr failed : %s\n",
                               fp->stream.name);