Skip to content

Commit

Permalink
ksmbd: fix missing use of get_write in in smb2_set_ea()
Browse files Browse the repository at this point in the history
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: [email protected]
Reported-by: Wang Zhaolong <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
  • Loading branch information
namjaejeon committed Jun 11, 2024
1 parent 2a37651 commit 60cc446
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 14 deletions.
9 changes: 5 additions & 4 deletions smb2pdu.c
Original file line number Diff line number Diff line change
Expand Up @@ -2397,7 +2397,8 @@ static int smb2_set_ea(struct smb2_ea_info *eabuf, unsigned int buf_len,
rc = ksmbd_vfs_remove_xattr(user_ns,
#endif
path,
attr_name);
attr_name,
get_write);

if (rc < 0) {
ksmbd_debug(SMB,
Expand All @@ -2417,7 +2418,7 @@ static int smb2_set_ea(struct smb2_ea_info *eabuf, unsigned int buf_len,
#endif
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",
Expand Down Expand Up @@ -2526,9 +2527,9 @@ static int smb2_remove_smb_xattrs(const struct path *path)
!strncmp(&name[XATTR_USER_PREFIX_LEN], STREAM_PREFIX,
STREAM_PREFIX_LEN)) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0)
err = ksmbd_vfs_remove_xattr(idmap, path, name);
err = ksmbd_vfs_remove_xattr(idmap, path, name, true);
#else
err = ksmbd_vfs_remove_xattr(user_ns, path, name);
err = ksmbd_vfs_remove_xattr(user_ns, path, name, true);
#endif
if (err)
ksmbd_debug(SMB, "remove xattr failed : %s\n",
Expand Down
20 changes: 12 additions & 8 deletions vfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -2017,7 +2017,7 @@ int ksmbd_vfs_remove_acl_xattrs(struct user_namespace *user_ns,
err = vfs_remove_acl(user_ns, path->dentry, name);
#endif
#else
err = ksmbd_vfs_remove_xattr(user_ns, path, name);
err = ksmbd_vfs_remove_xattr(user_ns, path, name, false);
#endif
if (err)
ksmbd_debug(SMB,
Expand Down Expand Up @@ -2055,9 +2055,9 @@ int ksmbd_vfs_remove_sd_xattrs(struct user_namespace *user_ns,

if (!strncmp(name, XATTR_NAME_SD, XATTR_NAME_SD_LEN)) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0)
err = ksmbd_vfs_remove_xattr(idmap, path, name);
err = ksmbd_vfs_remove_xattr(idmap, path, name, true);
#else
err = ksmbd_vfs_remove_xattr(user_ns, path, name);
err = ksmbd_vfs_remove_xattr(user_ns, path, name, true);
#endif
if (err)
ksmbd_debug(SMB, "remove xattr failed : %s\n", name);
Expand Down Expand Up @@ -2502,13 +2502,16 @@ int ksmbd_vfs_remove_xattr(struct mnt_idmap *idmap,
#else
int ksmbd_vfs_remove_xattr(struct user_namespace *user_ns,
#endif
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;
}

#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0)
Expand All @@ -2519,7 +2522,8 @@ int ksmbd_vfs_remove_xattr(struct user_namespace *user_ns,
#else
err = vfs_removexattr(path->dentry, attr_name);
#endif
mnt_drop_write(path->mnt);
if (get_write == true)
mnt_drop_write(path->mnt);

return err;
}
Expand Down
3 changes: 2 additions & 1 deletion vfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,8 @@ int ksmbd_vfs_remove_xattr(struct mnt_idmap *idmap,
#else
int ksmbd_vfs_remove_xattr(struct user_namespace *user_ns,
#endif
const struct path *path, char *attr_name);
const struct path *path, char *attr_name,
bool get_write);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0)
int ksmbd_vfs_kern_path_locked(struct ksmbd_work *work, char *name,
unsigned int flags, struct path *parent_path,
Expand Down
3 changes: 2 additions & 1 deletion vfs_cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,8 @@ static void __ksmbd_inode_close(struct ksmbd_file *fp)
err = ksmbd_vfs_remove_xattr(file_mnt_user_ns(filp),
#endif
&filp->f_path,
fp->stream.name);
fp->stream.name,
true);
if (err)
pr_err("remove xattr failed : %s\n",
fp->stream.name);
Expand Down

0 comments on commit 60cc446

Please sign in to comment.