mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-24 20:54:10 +08:00
ksmbd: fix permission check issue on chown and chmod
When commanding chmod and chown on cifs&ksmbd, ksmbd allows it without file permissions check. There is code to check it in settattr_prepare. Instead of setting the inode directly, update the mode and uid/gid through notify_change. Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com> Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
a9a27d4ab3
commit
e70e392fa7
@ -5861,10 +5861,15 @@ int smb2_set_info(struct ksmbd_work *work)
|
|||||||
break;
|
break;
|
||||||
case SMB2_O_INFO_SECURITY:
|
case SMB2_O_INFO_SECURITY:
|
||||||
ksmbd_debug(SMB, "GOT SMB2_O_INFO_SECURITY\n");
|
ksmbd_debug(SMB, "GOT SMB2_O_INFO_SECURITY\n");
|
||||||
|
if (ksmbd_override_fsids(work)) {
|
||||||
|
rc = -ENOMEM;
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
rc = smb2_set_info_sec(fp,
|
rc = smb2_set_info_sec(fp,
|
||||||
le32_to_cpu(req->AdditionalInformation),
|
le32_to_cpu(req->AdditionalInformation),
|
||||||
req->Buffer,
|
req->Buffer,
|
||||||
le32_to_cpu(req->BufferLength));
|
le32_to_cpu(req->BufferLength));
|
||||||
|
ksmbd_revert_fsids(work);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
rc = -EOPNOTSUPP;
|
rc = -EOPNOTSUPP;
|
||||||
|
@ -1300,6 +1300,7 @@ int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon,
|
|||||||
struct smb_fattr fattr = {{0}};
|
struct smb_fattr fattr = {{0}};
|
||||||
struct inode *inode = d_inode(path->dentry);
|
struct inode *inode = d_inode(path->dentry);
|
||||||
struct user_namespace *user_ns = mnt_user_ns(path->mnt);
|
struct user_namespace *user_ns = mnt_user_ns(path->mnt);
|
||||||
|
struct iattr newattrs;
|
||||||
|
|
||||||
fattr.cf_uid = INVALID_UID;
|
fattr.cf_uid = INVALID_UID;
|
||||||
fattr.cf_gid = INVALID_GID;
|
fattr.cf_gid = INVALID_GID;
|
||||||
@ -1309,12 +1310,23 @@ int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon,
|
|||||||
if (rc)
|
if (rc)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
inode->i_mode = (inode->i_mode & ~0777) | (fattr.cf_mode & 0777);
|
newattrs.ia_valid = ATTR_CTIME;
|
||||||
if (!uid_eq(fattr.cf_uid, INVALID_UID))
|
if (!uid_eq(fattr.cf_uid, INVALID_UID)) {
|
||||||
inode->i_uid = fattr.cf_uid;
|
newattrs.ia_valid |= ATTR_UID;
|
||||||
if (!gid_eq(fattr.cf_gid, INVALID_GID))
|
newattrs.ia_uid = fattr.cf_uid;
|
||||||
inode->i_gid = fattr.cf_gid;
|
}
|
||||||
mark_inode_dirty(inode);
|
if (!gid_eq(fattr.cf_gid, INVALID_GID)) {
|
||||||
|
newattrs.ia_valid |= ATTR_GID;
|
||||||
|
newattrs.ia_gid = fattr.cf_gid;
|
||||||
|
}
|
||||||
|
newattrs.ia_valid |= ATTR_MODE;
|
||||||
|
newattrs.ia_mode = (inode->i_mode & ~0777) | (fattr.cf_mode & 0777);
|
||||||
|
|
||||||
|
inode_lock(inode);
|
||||||
|
rc = notify_change(user_ns, path->dentry, &newattrs, NULL);
|
||||||
|
inode_unlock(inode);
|
||||||
|
if (rc)
|
||||||
|
goto out;
|
||||||
|
|
||||||
ksmbd_vfs_remove_acl_xattrs(user_ns, path->dentry);
|
ksmbd_vfs_remove_acl_xattrs(user_ns, path->dentry);
|
||||||
/* Update posix acls */
|
/* Update posix acls */
|
||||||
|
Loading…
Reference in New Issue
Block a user