From: Hyunchul Lee hyc.lee@gmail.com
mainline inclusion from mainline-5.15-rc1 commit ef24c962d0f29036041a007a75bcd0f50233c83e category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I60T7G CVE: NA
Reference: https://git.kernel.org/torvalds/linux/c/ef24c962d0f2
-------------------------------
For user namespace support, we need to pass struct user_namespace with struct dentry to some functions. For reducing the number of arguments, replace the struct dentry with struct path in these functions.
Reviewed-by: Christoph Hellwig hch@lst.de Signed-off-by: Hyunchul Lee hyc.lee@gmail.com Signed-off-by: Namjae Jeon namjae.jeon@samsung.com Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Jason Yan yanaijie@huawei.com Signed-off-by: Zhong Jinghua zhongjinghua@huawei.com --- fs/ksmbd/smb2pdu.c | 21 +++++++++++---------- fs/ksmbd/smbacl.c | 25 +++++++++++++------------ fs/ksmbd/smbacl.h | 6 +++--- 3 files changed, 27 insertions(+), 25 deletions(-)
diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c index bf798ee65b25..d79ea3eb57a7 100644 --- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -2172,13 +2172,13 @@ static noinline int smb2_set_stream_name_xattr(struct path *path, return 0; }
-static int smb2_remove_smb_xattrs(struct dentry *dentry) +static int smb2_remove_smb_xattrs(struct path *path) { char *name, *xattr_list = NULL; ssize_t xattr_list_len; int err = 0;
- xattr_list_len = ksmbd_vfs_listxattr(dentry, &xattr_list); + xattr_list_len = ksmbd_vfs_listxattr(path->dentry, &xattr_list); if (xattr_list_len < 0) { goto out; } else if (!xattr_list_len) { @@ -2196,7 +2196,7 @@ static int smb2_remove_smb_xattrs(struct dentry *dentry) strncmp(&name[XATTR_USER_PREFIX_LEN], STREAM_PREFIX, STREAM_PREFIX_LEN)) continue;
- err = ksmbd_vfs_remove_xattr(dentry, name); + err = ksmbd_vfs_remove_xattr(path->dentry, name); if (err) ksmbd_debug(SMB, "remove xattr failed : %s\n", name); } @@ -2214,7 +2214,7 @@ static int smb2_create_truncate(struct path *path) return rc; }
- rc = smb2_remove_smb_xattrs(path->dentry); + rc = smb2_remove_smb_xattrs(path); if (rc == -EOPNOTSUPP) rc = 0; if (rc) @@ -2305,7 +2305,7 @@ static int smb2_creat(struct ksmbd_work *work, struct path *path, char *name,
static int smb2_create_sd_buffer(struct ksmbd_work *work, struct smb2_create_req *req, - struct dentry *dentry) + struct path *path) { struct create_context *context; int rc = -ENOENT; @@ -2321,7 +2321,8 @@ static int smb2_create_sd_buffer(struct ksmbd_work *work, ksmbd_debug(SMB, "Set ACLs using SMB2_CREATE_SD_BUFFER context\n"); sd_buf = (struct create_sd_buf_req *)context; - rc = set_info_sec(work->conn, work->tcon, dentry, &sd_buf->ntsd, + rc = set_info_sec(work->conn, work->tcon, + path, &sd_buf->ntsd, le32_to_cpu(sd_buf->ccontext.DataLength), true); }
@@ -2684,7 +2685,7 @@ int smb2_open(struct ksmbd_work *work) daccess = smb_map_generic_desired_access(req->DesiredAccess);
if (file_present && !(req->CreateOptions & FILE_DELETE_ON_CLOSE_LE)) { - rc = smb_check_perm_dacl(conn, path.dentry, &daccess, + rc = smb_check_perm_dacl(conn, &path, &daccess, sess->user->uid); if (rc) goto err_out; @@ -2814,12 +2815,12 @@ int smb2_open(struct ksmbd_work *work)
if (test_share_config_flag(work->tcon->share_conf, KSMBD_SHARE_FLAG_ACL_XATTR)) { - rc = smb_inherit_dacl(conn, path.dentry, sess->user->uid, + rc = smb_inherit_dacl(conn, &path, sess->user->uid, sess->user->gid); }
if (rc) { - rc = smb2_create_sd_buffer(work, req, path.dentry); + rc = smb2_create_sd_buffer(work, req, &path); if (rc) { if (posix_acl_rc) ksmbd_vfs_set_init_posix_acl(inode); @@ -5719,7 +5720,7 @@ static int smb2_set_info_sec(struct ksmbd_file *fp, int addition_info,
fp->saccess |= FILE_SHARE_DELETE_LE;
- return set_info_sec(fp->conn, fp->tcon, fp->filp->f_path.dentry, pntsd, + return set_info_sec(fp->conn, fp->tcon, &fp->filp->f_path, pntsd, buf_len, false); }
diff --git a/fs/ksmbd/smbacl.c b/fs/ksmbd/smbacl.c index d385c7045cc0..e0825d3771a1 100644 --- a/fs/ksmbd/smbacl.c +++ b/fs/ksmbd/smbacl.c @@ -941,7 +941,8 @@ static void smb_set_ace(struct smb_ace *ace, const struct smb_sid *sid, u8 type, ace->size = cpu_to_le16(1 + 1 + 2 + 4 + 1 + 1 + 6 + (sid->num_subauth * 4)); }
-int smb_inherit_dacl(struct ksmbd_conn *conn, struct dentry *dentry, +int smb_inherit_dacl(struct ksmbd_conn *conn, + struct path *path, unsigned int uid, unsigned int gid) { const struct smb_sid *psid, *creator = NULL; @@ -949,11 +950,11 @@ int smb_inherit_dacl(struct ksmbd_conn *conn, struct dentry *dentry, struct smb_acl *parent_pdacl; struct smb_ntsd *parent_pntsd = NULL; struct smb_sid owner_sid, group_sid; - struct dentry *parent = dentry->d_parent; + struct dentry *parent = path->dentry->d_parent; int inherited_flags = 0, flags = 0, i, ace_cnt = 0, nt_size = 0; int rc = -ENOENT, num_aces, dacloffset, pntsd_type, acl_len; char *aces_base; - bool is_dir = S_ISDIR(d_inode(dentry)->i_mode); + bool is_dir = S_ISDIR(d_inode(path->dentry)->i_mode);
acl_len = ksmbd_vfs_get_sd_xattr(conn, parent, &parent_pntsd); if (acl_len <= 0) @@ -1086,7 +1087,7 @@ int smb_inherit_dacl(struct ksmbd_conn *conn, struct dentry *dentry, pntsd_size += sizeof(struct smb_acl) + nt_size; }
- ksmbd_vfs_set_sd_xattr(conn, dentry, pntsd, pntsd_size); + ksmbd_vfs_set_sd_xattr(conn, path->dentry, pntsd, pntsd_size); kfree(pntsd); rc = 0; } @@ -1109,7 +1110,7 @@ bool smb_inherit_flags(int flags, bool is_dir) return false; }
-int smb_check_perm_dacl(struct ksmbd_conn *conn, struct dentry *dentry, +int smb_check_perm_dacl(struct ksmbd_conn *conn, struct path *path, __le32 *pdaccess, int uid) { struct smb_ntsd *pntsd = NULL; @@ -1127,7 +1128,7 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, struct dentry *dentry, char *end_of_acl;
ksmbd_debug(SMB, "check permission using windows acl\n"); - acl_size = ksmbd_vfs_get_sd_xattr(conn, dentry, &pntsd); + acl_size = ksmbd_vfs_get_sd_xattr(conn, path->dentry, &pntsd); if (acl_size <= 0 || !pntsd || !pntsd->dacloffset) { kfree(pntsd); return 0; @@ -1201,7 +1202,7 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, struct dentry *dentry, granted = GENERIC_ALL_FLAGS; }
- posix_acls = get_acl(d_inode(dentry), ACL_TYPE_ACCESS); + posix_acls = get_acl(d_inode(path->dentry), ACL_TYPE_ACCESS); if (posix_acls && !found) { unsigned int id = -1;
@@ -1261,12 +1262,12 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, struct dentry *dentry, }
int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon, - struct dentry *dentry, struct smb_ntsd *pntsd, int ntsd_len, + struct path *path, struct smb_ntsd *pntsd, int ntsd_len, bool type_check) { int rc; struct smb_fattr fattr = {{0}}; - struct inode *inode = d_inode(dentry); + struct inode *inode = d_inode(path->dentry);
fattr.cf_uid = INVALID_UID; fattr.cf_gid = INVALID_GID; @@ -1283,7 +1284,7 @@ int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon, inode->i_gid = fattr.cf_gid; mark_inode_dirty(inode);
- ksmbd_vfs_remove_acl_xattrs(dentry); + ksmbd_vfs_remove_acl_xattrs(path->dentry); /* Update posix acls */ if (fattr.cf_dacls) { rc = set_posix_acl(&init_user_ns, inode, ACL_TYPE_ACCESS, @@ -1299,8 +1300,8 @@ int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon,
if (test_share_config_flag(tcon->share_conf, KSMBD_SHARE_FLAG_ACL_XATTR)) { /* Update WinACL in xattr */ - ksmbd_vfs_remove_sd_xattrs(dentry); - ksmbd_vfs_set_sd_xattr(conn, dentry, pntsd, ntsd_len); + ksmbd_vfs_remove_sd_xattrs(path->dentry); + ksmbd_vfs_set_sd_xattr(conn, path->dentry, pntsd, ntsd_len); }
out: diff --git a/fs/ksmbd/smbacl.h b/fs/ksmbd/smbacl.h index 3e1345e9f24f..4ee7bda32e5f 100644 --- a/fs/ksmbd/smbacl.h +++ b/fs/ksmbd/smbacl.h @@ -200,12 +200,12 @@ void posix_state_to_acl(struct posix_acl_state *state, struct posix_acl_entry *pace); int compare_sids(const struct smb_sid *ctsid, const struct smb_sid *cwsid); bool smb_inherit_flags(int flags, bool is_dir); -int smb_inherit_dacl(struct ksmbd_conn *conn, struct dentry *dentry, +int smb_inherit_dacl(struct ksmbd_conn *conn, struct path *path, unsigned int uid, unsigned int gid); -int smb_check_perm_dacl(struct ksmbd_conn *conn, struct dentry *dentry, +int smb_check_perm_dacl(struct ksmbd_conn *conn, struct path *path, __le32 *pdaccess, int uid); int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon, - struct dentry *dentry, struct smb_ntsd *pntsd, int ntsd_len, + struct path *path, struct smb_ntsd *pntsd, int ntsd_len, bool type_check); void id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid); void ksmbd_init_domain(u32 *sub_auth);