diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index e8649f4d9fcd..be6463e238f1 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c @@ -365,6 +365,21 @@ out: return err; } +int __ovl_xattr_get(struct dentry *dentry, struct inode *inode, + const char *name, void *value, size_t size) +{ + ssize_t res; + const struct cred *old_cred; + struct dentry *realdentry = + ovl_i_dentry_upper(inode) ?: ovl_dentry_lower(dentry); + + old_cred = ovl_override_creds(dentry->d_sb); + res = __vfs_getxattr(realdentry, d_inode(realdentry), name, value, + size); + ovl_revert_creds(old_cred); + return res; +} + int ovl_xattr_get(struct dentry *dentry, struct inode *inode, const char *name, void *value, size_t size) { diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index 8a3b11aca02d..25b31fcc8072 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -351,6 +351,8 @@ int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char *name, const void *value, size_t size, int flags); int ovl_xattr_get(struct dentry *dentry, struct inode *inode, const char *name, void *value, size_t size); +int __ovl_xattr_get(struct dentry *dentry, struct inode *inode, + const char *name, void *value, size_t size); ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size); struct posix_acl *ovl_get_acl(struct inode *inode, int type); int ovl_update_time(struct inode *inode, struct timespec64 *ts, int flags); diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 8805844fa323..e4f7298c64b3 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -885,6 +885,14 @@ ovl_posix_acl_xattr_get(const struct xattr_handler *handler, return ovl_xattr_get(dentry, inode, handler->name, buffer, size); } +static int __maybe_unused +__ovl_posix_acl_xattr_get(const struct xattr_handler *handler, + struct dentry *dentry, struct inode *inode, + const char *name, void *buffer, size_t size) +{ + return __ovl_xattr_get(dentry, inode, handler->name, buffer, size); +} + static int __maybe_unused ovl_posix_acl_xattr_set(const struct xattr_handler *handler, struct dentry *dentry, struct inode *inode, @@ -965,6 +973,13 @@ static int ovl_other_xattr_get(const struct xattr_handler *handler, return ovl_xattr_get(dentry, inode, name, buffer, size); } +static int __ovl_other_xattr_get(const struct xattr_handler *handler, + struct dentry *dentry, struct inode *inode, + const char *name, void *buffer, size_t size) +{ + return __ovl_xattr_get(dentry, inode, name, buffer, size); +} + static int ovl_other_xattr_set(const struct xattr_handler *handler, struct dentry *dentry, struct inode *inode, const char *name, const void *value, @@ -978,6 +993,7 @@ ovl_posix_acl_access_xattr_handler = { .name = XATTR_NAME_POSIX_ACL_ACCESS, .flags = ACL_TYPE_ACCESS, .get = ovl_posix_acl_xattr_get, + .__get = __ovl_posix_acl_xattr_get, .set = ovl_posix_acl_xattr_set, }; @@ -986,6 +1002,7 @@ ovl_posix_acl_default_xattr_handler = { .name = XATTR_NAME_POSIX_ACL_DEFAULT, .flags = ACL_TYPE_DEFAULT, .get = ovl_posix_acl_xattr_get, + .__get = __ovl_posix_acl_xattr_get, .set = ovl_posix_acl_xattr_set, }; @@ -998,6 +1015,7 @@ static const struct xattr_handler ovl_own_xattr_handler = { static const struct xattr_handler ovl_other_xattr_handler = { .prefix = "", /* catch all */ .get = ovl_other_xattr_get, + .__get = __ovl_other_xattr_get, .set = ovl_other_xattr_set, };