vfs_setxattr(), vfs_getxattr(), vfs_listxattr() and vfs_removexattr() along with their __vfs_setxattr_locked()/__vfs_removexattr_locked() counterparts and the do_setxattr()/do_getxattr()/listxattr()/ removexattr() syscall helpers take a struct mnt_idmap and a struct dentry even though callers either already hold a struct path (or a struct file) or have to pass &nop_mnt_idmap because no idmapped mount is involved. Switch them all to take a struct path instead and derive the idmap and dentry from it where needed.
__vfs_setxattr_noperm(), __vfs_getxattr(), __vfs_setxattr(), __vfs_removexattr() and vfs_getxattr_alloc() keep taking the idmap and dentry as they are only called from contexts that operate on bare dentries such as LSM internals. The SELinux and Smack inode_setsecctx implementations now pass the path they got from the previous patch straight through. The security_inode_*xattr() hooks invoked from fs/xattr.c keep taking the idmap and dentry for now; they will be converted together with the LSM hooks themselves in separate patches. evm_calc_hmac_or_hash() contains a redundant xattr size sanity check which calls vfs_getxattr() only to emit a debug message when the kernel-side and user-space-side xattr sizes differ, without ever influencing the result. Because that function only has a dentry, the call cannot be migrated to the new path-based signature; drop the check and the now unused user_space_size variable instead. Assisted-by: opencode: glm-5.3 Signed-off-by: Cai Xinchen <[email protected]> --- drivers/block/zloop.c | 4 +- fs/cachefiles/xattr.c | 32 ++++---- fs/ecryptfs/inode.c | 8 +- fs/nfsd/nfs4ctl.h | 4 +- fs/nfsd/vfs.c | 57 +++++++------- fs/overlayfs/copy_up.c | 4 +- fs/overlayfs/overlayfs.h | 18 +++-- fs/overlayfs/xattrs.c | 13 +++- fs/smb/server/smb2pdu.c | 75 +++++++------------ fs/smb/server/smb_common.c | 2 - fs/smb/server/smbacl.c | 19 +++-- fs/smb/server/tests/smbacl_kunit.c | 6 +- fs/smb/server/vfs.c | 112 ++++++++++++---------------- fs/smb/server/vfs.h | 39 ++++------ fs/smb/server/vfs_cache.c | 3 +- fs/xattr.c | 92 ++++++++++++----------- include/linux/xattr.h | 22 +++--- security/integrity/evm/evm_crypto.c | 8 +- security/selinux/hooks.c | 4 +- security/smack/smack_lsm.c | 4 +- 20 files changed, 243 insertions(+), 283 deletions(-) diff --git a/drivers/block/zloop.c b/drivers/block/zloop.c index f0ca221524db..d77b114d69fc 100644 --- a/drivers/block/zloop.c +++ b/drivers/block/zloop.c @@ -710,7 +710,7 @@ static int zloop_record_safe_wps(struct zloop_device *zlo) if (!zloop_zone_is_active(zone)) continue; - ret = vfs_setxattr(file_mnt_idmap(file), file_dentry(file), + ret = vfs_setxattr(&file->f_path, "user.zloop.wp", &zone->wp, sizeof(zone->wp), 0); if (ret) { pr_err("%pg: failed to record write pointer (%d)\n", @@ -1395,7 +1395,7 @@ static void zloop_forget_cache(struct zloop_device *zlo) if (!zloop_zone_is_active(zone)) continue; - ret = vfs_getxattr(file_mnt_idmap(file), file_dentry(file), + ret = vfs_getxattr(&file->f_path, "user.zloop.wp", &old_wp, sizeof(old_wp)); if (ret == -ENODATA) { old_wp = 0; diff --git a/fs/cachefiles/xattr.c b/fs/cachefiles/xattr.c index c70bf67e52b0..5a0b50bcfb73 100644 --- a/fs/cachefiles/xattr.c +++ b/fs/cachefiles/xattr.c @@ -40,14 +40,12 @@ struct cachefiles_vol_xattr { int cachefiles_set_object_xattr(struct cachefiles_object *object) { struct cachefiles_xattr *buf; - struct dentry *dentry; struct file *file = object->file; unsigned int len = object->cookie->aux_len; int ret; if (!file) return -ESTALE; - dentry = file->f_path.dentry; _enter("%x,#%d", object->debug_id, len); @@ -69,7 +67,7 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object) if (ret == 0) { ret = mnt_want_write_file(file); if (ret == 0) { - ret = vfs_setxattr(&nop_mnt_idmap, dentry, + ret = vfs_setxattr(&file->f_path, cachefiles_xattr_cache, buf, sizeof(struct cachefiles_xattr) + len, 0); mnt_drop_write_file(file); @@ -102,7 +100,6 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object) int cachefiles_check_auxdata(struct cachefiles_object *object, struct file *file) { struct cachefiles_xattr *buf; - struct dentry *dentry = file->f_path.dentry; unsigned int len = object->cookie->aux_len, tlen; const void *p = fscache_get_aux(object->cookie); enum cachefiles_coherency_trace why; @@ -117,7 +114,7 @@ int cachefiles_check_auxdata(struct cachefiles_object *object, struct file *file xlen = cachefiles_inject_read_error(); if (xlen == 0) - xlen = vfs_getxattr(&nop_mnt_idmap, dentry, cachefiles_xattr_cache, buf, tlen); + xlen = vfs_getxattr(&file->f_path, cachefiles_xattr_cache, buf, tlen); if (xlen != tlen) { if (xlen < 0) { ret = xlen; @@ -161,14 +158,14 @@ int cachefiles_remove_object_xattr(struct cachefiles_cache *cache, struct cachefiles_object *object, struct dentry *dentry) { + struct path path = { .mnt = cache->mnt, .dentry = dentry }; int ret; ret = cachefiles_inject_remove_error(); if (ret == 0) { ret = mnt_want_write(cache->mnt); if (ret == 0) { - ret = vfs_removexattr(&nop_mnt_idmap, dentry, - cachefiles_xattr_cache); + ret = vfs_removexattr(&path, cachefiles_xattr_cache); mnt_drop_write(cache->mnt); } } @@ -214,7 +211,8 @@ bool cachefiles_set_volume_xattr(struct cachefiles_volume *volume) struct cachefiles_vol_xattr *buf; unsigned int len = volume->vcookie->coherency_len; const void *p = volume->vcookie->coherency; - struct dentry *dentry = volume->dentry; + struct path path = { .mnt = volume->cache->mnt, + .dentry = volume->dentry }; int ret; _enter("%x,#%d", volume->vcookie->debug_id, len); @@ -230,22 +228,21 @@ bool cachefiles_set_volume_xattr(struct cachefiles_volume *volume) if (ret == 0) { ret = mnt_want_write(volume->cache->mnt); if (ret == 0) { - ret = vfs_setxattr(&nop_mnt_idmap, dentry, - cachefiles_xattr_cache, + ret = vfs_setxattr(&path, cachefiles_xattr_cache, buf, len, 0); mnt_drop_write(volume->cache->mnt); } } if (ret < 0) { - trace_cachefiles_vfs_error(NULL, d_inode(dentry), ret, + trace_cachefiles_vfs_error(NULL, d_inode(path.dentry), ret, cachefiles_trace_setxattr_error); - trace_cachefiles_vol_coherency(volume, d_inode(dentry)->i_ino, + trace_cachefiles_vol_coherency(volume, d_inode(path.dentry)->i_ino, cachefiles_coherency_vol_set_fail); if (ret != -ENOMEM) cachefiles_io_error( volume->cache, "Failed to set xattr with error %d", ret); } else { - trace_cachefiles_vol_coherency(volume, d_inode(dentry)->i_ino, + trace_cachefiles_vol_coherency(volume, d_inode(path.dentry)->i_ino, cachefiles_coherency_vol_set_ok); } @@ -260,9 +257,10 @@ bool cachefiles_set_volume_xattr(struct cachefiles_volume *volume) int cachefiles_check_volume_xattr(struct cachefiles_volume *volume) { struct cachefiles_vol_xattr *buf; - struct dentry *dentry = volume->dentry; unsigned int len = volume->vcookie->coherency_len; const void *p = volume->vcookie->coherency; + struct path path = { .mnt = volume->cache->mnt, + .dentry = volume->dentry }; enum cachefiles_coherency_trace why; ssize_t xlen; int ret = -ESTALE; @@ -276,11 +274,11 @@ int cachefiles_check_volume_xattr(struct cachefiles_volume *volume) xlen = cachefiles_inject_read_error(); if (xlen == 0) - xlen = vfs_getxattr(&nop_mnt_idmap, dentry, cachefiles_xattr_cache, buf, len); + xlen = vfs_getxattr(&path, cachefiles_xattr_cache, buf, len); if (xlen != len) { if (xlen < 0) { ret = xlen; - trace_cachefiles_vfs_error(NULL, d_inode(dentry), xlen, + trace_cachefiles_vfs_error(NULL, d_inode(path.dentry), xlen, cachefiles_trace_getxattr_error); if (xlen == -EIO) cachefiles_io_error( @@ -297,7 +295,7 @@ int cachefiles_check_volume_xattr(struct cachefiles_volume *volume) ret = 0; } - trace_cachefiles_vol_coherency(volume, d_inode(dentry)->i_ino, why); + trace_cachefiles_vol_coherency(volume, d_inode(path.dentry)->i_ino, why); kfree(buf); _leave(" = %d", ret); return ret; diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 627d456f9c38..3307cf13b5b4 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -991,17 +991,17 @@ ecryptfs_setxattr(struct dentry *dentry, struct inode *inode, size_t size, int flags) { int rc; - struct dentry *lower_dentry; + struct path lower_path; struct inode *lower_inode; - lower_dentry = ecryptfs_dentry_to_lower(dentry); - lower_inode = d_inode(lower_dentry); + lower_path = ecryptfs_lower_path(dentry); + lower_inode = d_inode(lower_path.dentry); if (!(lower_inode->i_opflags & IOP_XATTR)) { rc = -EOPNOTSUPP; goto out; } inode_lock(lower_inode); - rc = __vfs_setxattr_locked(&nop_mnt_idmap, lower_dentry, name, value, size, flags, NULL); + rc = __vfs_setxattr_locked(&lower_path, name, value, size, flags, NULL); inode_unlock(lower_inode); if (!rc && inode) fsstack_copy_attr_all(inode, lower_inode); diff --git a/fs/nfsd/nfs4ctl.h b/fs/nfsd/nfs4ctl.h index bcec4c4ef1d5..97ab3d4212aa 100644 --- a/fs/nfsd/nfs4ctl.h +++ b/fs/nfsd/nfs4ctl.h @@ -38,7 +38,7 @@ int nfsd4_create_laundry_wq(void); void nfsd4_destroy_laundry_wq(void); bool nfsd_wait_for_delegreturn(struct svc_rqst *rqstp, struct inode *inode); -extern int nfsd4_is_junction(struct dentry *dentry); +extern int nfsd4_is_junction(const struct path *path); extern int register_cld_notifier(void); extern void unregister_cld_notifier(void); #ifdef CONFIG_NFSD_V4_2_INTER_SSC @@ -68,7 +68,7 @@ static inline bool nfsd_wait_for_delegreturn(struct svc_rqst *rqstp, return false; } -static inline int nfsd4_is_junction(struct dentry *dentry) +static inline int nfsd4_is_junction(const struct path *path) { return 0; } diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 922337083fe9..a3b86fa60dca 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -233,11 +233,13 @@ static int nfsd_lookup_parent(struct svc_rqst *rqstp, struct dentry *dparent, st */ int nfsd_mountpoint(struct dentry *dentry, struct svc_export *exp) { + struct path path = { .mnt = exp->ex_path.mnt, .dentry = dentry }; + if (!d_inode(dentry)) return 0; if (exp->ex_flags & NFSEXP_V4ROOT) return 1; - if (nfsd4_is_junction(dentry)) + if (nfsd4_is_junction(&path)) return 1; if (d_managed(dentry)) /* @@ -684,14 +686,14 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, /** * nfsd4_is_junction - Test if an object could be an NFS junction * - * @dentry: object to test + * @path: object to test * - * Returns 1 if "dentry" appears to contain NFS junction information. + * Returns 1 if "path" appears to contain NFS junction information. * Otherwise 0 is returned. */ -int nfsd4_is_junction(struct dentry *dentry) +int nfsd4_is_junction(const struct path *path) { - struct inode *inode = d_inode(dentry); + struct inode *inode = d_inode(path->dentry); if (inode == NULL) return 0; @@ -699,8 +701,7 @@ int nfsd4_is_junction(struct dentry *dentry) return 0; if (!(inode->i_mode & S_ISVTX)) return 0; - if (vfs_getxattr(&nop_mnt_idmap, dentry, NFSD_JUNCTION_XATTR_NAME, - NULL, 0) <= 0) + if (vfs_getxattr(path, NFSD_JUNCTION_XATTR_NAME, NULL, 0) <= 0) return 0; return 1; } @@ -2619,19 +2620,20 @@ nfsd_getxattr(struct svc_rqst *rqstp, struct svc_fh *fhp, char *name, __be32 err; char *buf; struct inode *inode; - struct dentry *dentry; + struct path path; err = fh_verify(rqstp, fhp, 0, NFSD_MAY_READ); if (err) return err; err = nfs_ok; - dentry = fhp->fh_dentry; - inode = d_inode(dentry); + path.mnt = fhp->fh_export->ex_path.mnt; + path.dentry = fhp->fh_dentry; + inode = d_inode(path.dentry); inode_lock_shared(inode); - len = vfs_getxattr(&nop_mnt_idmap, dentry, name, NULL, 0); + len = vfs_getxattr(&path, name, NULL, 0); /* * Zero-length attribute, just return. @@ -2658,7 +2660,7 @@ nfsd_getxattr(struct svc_rqst *rqstp, struct svc_fh *fhp, char *name, goto out; } - len = vfs_getxattr(&nop_mnt_idmap, dentry, name, buf, len); + len = vfs_getxattr(&path, name, buf, len); if (len <= 0) { kvfree(buf); buf = NULL; @@ -2692,19 +2694,20 @@ nfsd_listxattr(struct svc_rqst *rqstp, struct svc_fh *fhp, char **bufp, __be32 err; char *buf; struct inode *inode; - struct dentry *dentry; + struct path path; err = fh_verify(rqstp, fhp, 0, NFSD_MAY_READ); if (err) return err; - dentry = fhp->fh_dentry; - inode = d_inode(dentry); + path.mnt = fhp->fh_export->ex_path.mnt; + path.dentry = fhp->fh_dentry; + inode = d_inode(path.dentry); *lenp = 0; inode_lock_shared(inode); - len = vfs_listxattr(dentry, NULL, 0); + len = vfs_listxattr(&path, NULL, 0); if (len <= 0) { err = nfsd_xattr_errno(len); goto out; @@ -2721,7 +2724,7 @@ nfsd_listxattr(struct svc_rqst *rqstp, struct svc_fh *fhp, char **bufp, goto out; } - len = vfs_listxattr(dentry, buf, len); + len = vfs_listxattr(&path, buf, len); if (len <= 0) { kvfree(buf); err = nfsd_xattr_errno(len); @@ -2754,6 +2757,7 @@ nfsd_removexattr(struct svc_rqst *rqstp, struct svc_fh *fhp, char *name) { __be32 err; int ret; + struct path path; err = fh_verify(rqstp, fhp, 0, NFSD_MAY_WRITE); if (err) @@ -2763,16 +2767,17 @@ nfsd_removexattr(struct svc_rqst *rqstp, struct svc_fh *fhp, char *name) if (ret) return nfserrno(ret); - inode_lock(fhp->fh_dentry->d_inode); + path.mnt = fhp->fh_export->ex_path.mnt; + path.dentry = fhp->fh_dentry; + inode_lock(d_inode(path.dentry)); err = fh_fill_pre_attrs(fhp); if (err != nfs_ok) goto out_unlock; - ret = __vfs_removexattr_locked(&nop_mnt_idmap, fhp->fh_dentry, - name, NULL); + ret = __vfs_removexattr_locked(&path, name, NULL); err = nfsd_xattr_errno(ret); fh_fill_post_attrs(fhp); out_unlock: - inode_unlock(fhp->fh_dentry->d_inode); + inode_unlock(d_inode(path.dentry)); fh_drop_write(fhp); return err; @@ -2784,6 +2789,7 @@ nfsd_setxattr(struct svc_rqst *rqstp, struct svc_fh *fhp, char *name, { __be32 err; int ret; + struct path path; err = fh_verify(rqstp, fhp, 0, NFSD_MAY_WRITE); if (err) @@ -2792,16 +2798,17 @@ nfsd_setxattr(struct svc_rqst *rqstp, struct svc_fh *fhp, char *name, ret = fh_want_write(fhp); if (ret) return nfserrno(ret); - inode_lock(fhp->fh_dentry->d_inode); + path.mnt = fhp->fh_export->ex_path.mnt; + path.dentry = fhp->fh_dentry; + inode_lock(d_inode(path.dentry)); err = fh_fill_pre_attrs(fhp); if (err != nfs_ok) goto out_unlock; - ret = __vfs_setxattr_locked(&nop_mnt_idmap, fhp->fh_dentry, - name, buf, len, flags, NULL); + ret = __vfs_setxattr_locked(&path, name, buf, len, flags, NULL); fh_fill_post_attrs(fhp); err = nfsd_xattr_errno(ret); out_unlock: - inode_unlock(fhp->fh_dentry->d_inode); + inode_unlock(d_inode(path.dentry)); fh_drop_write(fhp); return err; } diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c index e963701b4c87..6dc241f195a6 100644 --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c @@ -83,7 +83,7 @@ int ovl_copy_xattr(struct super_block *sb, const struct path *oldpath, struct de if (!old->d_inode->i_op->listxattr || !new->d_inode->i_op->listxattr) return 0; - list_size = vfs_listxattr(old, NULL, 0); + list_size = vfs_listxattr(oldpath, NULL, 0); if (list_size <= 0) { if (list_size == -EOPNOTSUPP) return 0; @@ -94,7 +94,7 @@ int ovl_copy_xattr(struct super_block *sb, const struct path *oldpath, struct de if (!buf) return -ENOMEM; - list_size = vfs_listxattr(old, buf, list_size); + list_size = vfs_listxattr(oldpath, buf, list_size); if (list_size <= 0) { error = list_size; goto out; diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index d915b87c0b06..c13f6b2c915c 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -291,8 +291,7 @@ static inline ssize_t ovl_do_getxattr(const struct path *path, const char *name, WARN_ON(path->dentry->d_sb != path->mnt->mnt_sb); - err = vfs_getxattr(mnt_idmap(path->mnt), path->dentry, - name, value, size); + err = vfs_getxattr(path, name, value, size); len = (value && err > 0) ? err : 0; pr_debug("getxattr(%pd2, \"%s\", \"%*pE\", %zu, 0) = %i\n", @@ -325,9 +324,13 @@ static inline int ovl_do_setxattr(struct ovl_fs *ofs, struct dentry *dentry, const char *name, const void *value, size_t size, int flags) { + struct path path = { + .mnt = ovl_upper_mnt(ofs), + .dentry = dentry, + }; + /* Use vfs_setxattr(), not __vfs_setxattr(): it idmaps the security.capability rootid. */ - int err = vfs_setxattr(ovl_upper_mnt_idmap(ofs), dentry, name, - value, size, flags); + int err = vfs_setxattr(&path, name, value, size, flags); pr_debug("setxattr(%pd2, \"%s\", \"%*pE\", %zu, %d) = %i\n", dentry, name, min((int)size, 48), value, size, flags, err); @@ -344,7 +347,12 @@ static inline int ovl_setxattr(struct ovl_fs *ofs, struct dentry *dentry, static inline int ovl_do_removexattr(struct ovl_fs *ofs, struct dentry *dentry, const char *name) { - int err = vfs_removexattr(ovl_upper_mnt_idmap(ofs), dentry, name); + struct path path = { + .mnt = ovl_upper_mnt(ofs), + .dentry = dentry, + }; + + int err = vfs_removexattr(&path, name); pr_debug("removexattr(%pd2, \"%s\") = %i\n", dentry, name, err); return err; } diff --git a/fs/overlayfs/xattrs.c b/fs/overlayfs/xattrs.c index 5ae44b9c8790..b4658324b9f3 100644 --- a/fs/overlayfs/xattrs.c +++ b/fs/overlayfs/xattrs.c @@ -45,7 +45,7 @@ static int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char if (!value && !upperdentry) { ovl_path_lower(dentry, &realpath); with_ovl_creds(dentry->d_sb) - err = vfs_getxattr(mnt_idmap(realpath.mnt), realdentry, name, NULL, 0); + err = vfs_getxattr(&realpath, name, NULL, 0); if (err < 0) goto out; } @@ -86,7 +86,7 @@ static int ovl_xattr_get(struct dentry *dentry, struct inode *inode, const char ovl_i_path_real(inode, &realpath); /* Use vfs_getxattr(), not __vfs_getxattr(): it idmaps the security.capability rootid. */ with_ovl_creds(dentry->d_sb) - return vfs_getxattr(mnt_idmap(realpath.mnt), realpath.dentry, name, value, size); + return vfs_getxattr(&realpath, name, value, size); } static bool ovl_can_list(struct super_block *sb, const char *s) @@ -105,15 +105,20 @@ static bool ovl_can_list(struct super_block *sb, const char *s) ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size) { - struct dentry *realdentry = ovl_dentry_real(dentry); + struct path realpath; struct ovl_fs *ofs = OVL_FS(dentry->d_sb); ssize_t res; size_t len; char *s; size_t prefix_len, name_len; + if (ovl_dentry_upper(dentry)) + ovl_path_upper(dentry, &realpath); + else + ovl_path_lower(dentry, &realpath); + with_ovl_creds(dentry->d_sb) - res = vfs_listxattr(realdentry, list, size); + res = vfs_listxattr(&realpath, list, size); if (res <= 0 || size == 0) return res; diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index fb3ee170db3c..b5db5f280701 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -3293,7 +3293,6 @@ static bool smb2_is_private_ea(const char *name, size_t name_len) static int smb2_set_ea(struct smb2_ea_info *eabuf, unsigned int buf_len, const struct path *path, bool get_write) { - struct mnt_idmap *idmap = mnt_idmap(path->mnt); char *attr_name = NULL, *value; int rc = 0; unsigned int next = 0; @@ -3333,16 +3332,14 @@ static int smb2_set_ea(struct smb2_ea_info *eabuf, unsigned int buf_len, value = (char *)&eabuf->name + eabuf->EaNameLength + 1; if (!eabuf->EaValueLength) { - rc = ksmbd_vfs_casexattr_len(idmap, - path->dentry, + rc = ksmbd_vfs_casexattr_len(path, attr_name, XATTR_USER_PREFIX_LEN + eabuf->EaNameLength); /* delete the EA only when it exits */ if (rc > 0) { - rc = ksmbd_vfs_remove_xattr(idmap, - path, + rc = ksmbd_vfs_remove_xattr(path, attr_name, get_write); @@ -3357,7 +3354,7 @@ static int smb2_set_ea(struct smb2_ea_info *eabuf, unsigned int buf_len, /* if the EA doesn't exist, just do nothing. */ rc = 0; } else { - rc = ksmbd_vfs_setxattr(idmap, path, attr_name, value, + rc = ksmbd_vfs_setxattr(path, attr_name, value, le16_to_cpu(eabuf->EaValueLength), 0, get_write); if (rc < 0) { @@ -3394,7 +3391,6 @@ static noinline int smb2_set_stream_name_xattr(const struct path *path, struct ksmbd_file *fp, char *stream_name, int s_type) { - struct mnt_idmap *idmap = mnt_idmap(path->mnt); size_t xattr_stream_size; char *xattr_stream_name; int rc; @@ -3410,8 +3406,7 @@ static noinline int smb2_set_stream_name_xattr(const struct path *path, fp->stream.size = xattr_stream_size; /* Check if there is stream prefix in xattr space */ - rc = ksmbd_vfs_casexattr_len(idmap, - path->dentry, + rc = ksmbd_vfs_casexattr_len(path, xattr_stream_name, xattr_stream_size); if (rc >= 0) @@ -3438,7 +3433,7 @@ static noinline int smb2_set_stream_name_xattr(const struct path *path, 0x00, 0x00, 0x01, 0x00, /* version */ [15] = 0x80, /* backup time */ }; - rc = ksmbd_vfs_setxattr(idmap, path, xattr_stream_name, + rc = ksmbd_vfs_setxattr(path, xattr_stream_name, (void *)afpinfo_empty, sizeof(afpinfo_empty), 0, false); return rc < 0 ? rc : 0; @@ -3447,7 +3442,7 @@ static noinline int smb2_set_stream_name_xattr(const struct path *path, return -EBADF; } - rc = ksmbd_vfs_setxattr(idmap, path, xattr_stream_name, NULL, 0, 0, false); + rc = ksmbd_vfs_setxattr(path, xattr_stream_name, NULL, 0, 0, false); if (rc < 0) pr_err("Failed to store XATTR stream name :%d\n", rc); return 0; @@ -3462,8 +3457,7 @@ static noinline int smb2_set_stream_name_xattr(const struct path *path, */ static loff_t ksmbd_stream_eof(struct ksmbd_file *fp) { - ssize_t slen = ksmbd_vfs_casexattr_len(file_mnt_idmap(fp->filp), - fp->filp->f_path.dentry, + ssize_t slen = ksmbd_vfs_casexattr_len(&fp->filp->f_path, fp->stream.name, fp->stream.size); return slen < 0 ? 0 : (loff_t)slen; @@ -3471,12 +3465,11 @@ static loff_t ksmbd_stream_eof(struct ksmbd_file *fp) static int smb2_remove_smb_xattrs(const struct path *path) { - struct mnt_idmap *idmap = mnt_idmap(path->mnt); char *name, *xattr_list = NULL; ssize_t xattr_list_len; int err = 0; - xattr_list_len = ksmbd_vfs_listxattr(path->dentry, &xattr_list); + xattr_list_len = ksmbd_vfs_listxattr(path, &xattr_list); if (xattr_list_len < 0) { goto out; } else if (!xattr_list_len) { @@ -3491,8 +3484,7 @@ static int smb2_remove_smb_xattrs(const struct path *path) if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) && !strncmp(&name[XATTR_USER_PREFIX_LEN], STREAM_PREFIX, STREAM_PREFIX_LEN)) { - err = ksmbd_vfs_remove_xattr(idmap, path, - name, true); + err = ksmbd_vfs_remove_xattr(path, name, true); if (err) ksmbd_debug(SMB, "remove xattr failed : %s\n", name); @@ -3538,7 +3530,7 @@ static void smb2_new_xattrs(struct ksmbd_tree_connect *tcon, const struct path * da.flags = XATTR_DOSINFO_ATTRIB | XATTR_DOSINFO_CREATE_TIME | XATTR_DOSINFO_ITIME; - rc = ksmbd_vfs_set_dos_attrib_xattr(mnt_idmap(path->mnt), path, &da, true); + rc = ksmbd_vfs_set_dos_attrib_xattr(path, &da, true); if (rc) ksmbd_debug(SMB, "failed to store file attribute into xattr\n"); } @@ -3547,6 +3539,7 @@ static bool smb2_parent_compressed(struct ksmbd_tree_connect *tcon, const struct path *path) { struct dentry *parent = dget_parent(path->dentry); + struct path parent_path = { .mnt = path->mnt, .dentry = parent }; struct file_kattr fa = { .flags_valid = true }; struct xattr_dos_attrib da; bool compressed = false; @@ -3558,7 +3551,7 @@ static bool smb2_parent_compressed(struct ksmbd_tree_connect *tcon, goto out; } - rc = ksmbd_vfs_get_dos_attrib_xattr(mnt_idmap(path->mnt), parent, &da); + rc = ksmbd_vfs_get_dos_attrib_xattr(&parent_path, &da); if (rc > 0 && da.attr & FILE_ATTRIBUTE_COMPRESSED) compressed = true; @@ -3578,8 +3571,7 @@ static void smb2_update_xattrs(struct ksmbd_tree_connect *tcon, fp->f_ci->m_fattr &= ~(FILE_ATTRIBUTE_HIDDEN_LE | FILE_ATTRIBUTE_SYSTEM_LE); /* get FileAttributes from XATTR_NAME_DOS_ATTRIBUTE */ - rc = ksmbd_vfs_get_dos_attrib_xattr(mnt_idmap(path->mnt), - path->dentry, &da); + rc = ksmbd_vfs_get_dos_attrib_xattr(path, &da); if (rc > 0) { if (store_dos_attrs) { fp->f_ci->m_fattr = cpu_to_le32(da.attr); @@ -4524,8 +4516,7 @@ int smb2_open(struct ksmbd_work *work) if (test_share_config_flag(tcon->share_conf, KSMBD_SHARE_FLAG_STORE_DOS_ATTRS) && - ksmbd_vfs_get_dos_attrib_xattr(mnt_idmap(path.mnt), - path.dentry, &da) > 0 && + ksmbd_vfs_get_dos_attrib_xattr(&path, &da) > 0 && da.attr & FILE_ATTRIBUTE_READONLY) { rsp->hdr.Status = STATUS_CANNOT_DELETE; rc = -EACCES; @@ -4863,7 +4854,6 @@ int smb2_open(struct ksmbd_work *work) } rc = ksmbd_vfs_set_sd_xattr(conn, - idmap, &path, pntsd, pntsd_size, @@ -5886,7 +5876,6 @@ static int process_query_dir_entries(struct smb2_query_dir_private *priv) ksmbd_kstat.kstat = &kstat; if (priv->info_level != FILE_NAMES_INFORMATION) { rc = ksmbd_vfs_fill_dentry_attrs(priv->work, - idmap, dent, &ksmbd_kstat); if (rc) { @@ -6428,7 +6417,6 @@ static int smb2_get_ea(struct ksmbd_work *work, struct ksmbd_file *fp, ssize_t buf_free_len, alignment_bytes, next_offset, rsp_data_cnt = 0; struct smb2_ea_info_req *ea_req = NULL; const struct path *path; - struct mnt_idmap *idmap = file_mnt_idmap(fp->filp); if (!(fp->daccess & FILE_READ_EA_LE)) { pr_err("Not permitted to read ext attr : 0x%x\n", @@ -6465,7 +6453,7 @@ static int smb2_get_ea(struct ksmbd_work *work, struct ksmbd_file *fp, if (buf_free_len < 0) return -EINVAL; - rc = ksmbd_vfs_listxattr(path->dentry, &xattr_list); + rc = ksmbd_vfs_listxattr(path, &xattr_list); if (rc < 0) { rsp->hdr.Status = STATUS_INVALID_HANDLE; goto out; @@ -6511,8 +6499,7 @@ static int smb2_get_ea(struct ksmbd_work *work, struct ksmbd_file *fp, buf_free_len -= (offsetof(struct smb2_ea_info, name) + name_len + 1); /* bailout if xattr can't fit in buf_free_len */ - value_len = ksmbd_vfs_getxattr(idmap, path->dentry, - name, &buf); + value_len = ksmbd_vfs_getxattr(path, name, &buf); if (value_len <= 0) { rc = -ENOENT; rsp->hdr.Status = STATUS_INVALID_HANDLE; @@ -6802,7 +6789,7 @@ static char *smb2_get_normalized_stream_name(struct ksmbd_file *fp) if (!ksmbd_stream_fd(fp)) return NULL; - xattr_list_len = ksmbd_vfs_listxattr(fp->filp->f_path.dentry, + xattr_list_len = ksmbd_vfs_listxattr(&fp->filp->f_path, &xattr_list); if (xattr_list_len <= 0) goto out; @@ -6905,7 +6892,7 @@ static int get_file_stream_info(struct ksmbd_work *work, if (buf_free_len < 0) goto out; - xattr_list_len = ksmbd_vfs_listxattr(path->dentry, &xattr_list); + xattr_list_len = ksmbd_vfs_listxattr(path, &xattr_list); if (xattr_list_len < 0) { goto out; } else if (!xattr_list_len) { @@ -6950,8 +6937,7 @@ static int get_file_stream_info(struct ksmbd_work *work, streamlen *= 2; kfree(stream_buf); file_info->StreamNameLength = cpu_to_le32(streamlen); - slen = ksmbd_vfs_xattr_len(file_mnt_idmap(fp->filp), - path->dentry, stream_name); + slen = ksmbd_vfs_xattr_len(path, stream_name); ssize = slen < 0 ? 0 : (loff_t)slen; file_info->StreamSize = cpu_to_le64(ssize); file_info->StreamAllocationSize = cpu_to_le64(ssize); @@ -7689,8 +7675,8 @@ static int smb2_get_info_sec(struct ksmbd_work *work, if (test_share_config_flag(work->tcon->share_conf, KSMBD_SHARE_FLAG_ACL_XATTR)) - ppntsd_size = ksmbd_vfs_get_sd_xattr(work->conn, idmap, - fp->filp->f_path.dentry, + ppntsd_size = ksmbd_vfs_get_sd_xattr(work->conn, + &fp->filp->f_path, &ppntsd); /* Check if sd buffer size exceeds response buffer size */ @@ -8051,8 +8037,7 @@ static int smb2_rename(struct ksmbd_work *work, goto out; } - stream_buf_len = ksmbd_vfs_getcasexattr(file_mnt_idmap(fp->filp), - fp->filp->f_path.dentry, + stream_buf_len = ksmbd_vfs_getcasexattr(&fp->filp->f_path, fp->stream.name, fp->stream.size, &stream_buf); @@ -8063,8 +8048,7 @@ static int smb2_rename(struct ksmbd_work *work, } } - rc = ksmbd_vfs_setxattr(file_mnt_idmap(fp->filp), - &fp->filp->f_path, + rc = ksmbd_vfs_setxattr(&fp->filp->f_path, xattr_stream_name, stream_buf, stream_buf_len, 0, true); kfree(stream_buf); @@ -8171,7 +8155,6 @@ static int set_file_basic_info(struct ksmbd_file *fp, struct iattr attrs; struct file *filp; struct inode *inode; - struct mnt_idmap *idmap; __le32 attrs_mask = FILE_ATTRIBUTE_DIRECTORY_LE | FILE_ATTRIBUTE_COMPRESSED_LE; int rc = 0; @@ -8182,7 +8165,6 @@ static int set_file_basic_info(struct ksmbd_file *fp, attrs.ia_valid = 0; filp = fp->filp; inode = file_inode(filp); - idmap = file_mnt_idmap(filp); if (file_info->CreationTime) fp->create_time = le64_to_cpu(file_info->CreationTime); @@ -8227,7 +8209,7 @@ static int set_file_basic_info(struct ksmbd_file *fp, da.flags = XATTR_DOSINFO_ATTRIB | XATTR_DOSINFO_CREATE_TIME | XATTR_DOSINFO_ITIME; - rc = ksmbd_vfs_set_dos_attrib_xattr(idmap, &filp->f_path, &da, + rc = ksmbd_vfs_set_dos_attrib_xattr(&filp->f_path, &da, true); if (rc) ksmbd_debug(SMB, @@ -10780,7 +10762,6 @@ static inline int fsctl_set_sparse(struct ksmbd_work *work, u64 id, struct file_sparse *sparse) { struct ksmbd_file *fp; - struct mnt_idmap *idmap; int ret = 0; __le32 old_fattr; @@ -10804,8 +10785,6 @@ static inline int fsctl_set_sparse(struct ksmbd_work *work, u64 id, goto out; } - idmap = file_mnt_idmap(fp->filp); - old_fattr = fp->f_ci->m_fattr; if (!sparse->SetSparse && (old_fattr & FILE_ATTRIBUTE_SPARSE_FILE_LE)) { @@ -10823,8 +10802,7 @@ static inline int fsctl_set_sparse(struct ksmbd_work *work, u64 id, const struct cred *saved_cred; struct xattr_dos_attrib da = {0}; - ret = ksmbd_vfs_get_dos_attrib_xattr(idmap, - fp->filp->f_path.dentry, &da); + ret = ksmbd_vfs_get_dos_attrib_xattr(&fp->filp->f_path, &da); if (ret <= 0) { da.version = 4; da.itime = fp->itime; @@ -10836,8 +10814,7 @@ static inline int fsctl_set_sparse(struct ksmbd_work *work, u64 id, da.attr = le32_to_cpu(fp->f_ci->m_fattr); da.flags |= XATTR_DOSINFO_ATTRIB; saved_cred = override_creds(fp->filp->f_cred); - ret = ksmbd_vfs_set_dos_attrib_xattr(idmap, - &fp->filp->f_path, + ret = ksmbd_vfs_set_dos_attrib_xattr(&fp->filp->f_path, &da, true); revert_creds(saved_cred); if (ret) diff --git a/fs/smb/server/smb_common.c b/fs/smb/server/smb_common.c index 086a1b85e5f4..2cc8e24dcd6c 100644 --- a/fs/smb/server/smb_common.c +++ b/fs/smb/server/smb_common.c @@ -467,7 +467,6 @@ int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work, int info_level, { int i, rc = 0; struct ksmbd_conn *conn = work->conn; - struct mnt_idmap *idmap = file_mnt_idmap(dir->filp); for (i = 0; i < 2; i++) { struct kstat kstat; @@ -493,7 +492,6 @@ int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work, int info_level, ksmbd_kstat.kstat = &kstat; rc = ksmbd_vfs_fill_dentry_attrs(work, - idmap, dentry, &ksmbd_kstat); if (rc) diff --git a/fs/smb/server/smbacl.c b/fs/smb/server/smbacl.c index fcace71b0a29..f81e06918cfb 100644 --- a/fs/smb/server/smbacl.c +++ b/fs/smb/server/smbacl.c @@ -1199,8 +1199,8 @@ int smb_inherit_dacl(struct ksmbd_conn *conn, struct smb_acl *parent_pdacl; struct smb_ntsd *parent_pntsd = NULL; struct smb_sid owner_sid, group_sid; - struct dentry *parent = path->dentry->d_parent; - struct mnt_idmap *idmap = mnt_idmap(path->mnt); + struct path parent_path = { .mnt = path->mnt, + .dentry = path->dentry->d_parent }; int inherited_flags = 0, flags = 0, i, nt_size = 0, pdacl_size; int rc = 0, pntsd_type, ppntsd_size, acl_len, aces_size; unsigned int dacloffset; @@ -1209,8 +1209,8 @@ int smb_inherit_dacl(struct ksmbd_conn *conn, char *aces_base; bool is_dir = S_ISDIR(d_inode(path->dentry)->i_mode); - ppntsd_size = ksmbd_vfs_get_sd_xattr(conn, idmap, - parent, &parent_pntsd); + ppntsd_size = ksmbd_vfs_get_sd_xattr(conn, &parent_path, + &parent_pntsd); if (ppntsd_size <= 0) return -ENOENT; @@ -1427,7 +1427,7 @@ int smb_inherit_dacl(struct ksmbd_conn *conn, pntsd_size += sizeof(struct smb_acl) + nt_size; } - ksmbd_vfs_set_sd_xattr(conn, idmap, path, pntsd, pntsd_size, false); + ksmbd_vfs_set_sd_xattr(conn, path, pntsd, pntsd_size, false); kfree(pntsd); } @@ -1476,8 +1476,7 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, const struct path *path, vfsuid_t vfsuid; ksmbd_debug(SMB, "check permission using windows acl\n"); - pntsd_size = ksmbd_vfs_get_sd_xattr(conn, idmap, - path->dentry, &pntsd); + pntsd_size = ksmbd_vfs_get_sd_xattr(conn, path, &pntsd); if (pntsd_size <= 0 || !pntsd) goto err_out; @@ -1701,7 +1700,7 @@ int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon, newattrs.ia_valid |= ATTR_MODE; newattrs.ia_mode = (inode->i_mode & ~0777) | (fattr.cf_mode & 0777); - ksmbd_vfs_remove_acl_xattrs(idmap, path); + ksmbd_vfs_remove_acl_xattrs(path); /* Update posix acls */ if (IS_ENABLED(CONFIG_FS_POSIX_ACL) && fattr.cf_dacls) { rc = set_posix_acl(idmap, path->dentry, @@ -1732,8 +1731,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(idmap, path); - ksmbd_vfs_set_sd_xattr(conn, idmap, path, pntsd, ntsd_len, + ksmbd_vfs_remove_sd_xattrs(path); + ksmbd_vfs_set_sd_xattr(conn, path, pntsd, ntsd_len, get_write); } diff --git a/fs/smb/server/tests/smbacl_kunit.c b/fs/smb/server/tests/smbacl_kunit.c index 33496b4d31a3..0e918b72f94f 100644 --- a/fs/smb/server/tests/smbacl_kunit.c +++ b/fs/smb/server/tests/smbacl_kunit.c @@ -221,8 +221,7 @@ static void ksmbd_smb_check_perm_dacl_boundary_test(struct kunit *test) mk_vma_flags(VMA_NORESERVE_BIT)); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, file); - rc = ksmbd_vfs_set_sd_xattr(NULL, mnt_idmap(file->f_path.mnt), - &file->f_path, pntsd, ntsd_size, + rc = ksmbd_vfs_set_sd_xattr(NULL, &file->f_path, pntsd, ntsd_size, false); KUNIT_EXPECT_EQ(test, 0, rc); if (rc) @@ -263,8 +262,7 @@ ksmbd_smb_check_perm_dacl_maximal_boundary_test(struct kunit *test) mk_vma_flags(VMA_NORESERVE_BIT)); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, file); - rc = ksmbd_vfs_set_sd_xattr(NULL, mnt_idmap(file->f_path.mnt), - &file->f_path, pntsd, ntsd_size, + rc = ksmbd_vfs_set_sd_xattr(NULL, &file->f_path, pntsd, ntsd_size, false); KUNIT_EXPECT_EQ(test, 0, rc); if (rc) diff --git a/fs/smb/server/vfs.c b/fs/smb/server/vfs.c index db0f2de2bab3..eb904cf9ef2d 100644 --- a/fs/smb/server/vfs.c +++ b/fs/smb/server/vfs.c @@ -217,14 +217,14 @@ int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char *name, umode_t mode) return err; } -ssize_t ksmbd_vfs_getcasexattr(struct mnt_idmap *idmap, - struct dentry *dentry, char *attr_name, +ssize_t ksmbd_vfs_getcasexattr(const struct path *path, + char *attr_name, int attr_name_len, char **attr_value) { char *name, *xattr_list = NULL; ssize_t value_len = -ENOENT, xattr_list_len; - xattr_list_len = ksmbd_vfs_listxattr(dentry, &xattr_list); + xattr_list_len = ksmbd_vfs_listxattr(path, &xattr_list); if (xattr_list_len <= 0) goto out; @@ -234,8 +234,7 @@ ssize_t ksmbd_vfs_getcasexattr(struct mnt_idmap *idmap, if (strncasecmp(attr_name, name, attr_name_len)) continue; - value_len = ksmbd_vfs_getxattr(idmap, - dentry, + value_len = ksmbd_vfs_getxattr(path, name, attr_value); if (value_len < 0) @@ -259,8 +258,7 @@ static int ksmbd_vfs_stream_read(struct ksmbd_file *fp, char *buf, loff_t *pos, *pos, count); saved_cred = override_creds(fp->filp->f_cred); - v_len = ksmbd_vfs_getcasexattr(file_mnt_idmap(fp->filp), - fp->filp->f_path.dentry, + v_len = ksmbd_vfs_getcasexattr(&fp->filp->f_path, fp->stream.name, fp->stream.size, &stream_buf); @@ -387,7 +385,6 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos, { const struct cred *saved_cred; char *stream_buf = NULL, *wbuf; - struct mnt_idmap *idmap = file_mnt_idmap(fp->filp); size_t size; ssize_t v_len; int err = 0; @@ -407,8 +404,7 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos, } saved_cred = override_creds(fp->filp->f_cred); - v_len = ksmbd_vfs_getcasexattr(idmap, - fp->filp->f_path.dentry, + v_len = ksmbd_vfs_getcasexattr(&fp->filp->f_path, fp->stream.name, fp->stream.size, &stream_buf); @@ -433,8 +429,7 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos, memcpy(&stream_buf[*pos], buf, count); - err = ksmbd_vfs_setxattr(idmap, - &fp->filp->f_path, + err = ksmbd_vfs_setxattr(&fp->filp->f_path, fp->stream.name, (void *)stream_buf, size, @@ -813,17 +808,17 @@ int ksmbd_vfs_truncate(struct ksmbd_work *work, /** * ksmbd_vfs_listxattr() - vfs helper for smb list extended attributes - * @dentry: dentry of file for listing xattrs + * @path: path of file for listing xattrs * @list: destination buffer * * Return: xattr list length on success, otherwise error */ -ssize_t ksmbd_vfs_listxattr(struct dentry *dentry, char **list) +ssize_t ksmbd_vfs_listxattr(const struct path *path, char **list) { ssize_t size; char *vlist = NULL; - size = vfs_listxattr(dentry, NULL, 0); + size = vfs_listxattr(path, NULL, 0); if (size <= 0) return size; @@ -832,7 +827,7 @@ ssize_t ksmbd_vfs_listxattr(struct dentry *dentry, char **list) return -ENOMEM; *list = vlist; - size = vfs_listxattr(dentry, vlist, size); + size = vfs_listxattr(path, vlist, size); if (size < 0) { ksmbd_debug(VFS, "listxattr failed\n"); kvfree(vlist); @@ -842,30 +837,27 @@ ssize_t ksmbd_vfs_listxattr(struct dentry *dentry, char **list) return size; } -ssize_t ksmbd_vfs_xattr_len(struct mnt_idmap *idmap, - struct dentry *dentry, char *xattr_name) +ssize_t ksmbd_vfs_xattr_len(const struct path *path, char *xattr_name) { - return vfs_getxattr(idmap, dentry, xattr_name, NULL, 0); + return vfs_getxattr(path, xattr_name, NULL, 0); } /** * ksmbd_vfs_getxattr() - vfs helper for smb get extended attributes value - * @idmap: idmap - * @dentry: dentry of file for getting xattrs + * @path: path of file for getting xattrs * @xattr_name: name of xattr name to query * @xattr_buf: destination buffer xattr value * * Return: read xattr value length on success, otherwise error */ -ssize_t ksmbd_vfs_getxattr(struct mnt_idmap *idmap, - struct dentry *dentry, +ssize_t ksmbd_vfs_getxattr(const struct path *path, char *xattr_name, char **xattr_buf) { ssize_t xattr_len; char *buf; *xattr_buf = NULL; - xattr_len = ksmbd_vfs_xattr_len(idmap, dentry, xattr_name); + xattr_len = ksmbd_vfs_xattr_len(path, xattr_name); if (xattr_len < 0) return xattr_len; @@ -873,8 +865,7 @@ ssize_t ksmbd_vfs_getxattr(struct mnt_idmap *idmap, if (!buf) return -ENOMEM; - xattr_len = vfs_getxattr(idmap, dentry, xattr_name, - (void *)buf, xattr_len); + xattr_len = vfs_getxattr(path, xattr_name, (void *)buf, xattr_len); if (xattr_len > 0) *xattr_buf = buf; else @@ -884,7 +875,6 @@ ssize_t ksmbd_vfs_getxattr(struct mnt_idmap *idmap, /** * ksmbd_vfs_setxattr() - vfs helper for smb set extended attributes value - * @idmap: idmap of the relevant mount * @path: path of dentry to set XATTR at * @attr_name: xattr name for setxattr * @attr_value: xattr value to set @@ -894,8 +884,7 @@ ssize_t ksmbd_vfs_getxattr(struct mnt_idmap *idmap, * * Return: 0 on success, otherwise error */ -int ksmbd_vfs_setxattr(struct mnt_idmap *idmap, - const struct path *path, const char *attr_name, +int ksmbd_vfs_setxattr(const struct path *path, const char *attr_name, void *attr_value, size_t attr_size, int flags, bool get_write) { @@ -907,8 +896,7 @@ int ksmbd_vfs_setxattr(struct mnt_idmap *idmap, return err; } - err = vfs_setxattr(idmap, - path->dentry, + err = vfs_setxattr(path, attr_name, attr_value, attr_size, @@ -1178,8 +1166,7 @@ int ksmbd_vfs_query_allocated_ranges(struct ksmbd_file *fp, loff_t start, return ret; } -int ksmbd_vfs_remove_xattr(struct mnt_idmap *idmap, - const struct path *path, char *attr_name, +int ksmbd_vfs_remove_xattr(const struct path *path, char *attr_name, bool get_write) { int err; @@ -1190,7 +1177,7 @@ int ksmbd_vfs_remove_xattr(struct mnt_idmap *idmap, return err; } - err = vfs_removexattr(idmap, path->dentry, attr_name); + err = vfs_removexattr(path, attr_name); if (get_write == true) mnt_drop_write(path->mnt); @@ -1472,14 +1459,13 @@ struct dentry *ksmbd_vfs_kern_path_create(struct ksmbd_work *work, return dent; } -int ksmbd_vfs_remove_acl_xattrs(struct mnt_idmap *idmap, - const struct path *path) +int ksmbd_vfs_remove_acl_xattrs(const struct path *path) { char *name, *xattr_list = NULL; ssize_t xattr_list_len; int err = 0; - xattr_list_len = ksmbd_vfs_listxattr(path->dentry, &xattr_list); + xattr_list_len = ksmbd_vfs_listxattr(path, &xattr_list); if (xattr_list_len < 0) { goto out; } else if (!xattr_list_len) { @@ -1499,7 +1485,8 @@ int ksmbd_vfs_remove_acl_xattrs(struct mnt_idmap *idmap, sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1) || !strncmp(name, XATTR_NAME_POSIX_ACL_DEFAULT, sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1)) { - err = vfs_remove_acl(idmap, path->dentry, name); + err = vfs_remove_acl(mnt_idmap(path->mnt), + path->dentry, name); if (err) ksmbd_debug(SMB, "remove acl xattr failed : %s\n", name); @@ -1512,13 +1499,13 @@ int ksmbd_vfs_remove_acl_xattrs(struct mnt_idmap *idmap, return err; } -int ksmbd_vfs_remove_sd_xattrs(struct mnt_idmap *idmap, const struct path *path) +int ksmbd_vfs_remove_sd_xattrs(const struct path *path) { char *name, *xattr_list = NULL; ssize_t xattr_list_len; int err = 0; - xattr_list_len = ksmbd_vfs_listxattr(path->dentry, &xattr_list); + xattr_list_len = ksmbd_vfs_listxattr(path, &xattr_list); if (xattr_list_len < 0) { goto out; } else if (!xattr_list_len) { @@ -1531,7 +1518,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, true); + err = ksmbd_vfs_remove_xattr(path, name, true); if (err) ksmbd_debug(SMB, "remove xattr failed : %s\n", name); } @@ -1607,7 +1594,6 @@ static struct xattr_smb_acl *ksmbd_vfs_make_xattr_posix_acl(struct mnt_idmap *id } int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, - struct mnt_idmap *idmap, const struct path *path, struct smb_ntsd *pntsd, int len, bool get_write) @@ -1618,6 +1604,7 @@ int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, struct xattr_smb_acl *smb_acl, *def_smb_acl = NULL; struct dentry *dentry = path->dentry; struct inode *inode = d_inode(dentry); + struct mnt_idmap *idmap = mnt_idmap(path->mnt); acl.version = 4; acl.hash_type = XATTR_SD_HASH_TYPE_SHA256; @@ -1659,7 +1646,7 @@ int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, goto out; } - rc = ksmbd_vfs_setxattr(idmap, path, + rc = ksmbd_vfs_setxattr(path, XATTR_NAME_SD, sd_ndr.data, sd_ndr.offset, 0, get_write); if (rc < 0) @@ -1675,19 +1662,19 @@ int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, EXPORT_SYMBOL_IF_KUNIT(ksmbd_vfs_set_sd_xattr); int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn, - struct mnt_idmap *idmap, - struct dentry *dentry, + const struct path *path, struct smb_ntsd **pntsd) { int rc; struct ndr n; - struct inode *inode = d_inode(dentry); + struct inode *inode = d_inode(path->dentry); struct ndr acl_ndr = {0}; struct xattr_ntacl acl = {0}; struct xattr_smb_acl *smb_acl = NULL, *def_smb_acl = NULL; + struct mnt_idmap *idmap = mnt_idmap(path->mnt); __u8 cmp_hash[XATTR_SD_HASH_SIZE] = {0}; - rc = ksmbd_vfs_getxattr(idmap, dentry, XATTR_NAME_SD, &n.data); + rc = ksmbd_vfs_getxattr(path, XATTR_NAME_SD, &n.data); if (rc <= 0) return rc; @@ -1744,8 +1731,7 @@ int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn, return rc; } -int ksmbd_vfs_set_dos_attrib_xattr(struct mnt_idmap *idmap, - const struct path *path, +int ksmbd_vfs_set_dos_attrib_xattr(const struct path *path, struct xattr_dos_attrib *da, bool get_write) { @@ -1756,7 +1742,7 @@ int ksmbd_vfs_set_dos_attrib_xattr(struct mnt_idmap *idmap, if (err) goto out; - err = ksmbd_vfs_setxattr(idmap, path, XATTR_NAME_DOS_ATTRIBUTE, + err = ksmbd_vfs_setxattr(path, XATTR_NAME_DOS_ATTRIBUTE, (void *)n.data, n.offset, 0, get_write); if (err) ksmbd_debug(SMB, "failed to store dos attribute in xattr\n"); @@ -1766,14 +1752,13 @@ int ksmbd_vfs_set_dos_attrib_xattr(struct mnt_idmap *idmap, return err; } -int ksmbd_vfs_get_dos_attrib_xattr(struct mnt_idmap *idmap, - struct dentry *dentry, +int ksmbd_vfs_get_dos_attrib_xattr(const struct path *path, struct xattr_dos_attrib *da) { struct ndr n; int err; - err = ksmbd_vfs_getxattr(idmap, dentry, XATTR_NAME_DOS_ATTRIBUTE, + err = ksmbd_vfs_getxattr(path, XATTR_NAME_DOS_ATTRIBUTE, (char **)&n.data); if (err > 0) { n.length = err; @@ -1822,7 +1807,6 @@ void *ksmbd_vfs_init_kstat(char **p, struct ksmbd_kstat *ksmbd_kstat) } int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work, - struct mnt_idmap *idmap, struct dentry *dentry, struct ksmbd_kstat *ksmbd_kstat) { @@ -1856,7 +1840,7 @@ int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work, KSMBD_SHARE_FLAG_STORE_DOS_ATTRS)) { struct xattr_dos_attrib da; - rc = ksmbd_vfs_get_dos_attrib_xattr(idmap, dentry, &da); + rc = ksmbd_vfs_get_dos_attrib_xattr(&path, &da); if (rc > 0) { ksmbd_kstat->file_attributes = cpu_to_le32(da.attr); ksmbd_kstat->create_time = da.create_time; @@ -1879,7 +1863,7 @@ int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work, char *xattr_list = NULL, *name; ssize_t xattr_list_len; - xattr_list_len = ksmbd_vfs_listxattr(dentry, &xattr_list); + xattr_list_len = ksmbd_vfs_listxattr(&path, &xattr_list); if (xattr_list_len > 0) { for (name = xattr_list; name - xattr_list < xattr_list_len; @@ -1897,14 +1881,14 @@ int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work, return 0; } -ssize_t ksmbd_vfs_casexattr_len(struct mnt_idmap *idmap, - struct dentry *dentry, char *attr_name, +ssize_t ksmbd_vfs_casexattr_len(const struct path *path, + char *attr_name, int attr_name_len) { char *name, *xattr_list = NULL; ssize_t value_len = -ENOENT, xattr_list_len; - xattr_list_len = ksmbd_vfs_listxattr(dentry, &xattr_list); + xattr_list_len = ksmbd_vfs_listxattr(path, &xattr_list); if (xattr_list_len <= 0) goto out; @@ -1914,7 +1898,7 @@ ssize_t ksmbd_vfs_casexattr_len(struct mnt_idmap *idmap, if (strncasecmp(attr_name, name, attr_name_len)) continue; - value_len = ksmbd_vfs_xattr_len(idmap, dentry, name); + value_len = ksmbd_vfs_xattr_len(path, name); break; } @@ -2067,8 +2051,7 @@ int ksmbd_vfs_copy_file_ranges(struct ksmbd_work *work, saved_cred = override_creds(src_fp->filp->f_cred); src_file_size = ksmbd_vfs_casexattr_len( - file_mnt_idmap(src_fp->filp), - src_fp->filp->f_path.dentry, + &src_fp->filp->f_path, src_fp->stream.name, src_fp->stream.size); revert_creds(saved_cred); if (src_file_size < 0) @@ -2386,7 +2369,7 @@ static int __ksmbd_vfs_set_compression(struct ksmbd_work *work, if (fp->f_ci->m_fattr != old_fattr) { struct xattr_dos_attrib da = {0}; - rc = ksmbd_vfs_get_dos_attrib_xattr(idmap, dentry, &da); + rc = ksmbd_vfs_get_dos_attrib_xattr(&fp->filp->f_path, &da); if (rc <= 0) { da.version = 4; da.itime = fp->itime; @@ -2397,8 +2380,7 @@ static int __ksmbd_vfs_set_compression(struct ksmbd_work *work, da.attr = le32_to_cpu(fp->f_ci->m_fattr); da.flags |= XATTR_DOSINFO_ATTRIB; - rc = ksmbd_vfs_set_dos_attrib_xattr(idmap, - &fp->filp->f_path, + rc = ksmbd_vfs_set_dos_attrib_xattr(&fp->filp->f_path, &da, true); if (rc) rc = 0; diff --git a/fs/smb/server/vfs.h b/fs/smb/server/vfs.h index 566c670c90be..a0cf77a7a2c7 100644 --- a/fs/smb/server/vfs.h +++ b/fs/smb/server/vfs.h @@ -103,27 +103,24 @@ int ksmbd_vfs_copy_file_ranges(struct ksmbd_work *work, unsigned int *chunk_count_written, unsigned int *chunk_size_written, loff_t *total_size_written); -ssize_t ksmbd_vfs_listxattr(struct dentry *dentry, char **list); -ssize_t ksmbd_vfs_getxattr(struct mnt_idmap *idmap, - struct dentry *dentry, +ssize_t ksmbd_vfs_listxattr(const struct path *path, char **list); +ssize_t ksmbd_vfs_getxattr(const struct path *path, char *xattr_name, char **xattr_buf); -ssize_t ksmbd_vfs_xattr_len(struct mnt_idmap *idmap, - struct dentry *dentry, char *xattr_name); -ssize_t ksmbd_vfs_getcasexattr(struct mnt_idmap *idmap, - struct dentry *dentry, char *attr_name, +ssize_t ksmbd_vfs_xattr_len(const struct path *path, + char *xattr_name); +ssize_t ksmbd_vfs_getcasexattr(const struct path *path, + char *attr_name, int attr_name_len, char **attr_value); -ssize_t ksmbd_vfs_casexattr_len(struct mnt_idmap *idmap, - struct dentry *dentry, char *attr_name, +ssize_t ksmbd_vfs_casexattr_len(const struct path *path, + char *attr_name, int attr_name_len); -int ksmbd_vfs_setxattr(struct mnt_idmap *idmap, - const struct path *path, const char *attr_name, +int ksmbd_vfs_setxattr(const struct path *path, const char *attr_name, void *attr_value, size_t attr_size, int flags, bool get_write); 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, +int ksmbd_vfs_remove_xattr(const struct path *path, char *attr_name, bool get_write); int ksmbd_vfs_kern_path(struct ksmbd_work *work, char *name, unsigned int flags, @@ -152,29 +149,23 @@ int ksmbd_vfs_query_allocated_ranges(struct ksmbd_file *fp, loff_t start, int ksmbd_vfs_unlink(struct file *filp); void *ksmbd_vfs_init_kstat(char **p, struct ksmbd_kstat *ksmbd_kstat); int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work, - struct mnt_idmap *idmap, struct dentry *dentry, struct ksmbd_kstat *ksmbd_kstat); void ksmbd_vfs_posix_lock_wait(struct file_lock *flock); void ksmbd_vfs_posix_lock_unblock(struct file_lock *flock); -int ksmbd_vfs_remove_acl_xattrs(struct mnt_idmap *idmap, - const struct path *path); -int ksmbd_vfs_remove_sd_xattrs(struct mnt_idmap *idmap, const struct path *path); +int ksmbd_vfs_remove_acl_xattrs(const struct path *path); +int ksmbd_vfs_remove_sd_xattrs(const struct path *path); int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, - struct mnt_idmap *idmap, const struct path *path, struct smb_ntsd *pntsd, int len, bool get_write); int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn, - struct mnt_idmap *idmap, - struct dentry *dentry, + const struct path *path, struct smb_ntsd **pntsd); -int ksmbd_vfs_set_dos_attrib_xattr(struct mnt_idmap *idmap, - const struct path *path, +int ksmbd_vfs_set_dos_attrib_xattr(const struct path *path, struct xattr_dos_attrib *da, bool get_write); -int ksmbd_vfs_get_dos_attrib_xattr(struct mnt_idmap *idmap, - struct dentry *dentry, +int ksmbd_vfs_get_dos_attrib_xattr(const struct path *path, struct xattr_dos_attrib *da); int ksmbd_vfs_set_init_posix_acl(struct mnt_idmap *idmap, const struct path *path); diff --git a/fs/smb/server/vfs_cache.c b/fs/smb/server/vfs_cache.c index a96b764c4db5..b5700c6f096f 100644 --- a/fs/smb/server/vfs_cache.c +++ b/fs/smb/server/vfs_cache.c @@ -538,8 +538,7 @@ static void __ksmbd_inode_close(struct ksmbd_file *fp) const struct cred *saved_cred; saved_cred = override_creds(filp->f_cred); - err = ksmbd_vfs_remove_xattr(file_mnt_idmap(filp), - &filp->f_path, + err = ksmbd_vfs_remove_xattr(&filp->f_path, fp->stream.name, true); revert_creds(saved_cred); diff --git a/fs/xattr.c b/fs/xattr.c index d58979115200..818d6652b6d9 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -285,8 +285,7 @@ int __vfs_setxattr_noperm(struct mnt_idmap *idmap, * __vfs_setxattr_locked - set an extended attribute while holding the inode * lock * - * @idmap: idmap of the mount of the target inode - * @dentry: object to perform setxattr on + * @path: object to perform setxattr on * @name: xattr name to set * @value: value to set @name to * @size: size of @value @@ -295,10 +294,12 @@ int __vfs_setxattr_noperm(struct mnt_idmap *idmap, * a delegation was broken on, NULL if none. */ int -__vfs_setxattr_locked(struct mnt_idmap *idmap, struct dentry *dentry, - const char *name, const void *value, size_t size, - int flags, struct delegated_inode *delegated_inode) +__vfs_setxattr_locked(const struct path *path, const char *name, + const void *value, size_t size, int flags, + struct delegated_inode *delegated_inode) { + struct mnt_idmap *idmap = mnt_idmap(path->mnt); + struct dentry *dentry = path->dentry; struct inode *inode = dentry->d_inode; int error; @@ -324,9 +325,11 @@ __vfs_setxattr_locked(struct mnt_idmap *idmap, struct dentry *dentry, EXPORT_SYMBOL_GPL(__vfs_setxattr_locked); int -vfs_setxattr(struct mnt_idmap *idmap, struct dentry *dentry, - const char *name, const void *value, size_t size, int flags) +vfs_setxattr(const struct path *path, const char *name, const void *value, + size_t size, int flags) { + struct mnt_idmap *idmap = mnt_idmap(path->mnt); + struct dentry *dentry = path->dentry; struct inode *inode = dentry->d_inode; struct delegated_inode delegated_inode = { }; const void *orig_value = value; @@ -341,7 +344,7 @@ vfs_setxattr(struct mnt_idmap *idmap, struct dentry *dentry, retry_deleg: inode_lock(inode); - error = __vfs_setxattr_locked(idmap, dentry, name, value, size, + error = __vfs_setxattr_locked(path, name, value, size, flags, &delegated_inode); inode_unlock(inode); @@ -448,9 +451,11 @@ __vfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name, EXPORT_SYMBOL(__vfs_getxattr); ssize_t -vfs_getxattr(struct mnt_idmap *idmap, struct dentry *dentry, - const char *name, void *value, size_t size) +vfs_getxattr(const struct path *path, const char *name, void *value, + size_t size) { + struct mnt_idmap *idmap = mnt_idmap(path->mnt); + struct dentry *dentry = path->dentry; struct inode *inode = dentry->d_inode; int error; @@ -482,12 +487,12 @@ EXPORT_SYMBOL_GPL(vfs_getxattr); /** * vfs_listxattr - retrieve \0 separated list of xattr names - * @dentry: the dentry from whose inode the xattr names are retrieved + * @path: the path from whose inode the xattr names are retrieved * @list: buffer to store xattr names into * @size: size of the buffer * * This function returns the names of all xattrs associated with the - * inode of @dentry. + * inode of @path->dentry. * * Note, for legacy reasons the vfs_listxattr() function lists POSIX * ACLs as well. Since POSIX ACLs are decoupled from IOP_XATTR the @@ -503,8 +508,9 @@ EXPORT_SYMBOL_GPL(vfs_getxattr); * negative error code. */ ssize_t -vfs_listxattr(struct dentry *dentry, char *list, size_t size) +vfs_listxattr(const struct path *path, char *list, size_t size) { + struct dentry *dentry = path->dentry; struct inode *inode = d_inode(dentry); ssize_t error; @@ -550,17 +556,17 @@ EXPORT_SYMBOL(__vfs_removexattr); * __vfs_removexattr_locked - set an extended attribute while holding the inode * lock * - * @idmap: idmap of the mount of the target inode - * @dentry: object to perform setxattr on + * @path: object to perform removexattr on * @name: name of xattr to remove * @delegated_inode: on return, will contain an inode pointer that * a delegation was broken on, NULL if none. */ int -__vfs_removexattr_locked(struct mnt_idmap *idmap, - struct dentry *dentry, const char *name, +__vfs_removexattr_locked(const struct path *path, const char *name, struct delegated_inode *delegated_inode) { + struct mnt_idmap *idmap = mnt_idmap(path->mnt); + struct dentry *dentry = path->dentry; struct inode *inode = dentry->d_inode; int error; @@ -589,17 +595,16 @@ __vfs_removexattr_locked(struct mnt_idmap *idmap, EXPORT_SYMBOL_GPL(__vfs_removexattr_locked); int -vfs_removexattr(struct mnt_idmap *idmap, struct dentry *dentry, - const char *name) +vfs_removexattr(const struct path *path, const char *name) { + struct dentry *dentry = path->dentry; struct inode *inode = dentry->d_inode; struct delegated_inode delegated_inode = { }; int error; retry_deleg: inode_lock(inode); - error = __vfs_removexattr_locked(idmap, dentry, - name, &delegated_inode); + error = __vfs_removexattr_locked(path, name, &delegated_inode); inode_unlock(inode); if (is_delegated(&delegated_inode)) { @@ -652,14 +657,13 @@ int setxattr_copy(const char __user *name, struct kernel_xattr_ctx *ctx) return error; } -static int do_setxattr(struct mnt_idmap *idmap, struct dentry *dentry, - struct kernel_xattr_ctx *ctx) +static int do_setxattr(const struct path *path, struct kernel_xattr_ctx *ctx) { if (is_posix_acl_xattr(ctx->kname->name)) - return do_set_acl(idmap, dentry, ctx->kname->name, - ctx->kvalue, ctx->size); + return do_set_acl(mnt_idmap(path->mnt), path->dentry, + ctx->kname->name, ctx->kvalue, ctx->size); - return vfs_setxattr(idmap, dentry, ctx->kname->name, + return vfs_setxattr(path, ctx->kname->name, ctx->kvalue, ctx->size, ctx->flags); } @@ -669,7 +673,7 @@ int file_setxattr(struct file *f, struct kernel_xattr_ctx *ctx) if (!error) { audit_file(f); - error = do_setxattr(file_mnt_idmap(f), f->f_path.dentry, ctx); + error = do_setxattr(&f->f_path, ctx); mnt_drop_write_file(f); } return error; @@ -687,7 +691,7 @@ int filename_setxattr(int dfd, struct filename *filename, return error; error = mnt_want_write(path.mnt); if (!error) { - error = do_setxattr(mnt_idmap(path.mnt), path.dentry, ctx); + error = do_setxattr(&path, ctx); mnt_drop_write(path.mnt); } path_put(&path); @@ -787,8 +791,7 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name, * Extended attribute GET operations */ static ssize_t -do_getxattr(struct mnt_idmap *idmap, struct dentry *d, - struct kernel_xattr_ctx *ctx) +do_getxattr(const struct path *path, struct kernel_xattr_ctx *ctx) { ssize_t error; char *kname = ctx->kname->name; @@ -803,9 +806,10 @@ do_getxattr(struct mnt_idmap *idmap, struct dentry *d, } if (is_posix_acl_xattr(kname)) - error = do_get_acl(idmap, d, kname, kvalue, ctx->size); + error = do_get_acl(mnt_idmap(path->mnt), path->dentry, + kname, kvalue, ctx->size); else - error = vfs_getxattr(idmap, d, kname, kvalue, ctx->size); + error = vfs_getxattr(path, kname, kvalue, ctx->size); if (error > 0) { if (ctx->size && copy_to_user(ctx->value, kvalue, error)) error = -EFAULT; @@ -822,7 +826,7 @@ do_getxattr(struct mnt_idmap *idmap, struct dentry *d, ssize_t file_getxattr(struct file *f, struct kernel_xattr_ctx *ctx) { audit_file(f); - return do_getxattr(file_mnt_idmap(f), f->f_path.dentry, ctx); + return do_getxattr(&f->f_path, ctx); } ssize_t filename_getxattr(int dfd, struct filename *filename, @@ -834,7 +838,7 @@ ssize_t filename_getxattr(int dfd, struct filename *filename, error = filename_lookup(dfd, filename, lookup_flags, &path, NULL); if (error) return error; - error = do_getxattr(mnt_idmap(path.mnt), path.dentry, ctx); + error = do_getxattr(&path, ctx); path_put(&path); if (retry_estale(error, lookup_flags)) { lookup_flags |= LOOKUP_REVAL; @@ -925,7 +929,7 @@ SYSCALL_DEFINE4(fgetxattr, int, fd, const char __user *, name, * Extended attribute LIST operations */ static ssize_t -listxattr(struct dentry *d, char __user *list, size_t size) +listxattr(const struct path *path, char __user *list, size_t size) { ssize_t error; char *klist = NULL; @@ -938,7 +942,7 @@ listxattr(struct dentry *d, char __user *list, size_t size) return -ENOMEM; } - error = vfs_listxattr(d, klist, size); + error = vfs_listxattr(path, klist, size); if (error > 0) { if (size && copy_to_user(list, klist, error)) error = -EFAULT; @@ -957,7 +961,7 @@ static ssize_t file_listxattr(struct file *f, char __user *list, size_t size) { audit_file(f); - return listxattr(f->f_path.dentry, list, size); + return listxattr(&f->f_path, list, size); } static @@ -971,7 +975,7 @@ ssize_t filename_listxattr(int dfd, struct filename *filename, error = filename_lookup(dfd, filename, lookup_flags, &path, NULL); if (error) return error; - error = listxattr(path.dentry, list, size); + error = listxattr(&path, list, size); path_put(&path); if (retry_estale(error, lookup_flags)) { lookup_flags |= LOOKUP_REVAL; @@ -1029,11 +1033,12 @@ SYSCALL_DEFINE3(flistxattr, int, fd, char __user *, list, size_t, size) * Extended attribute REMOVE operations */ static long -removexattr(struct mnt_idmap *idmap, struct dentry *d, const char *name) +removexattr(const struct path *path, const char *name) { if (is_posix_acl_xattr(name)) - return vfs_remove_acl(idmap, d, name); - return vfs_removexattr(idmap, d, name); + return vfs_remove_acl(mnt_idmap(path->mnt), path->dentry, + name); + return vfs_removexattr(path, name); } static int file_removexattr(struct file *f, struct xattr_name *kname) @@ -1042,8 +1047,7 @@ static int file_removexattr(struct file *f, struct xattr_name *kname) if (!error) { audit_file(f); - error = removexattr(file_mnt_idmap(f), - f->f_path.dentry, kname->name); + error = removexattr(&f->f_path, kname->name); mnt_drop_write_file(f); } return error; @@ -1061,7 +1065,7 @@ static int filename_removexattr(int dfd, struct filename *filename, return error; error = mnt_want_write(path.mnt); if (!error) { - error = removexattr(mnt_idmap(path.mnt), path.dentry, kname->name); + error = removexattr(&path, kname->name); mnt_drop_write(path.mnt); } path_put(&path); diff --git a/include/linux/xattr.h b/include/linux/xattr.h index 54ac3cbc133f..85042618fd81 100644 --- a/include/linux/xattr.h +++ b/include/linux/xattr.h @@ -77,22 +77,22 @@ struct xattr { }; ssize_t __vfs_getxattr(struct dentry *, struct inode *, const char *, void *, size_t); -ssize_t vfs_getxattr(struct mnt_idmap *, struct dentry *, const char *, - void *, size_t); -ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size); +ssize_t vfs_getxattr(const struct path *path, const char *name, void *value, + size_t size); +ssize_t vfs_listxattr(const struct path *path, char *list, size_t size); int __vfs_setxattr(struct mnt_idmap *, struct dentry *, struct inode *, const char *, const void *, size_t, int); int __vfs_setxattr_noperm(struct mnt_idmap *, struct dentry *, const char *, const void *, size_t, int); -int __vfs_setxattr_locked(struct mnt_idmap *, struct dentry *, - const char *, const void *, size_t, int, - struct delegated_inode *); -int vfs_setxattr(struct mnt_idmap *, struct dentry *, const char *, - const void *, size_t, int); +int __vfs_setxattr_locked(const struct path *path, const char *name, + const void *value, size_t size, int flags, + struct delegated_inode *delegated_inode); +int vfs_setxattr(const struct path *path, const char *name, + const void *value, size_t size, int flags); int __vfs_removexattr(struct mnt_idmap *, struct dentry *, const char *); -int __vfs_removexattr_locked(struct mnt_idmap *, struct dentry *, - const char *, struct delegated_inode *); -int vfs_removexattr(struct mnt_idmap *, struct dentry *, const char *); +int __vfs_removexattr_locked(const struct path *path, const char *name, + struct delegated_inode *delegated_inode); +int vfs_removexattr(const struct path *path, const char *name); ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size); int vfs_getxattr_alloc(struct mnt_idmap *idmap, diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c index 1c41af2f91a6..3d759efd3c6c 100644 --- a/security/integrity/evm/evm_crypto.c +++ b/security/integrity/evm/evm_crypto.c @@ -237,7 +237,7 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry, size_t xattr_size = 0; char *xattr_value = NULL; int error; - int size, user_space_size; + int size; bool ima_present = false; u64 i_version = 0; @@ -287,12 +287,6 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry, if (size < 0) continue; - user_space_size = vfs_getxattr(&nop_mnt_idmap, dentry, - xattr->name, NULL, 0); - if (user_space_size != size) - pr_debug("file %s: xattr %s size mismatch (kernel: %d, user: %d)\n", - dentry->d_name.name, xattr->name, size, - user_space_size); error = 0; xattr_size = size; crypto_shash_update(desc, (const u8 *)xattr_value, xattr_size); diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 8af024fe4fb5..1d06b08f3c41 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -7168,8 +7168,8 @@ static int selinux_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen */ static int selinux_inode_setsecctx(const struct path *path, void *ctx, u32 ctxlen) { - return __vfs_setxattr_locked(&nop_mnt_idmap, path->dentry, - XATTR_NAME_SELINUX, ctx, ctxlen, 0, NULL); + return __vfs_setxattr_locked(path, XATTR_NAME_SELINUX, + ctx, ctxlen, 0, NULL); } static int selinux_inode_getsecctx(struct inode *inode, struct lsm_context *cp) diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index d9e9f4a52567..e517809c230d 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -4980,8 +4980,8 @@ static int smack_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) static int smack_inode_setsecctx(const struct path *path, void *ctx, u32 ctxlen) { - return __vfs_setxattr_locked(&nop_mnt_idmap, path->dentry, - XATTR_NAME_SMACK, ctx, ctxlen, 0, NULL); + return __vfs_setxattr_locked(path, XATTR_NAME_SMACK, + ctx, ctxlen, 0, NULL); } static int smack_inode_getsecctx(struct inode *inode, struct lsm_context *cp) -- 2.18.0.huawei.25

