| From 2a8bb66be583910a2f25a89b12adf0a2f822e9b7 Mon Sep 17 00:00:00 2001 |
| From: Mark Salyzyn <salyzyn@google.com> |
| Date: Mon, 4 Nov 2019 08:57:10 -0800 |
| Subject: [PATCH] FROMLIST: Add flags option to get xattr method paired to |
| __vfs_getxattr |
| |
| Add a flag option to get xattr method that could have a bit flag of |
| XATTR_NOSECURITY passed to it. XATTR_NOSECURITY is generally then |
| set in the __vfs_getxattr path when called by security |
| infrastructure. |
| |
| This handles the case of a union filesystem driver that is being |
| requested by the security layer to report back the xattr data. |
| |
| For the use case where access is to be blocked by the security layer. |
| |
| The path then could be security(dentry) -> |
| __vfs_getxattr(dentry...XATTR_NOSECURITY) -> |
| handler->get(dentry...XATTR_NOSECURITY) -> |
| __vfs_getxattr(lower_dentry...XATTR_NOSECURITY) -> |
| lower_handler->get(lower_dentry...XATTR_NOSECURITY) |
| which would report back through the chain data and success as |
| expected, the logging security layer at the top would have the |
| data to determine the access permissions and report back the target |
| context that was blocked. |
| |
| Without the get handler flag, the path on a union filesystem would be |
| the errant security(dentry) -> __vfs_getxattr(dentry) -> |
| handler->get(dentry) -> vfs_getxattr(lower_dentry) -> nested -> |
| security(lower_dentry, log off) -> lower_handler->get(lower_dentry) |
| which would report back through the chain no data, and -EACCES. |
| |
| For selinux for both cases, this would translate to a correctly |
| determined blocked access. In the first case with this change a correct avc |
| log would be reported, in the second legacy case an incorrect avc log |
| would be reported against an uninitialized u:object_r:unlabeled:s0 |
| context making the logs cosmetically useless for audit2allow. |
| |
| This patch series is inert and is the wide-spread addition of the |
| flags option for xattr functions, and a replacement of __vfs_getxattr |
| with __vfs_getxattr(...XATTR_NOSECURITY). |
| |
| Signed-off-by: Mark Salyzyn <salyzyn@android.com> |
| Reviewed-by: Jan Kara <jack@suse.cz> |
| Acked-by: Jan Kara <jack@suse.cz> |
| Acked-by: Jeff Layton <jlayton@kernel.org> |
| Acked-by: David Sterba <dsterba@suse.com> |
| Acked-by: Darrick J. Wong <darrick.wong@oracle.com> |
| Acked-by: Mike Marshall <hubcap@omnibond.com> |
| Cc: Stephen Smalley <sds@tycho.nsa.gov> |
| Cc: linux-kernel@vger.kernel.org |
| Cc: kernel-team@android.com |
| Cc: linux-security-module@vger.kernel.org |
| |
| (cherry picked from (rejected from archive because of too many recipients)) |
| Signed-off-by: Mark Salyzyn <salyzyn@google.com> |
| Bug: 133515582 |
| Bug: 136124883 |
| Bug: 129319403 |
| Change-Id: Iabbb8771939d5f66667a26bb23ddf4c562c349a1 |
| |
| Conflicts: |
| security/integrity/evm/evm_main.c |
| [rebase510(groeck): Context conflicts] |
| Signed-off-by: Guenter Roeck <groeck@chromium.org> |
| --- |
| Documentation/filesystems/locking.rst | 2 +- |
| fs/9p/acl.c | 3 +- |
| fs/9p/xattr.c | 3 +- |
| fs/afs/xattr.c | 10 +++---- |
| fs/btrfs/xattr.c | 3 +- |
| fs/ceph/xattr.c | 3 +- |
| fs/cifs/xattr.c | 2 +- |
| fs/ecryptfs/inode.c | 6 ++-- |
| fs/ecryptfs/mmap.c | 5 ++-- |
| fs/erofs/xattr.c | 3 +- |
| fs/ext2/xattr_security.c | 2 +- |
| fs/ext2/xattr_trusted.c | 2 +- |
| fs/ext2/xattr_user.c | 2 +- |
| fs/ext4/xattr_security.c | 2 +- |
| fs/ext4/xattr_trusted.c | 2 +- |
| fs/ext4/xattr_user.c | 2 +- |
| fs/f2fs/xattr.c | 4 +-- |
| fs/fuse/xattr.c | 4 +-- |
| fs/gfs2/xattr.c | 3 +- |
| fs/hfs/attr.c | 2 +- |
| fs/hfsplus/xattr.c | 3 +- |
| fs/hfsplus/xattr_security.c | 3 +- |
| fs/hfsplus/xattr_trusted.c | 3 +- |
| fs/hfsplus/xattr_user.c | 3 +- |
| fs/jffs2/security.c | 3 +- |
| fs/jffs2/xattr_trusted.c | 3 +- |
| fs/jffs2/xattr_user.c | 3 +- |
| fs/jfs/xattr.c | 5 ++-- |
| fs/kernfs/inode.c | 3 +- |
| fs/nfs/nfs4proc.c | 6 ++-- |
| fs/ocfs2/xattr.c | 9 ++++-- |
| fs/orangefs/xattr.c | 3 +- |
| fs/overlayfs/super.c | 8 ++++-- |
| fs/posix_acl.c | 2 +- |
| fs/reiserfs/xattr_security.c | 3 +- |
| fs/reiserfs/xattr_trusted.c | 3 +- |
| fs/reiserfs/xattr_user.c | 3 +- |
| fs/squashfs/xattr.c | 2 +- |
| fs/ubifs/xattr.c | 3 +- |
| fs/xattr.c | 41 ++++++++++++++------------- |
| fs/xfs/xfs_xattr.c | 3 +- |
| include/linux/xattr.h | 9 +++--- |
| include/uapi/linux/xattr.h | 7 +++-- |
| mm/shmem.c | 3 +- |
| net/socket.c | 3 +- |
| security/commoncap.c | 8 ++++-- |
| security/integrity/evm/evm_main.c | 4 ++- |
| security/selinux/hooks.c | 16 +++++++---- |
| security/smack/smack_lsm.c | 7 +++-- |
| 49 files changed, 143 insertions(+), 94 deletions(-) |
| |
| diff --git a/Documentation/filesystems/locking.rst b/Documentation/filesystems/locking.rst |
| index b7dcc86c92a4..ef5e6c20c4ba 100644 |
| --- a/Documentation/filesystems/locking.rst |
| +++ b/Documentation/filesystems/locking.rst |
| @@ -125,7 +125,7 @@ prototypes:: |
| bool (*list)(struct dentry *dentry); |
| int (*get)(const struct xattr_handler *handler, struct dentry *dentry, |
| struct inode *inode, const char *name, void *buffer, |
| - size_t size); |
| + size_t size, int flags); |
| int (*set)(const struct xattr_handler *handler, |
| struct user_namespace *mnt_userns, |
| struct dentry *dentry, struct inode *inode, const char *name, |
| diff --git a/fs/9p/acl.c b/fs/9p/acl.c |
| index bb1b286c49ae..675086d728fb 100644 |
| --- a/fs/9p/acl.c |
| +++ b/fs/9p/acl.c |
| @@ -214,7 +214,8 @@ int v9fs_acl_mode(struct inode *dir, umode_t *modep, |
| |
| static int v9fs_xattr_get_acl(const struct xattr_handler *handler, |
| struct dentry *dentry, struct inode *inode, |
| - const char *name, void *buffer, size_t size) |
| + const char *name, void *buffer, size_t size, |
| + int flags) |
| { |
| struct v9fs_session_info *v9ses; |
| struct posix_acl *acl; |
| diff --git a/fs/9p/xattr.c b/fs/9p/xattr.c |
| index ee331845e2c7..57f88b9ae8ef 100644 |
| --- a/fs/9p/xattr.c |
| +++ b/fs/9p/xattr.c |
| @@ -149,7 +149,8 @@ ssize_t v9fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) |
| |
| static int v9fs_xattr_handler_get(const struct xattr_handler *handler, |
| struct dentry *dentry, struct inode *inode, |
| - const char *name, void *buffer, size_t size) |
| + const char *name, void *buffer, size_t size, |
| + int flags) |
| { |
| const char *full_name = xattr_full_name(handler, name); |
| |
| diff --git a/fs/afs/xattr.c b/fs/afs/xattr.c |
| index 7751b0b3f81d..172013d3e0dd 100644 |
| --- a/fs/afs/xattr.c |
| +++ b/fs/afs/xattr.c |
| @@ -36,7 +36,7 @@ static const struct afs_operation_ops afs_fetch_acl_operation = { |
| static int afs_xattr_get_acl(const struct xattr_handler *handler, |
| struct dentry *dentry, |
| struct inode *inode, const char *name, |
| - void *buffer, size_t size) |
| + void *buffer, size_t size, int flags) |
| { |
| struct afs_operation *op; |
| struct afs_vnode *vnode = AFS_FS_I(inode); |
| @@ -138,7 +138,7 @@ static const struct afs_operation_ops yfs_fetch_opaque_acl_operation = { |
| static int afs_xattr_get_yfs(const struct xattr_handler *handler, |
| struct dentry *dentry, |
| struct inode *inode, const char *name, |
| - void *buffer, size_t size) |
| + void *buffer, size_t size, int flags) |
| { |
| struct afs_operation *op; |
| struct afs_vnode *vnode = AFS_FS_I(inode); |
| @@ -268,7 +268,7 @@ static const struct xattr_handler afs_xattr_yfs_handler = { |
| static int afs_xattr_get_cell(const struct xattr_handler *handler, |
| struct dentry *dentry, |
| struct inode *inode, const char *name, |
| - void *buffer, size_t size) |
| + void *buffer, size_t size, int flags) |
| { |
| struct afs_vnode *vnode = AFS_FS_I(inode); |
| struct afs_cell *cell = vnode->volume->cell; |
| @@ -295,7 +295,7 @@ static const struct xattr_handler afs_xattr_afs_cell_handler = { |
| static int afs_xattr_get_fid(const struct xattr_handler *handler, |
| struct dentry *dentry, |
| struct inode *inode, const char *name, |
| - void *buffer, size_t size) |
| + void *buffer, size_t size, int flags) |
| { |
| struct afs_vnode *vnode = AFS_FS_I(inode); |
| char text[16 + 1 + 24 + 1 + 8 + 1]; |
| @@ -333,7 +333,7 @@ static const struct xattr_handler afs_xattr_afs_fid_handler = { |
| static int afs_xattr_get_volume(const struct xattr_handler *handler, |
| struct dentry *dentry, |
| struct inode *inode, const char *name, |
| - void *buffer, size_t size) |
| + void *buffer, size_t size, int flags) |
| { |
| struct afs_vnode *vnode = AFS_FS_I(inode); |
| const char *volname = vnode->volume->name; |
| diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c |
| index 8a4514283a4b..ee68273fdc0a 100644 |
| --- a/fs/btrfs/xattr.c |
| +++ b/fs/btrfs/xattr.c |
| @@ -378,7 +378,8 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size) |
| |
| static int btrfs_xattr_handler_get(const struct xattr_handler *handler, |
| struct dentry *unused, struct inode *inode, |
| - const char *name, void *buffer, size_t size) |
| + const char *name, void *buffer, size_t size, |
| + int flags) |
| { |
| name = xattr_full_name(handler, name); |
| return btrfs_getxattr(inode, name, buffer, size); |
| diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c |
| index 02f59bcb4f27..c7c0760f6143 100644 |
| --- a/fs/ceph/xattr.c |
| +++ b/fs/ceph/xattr.c |
| @@ -1230,7 +1230,8 @@ int __ceph_setxattr(struct inode *inode, const char *name, |
| |
| static int ceph_get_xattr_handler(const struct xattr_handler *handler, |
| struct dentry *dentry, struct inode *inode, |
| - const char *name, void *value, size_t size) |
| + const char *name, void *value, size_t size, |
| + int flags) |
| { |
| if (!ceph_is_valid_xattr(name)) |
| return -EOPNOTSUPP; |
| diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c |
| index 41a611e76bb7..6314ed1b6802 100644 |
| --- a/fs/cifs/xattr.c |
| +++ b/fs/cifs/xattr.c |
| @@ -289,7 +289,7 @@ static int cifs_creation_time_get(struct dentry *dentry, struct inode *inode, |
| |
| static int cifs_xattr_get(const struct xattr_handler *handler, |
| struct dentry *dentry, struct inode *inode, |
| - const char *name, void *value, size_t size) |
| + const char *name, void *value, size_t size, int flags) |
| { |
| ssize_t rc = -EOPNOTSUPP; |
| unsigned int xid; |
| diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c |
| index 18e9285fbb4c..86897016cb26 100644 |
| --- a/fs/ecryptfs/inode.c |
| +++ b/fs/ecryptfs/inode.c |
| @@ -1065,7 +1065,8 @@ ecryptfs_getxattr_lower(struct dentry *lower_dentry, struct inode *lower_inode, |
| goto out; |
| } |
| inode_lock(lower_inode); |
| - rc = __vfs_getxattr(lower_dentry, lower_inode, name, value, size); |
| + rc = __vfs_getxattr(&init_user_ns, lower_dentry, lower_inode, name, |
| + value, size, XATTR_NOSECURITY); |
| inode_unlock(lower_inode); |
| out: |
| return rc; |
| @@ -1150,7 +1151,8 @@ const struct inode_operations ecryptfs_main_iops = { |
| |
| static int ecryptfs_xattr_get(const struct xattr_handler *handler, |
| struct dentry *dentry, struct inode *inode, |
| - const char *name, void *buffer, size_t size) |
| + const char *name, void *buffer, size_t size, |
| + int flags) |
| { |
| return ecryptfs_getxattr(dentry, inode, name, buffer, size); |
| } |
| diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c |
| index 2f333a40ff4d..b24cbb6eb7bf 100644 |
| --- a/fs/ecryptfs/mmap.c |
| +++ b/fs/ecryptfs/mmap.c |
| @@ -421,8 +421,9 @@ static int ecryptfs_write_inode_size_to_xattr(struct inode *ecryptfs_inode) |
| goto out; |
| } |
| inode_lock(lower_inode); |
| - size = __vfs_getxattr(lower_dentry, lower_inode, ECRYPTFS_XATTR_NAME, |
| - xattr_virt, PAGE_SIZE); |
| + size = __vfs_getxattr(&init_user_ns, lower_dentry, lower_inode, |
| + ECRYPTFS_XATTR_NAME, xattr_virt, PAGE_SIZE, |
| + XATTR_NOSECURITY); |
| if (size < 0) |
| size = 8; |
| put_unaligned_be64(i_size_read(ecryptfs_inode), xattr_virt); |
| diff --git a/fs/erofs/xattr.c b/fs/erofs/xattr.c |
| index 47314a26767a..6330bca9d91d 100644 |
| --- a/fs/erofs/xattr.c |
| +++ b/fs/erofs/xattr.c |
| @@ -471,7 +471,8 @@ int erofs_getxattr(struct inode *inode, int index, |
| |
| static int erofs_xattr_generic_get(const struct xattr_handler *handler, |
| struct dentry *unused, struct inode *inode, |
| - const char *name, void *buffer, size_t size) |
| + const char *name, void *buffer, size_t size, |
| + int flags) |
| { |
| struct erofs_sb_info *const sbi = EROFS_I_SB(inode); |
| |
| diff --git a/fs/ext2/xattr_security.c b/fs/ext2/xattr_security.c |
| index ebade1f52451..91c716ec140f 100644 |
| --- a/fs/ext2/xattr_security.c |
| +++ b/fs/ext2/xattr_security.c |
| @@ -11,7 +11,7 @@ |
| static int |
| ext2_xattr_security_get(const struct xattr_handler *handler, |
| struct dentry *unused, struct inode *inode, |
| - const char *name, void *buffer, size_t size) |
| + const char *name, void *buffer, size_t size, int flags) |
| { |
| return ext2_xattr_get(inode, EXT2_XATTR_INDEX_SECURITY, name, |
| buffer, size); |
| diff --git a/fs/ext2/xattr_trusted.c b/fs/ext2/xattr_trusted.c |
| index 18a87d5dd1ab..362f83e43c4c 100644 |
| --- a/fs/ext2/xattr_trusted.c |
| +++ b/fs/ext2/xattr_trusted.c |
| @@ -18,7 +18,7 @@ ext2_xattr_trusted_list(struct dentry *dentry) |
| static int |
| ext2_xattr_trusted_get(const struct xattr_handler *handler, |
| struct dentry *unused, struct inode *inode, |
| - const char *name, void *buffer, size_t size) |
| + const char *name, void *buffer, size_t size, int flags) |
| { |
| return ext2_xattr_get(inode, EXT2_XATTR_INDEX_TRUSTED, name, |
| buffer, size); |
| diff --git a/fs/ext2/xattr_user.c b/fs/ext2/xattr_user.c |
| index 58092449f8ff..37936d5979c8 100644 |
| --- a/fs/ext2/xattr_user.c |
| +++ b/fs/ext2/xattr_user.c |
| @@ -20,7 +20,7 @@ ext2_xattr_user_list(struct dentry *dentry) |
| static int |
| ext2_xattr_user_get(const struct xattr_handler *handler, |
| struct dentry *unused, struct inode *inode, |
| - const char *name, void *buffer, size_t size) |
| + const char *name, void *buffer, size_t size, int flags) |
| { |
| if (!test_opt(inode->i_sb, XATTR_USER)) |
| return -EOPNOTSUPP; |
| diff --git a/fs/ext4/xattr_security.c b/fs/ext4/xattr_security.c |
| index 8213f66f7b2d..f85699f6ad17 100644 |
| --- a/fs/ext4/xattr_security.c |
| +++ b/fs/ext4/xattr_security.c |
| @@ -15,7 +15,7 @@ |
| static int |
| ext4_xattr_security_get(const struct xattr_handler *handler, |
| struct dentry *unused, struct inode *inode, |
| - const char *name, void *buffer, size_t size) |
| + const char *name, void *buffer, size_t size, int flags) |
| { |
| return ext4_xattr_get(inode, EXT4_XATTR_INDEX_SECURITY, |
| name, buffer, size); |
| diff --git a/fs/ext4/xattr_trusted.c b/fs/ext4/xattr_trusted.c |
| index 7c21ffb26d25..9b550a8a5c0b 100644 |
| --- a/fs/ext4/xattr_trusted.c |
| +++ b/fs/ext4/xattr_trusted.c |
| @@ -22,7 +22,7 @@ ext4_xattr_trusted_list(struct dentry *dentry) |
| static int |
| ext4_xattr_trusted_get(const struct xattr_handler *handler, |
| struct dentry *unused, struct inode *inode, |
| - const char *name, void *buffer, size_t size) |
| + const char *name, void *buffer, size_t size, int flags) |
| { |
| return ext4_xattr_get(inode, EXT4_XATTR_INDEX_TRUSTED, |
| name, buffer, size); |
| diff --git a/fs/ext4/xattr_user.c b/fs/ext4/xattr_user.c |
| index 2fe7ff0a479c..5483b158c5b5 100644 |
| --- a/fs/ext4/xattr_user.c |
| +++ b/fs/ext4/xattr_user.c |
| @@ -21,7 +21,7 @@ ext4_xattr_user_list(struct dentry *dentry) |
| static int |
| ext4_xattr_user_get(const struct xattr_handler *handler, |
| struct dentry *unused, struct inode *inode, |
| - const char *name, void *buffer, size_t size) |
| + const char *name, void *buffer, size_t size, int flags) |
| { |
| if (!test_opt(inode->i_sb, XATTR_USER)) |
| return -EOPNOTSUPP; |
| diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c |
| index 490f843ec3bf..a69a0588539b 100644 |
| --- a/fs/f2fs/xattr.c |
| +++ b/fs/f2fs/xattr.c |
| @@ -44,7 +44,7 @@ static void xattr_free(struct f2fs_sb_info *sbi, void *xattr_addr, |
| |
| static int f2fs_xattr_generic_get(const struct xattr_handler *handler, |
| struct dentry *unused, struct inode *inode, |
| - const char *name, void *buffer, size_t size) |
| + const char *name, void *buffer, size_t size, int flags) |
| { |
| struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); |
| |
| @@ -100,7 +100,7 @@ static bool f2fs_xattr_trusted_list(struct dentry *dentry) |
| |
| static int f2fs_xattr_advise_get(const struct xattr_handler *handler, |
| struct dentry *unused, struct inode *inode, |
| - const char *name, void *buffer, size_t size) |
| + const char *name, void *buffer, size_t size, int flags) |
| { |
| if (buffer) |
| *((char *)buffer) = F2FS_I(inode)->i_advise; |
| diff --git a/fs/fuse/xattr.c b/fs/fuse/xattr.c |
| index 1a7d7ace54e1..dc890e12997e 100644 |
| --- a/fs/fuse/xattr.c |
| +++ b/fs/fuse/xattr.c |
| @@ -179,7 +179,7 @@ int fuse_removexattr(struct inode *inode, const char *name) |
| |
| static int fuse_xattr_get(const struct xattr_handler *handler, |
| struct dentry *dentry, struct inode *inode, |
| - const char *name, void *value, size_t size) |
| + const char *name, void *value, size_t size, int flags) |
| { |
| if (fuse_is_bad(inode)) |
| return -EIO; |
| @@ -209,7 +209,7 @@ static bool no_xattr_list(struct dentry *dentry) |
| |
| static int no_xattr_get(const struct xattr_handler *handler, |
| struct dentry *dentry, struct inode *inode, |
| - const char *name, void *value, size_t size) |
| + const char *name, void *value, size_t size, int flags) |
| { |
| return -EOPNOTSUPP; |
| } |
| diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c |
| index 124b3d5a7266..617f83de2614 100644 |
| --- a/fs/gfs2/xattr.c |
| +++ b/fs/gfs2/xattr.c |
| @@ -610,7 +610,8 @@ static int __gfs2_xattr_get(struct inode *inode, const char *name, |
| |
| static int gfs2_xattr_get(const struct xattr_handler *handler, |
| struct dentry *unused, struct inode *inode, |
| - const char *name, void *buffer, size_t size) |
| + const char *name, void *buffer, size_t size, |
| + int flags) |
| { |
| struct gfs2_inode *ip = GFS2_I(inode); |
| struct gfs2_holder gh; |
| diff --git a/fs/hfs/attr.c b/fs/hfs/attr.c |
| index 2bd54efaf416..c42385c33d2a 100644 |
| --- a/fs/hfs/attr.c |
| +++ b/fs/hfs/attr.c |
| @@ -115,7 +115,7 @@ static ssize_t __hfs_getxattr(struct inode *inode, enum hfs_xattr_type type, |
| |
| static int hfs_xattr_get(const struct xattr_handler *handler, |
| struct dentry *unused, struct inode *inode, |
| - const char *name, void *value, size_t size) |
| + const char *name, void *value, size_t size, int flags) |
| { |
| return __hfs_getxattr(inode, handler->flags, value, size); |
| } |
| diff --git a/fs/hfsplus/xattr.c b/fs/hfsplus/xattr.c |
| index 4d169c5a2673..67b9d4a94616 100644 |
| --- a/fs/hfsplus/xattr.c |
| +++ b/fs/hfsplus/xattr.c |
| @@ -839,7 +839,8 @@ static int hfsplus_removexattr(struct inode *inode, const char *name) |
| |
| static int hfsplus_osx_getxattr(const struct xattr_handler *handler, |
| struct dentry *unused, struct inode *inode, |
| - const char *name, void *buffer, size_t size) |
| + const char *name, void *buffer, size_t size, |
| + int flags) |
| { |
| /* |
| * Don't allow retrieving properly prefixed attributes |
| diff --git a/fs/hfsplus/xattr_security.c b/fs/hfsplus/xattr_security.c |
| index c1c7a16cbf21..1b28b83c201e 100644 |
| --- a/fs/hfsplus/xattr_security.c |
| +++ b/fs/hfsplus/xattr_security.c |
| @@ -15,7 +15,8 @@ |
| |
| static int hfsplus_security_getxattr(const struct xattr_handler *handler, |
| struct dentry *unused, struct inode *inode, |
| - const char *name, void *buffer, size_t size) |
| + const char *name, void *buffer, |
| + size_t size, int flags) |
| { |
| return hfsplus_getxattr(inode, name, buffer, size, |
| XATTR_SECURITY_PREFIX, |
| diff --git a/fs/hfsplus/xattr_trusted.c b/fs/hfsplus/xattr_trusted.c |
| index e150372ec564..7caeff6243d7 100644 |
| --- a/fs/hfsplus/xattr_trusted.c |
| +++ b/fs/hfsplus/xattr_trusted.c |
| @@ -14,7 +14,8 @@ |
| |
| static int hfsplus_trusted_getxattr(const struct xattr_handler *handler, |
| struct dentry *unused, struct inode *inode, |
| - const char *name, void *buffer, size_t size) |
| + const char *name, void *buffer, |
| + size_t size, int flags) |
| { |
| return hfsplus_getxattr(inode, name, buffer, size, |
| XATTR_TRUSTED_PREFIX, |
| diff --git a/fs/hfsplus/xattr_user.c b/fs/hfsplus/xattr_user.c |
| index a6b60b153916..ca74443eb123 100644 |
| --- a/fs/hfsplus/xattr_user.c |
| +++ b/fs/hfsplus/xattr_user.c |
| @@ -14,7 +14,8 @@ |
| |
| static int hfsplus_user_getxattr(const struct xattr_handler *handler, |
| struct dentry *unused, struct inode *inode, |
| - const char *name, void *buffer, size_t size) |
| + const char *name, void *buffer, size_t size, |
| + int flags) |
| { |
| |
| return hfsplus_getxattr(inode, name, buffer, size, |
| diff --git a/fs/jffs2/security.c b/fs/jffs2/security.c |
| index aef5522551db..c443c4e47208 100644 |
| --- a/fs/jffs2/security.c |
| +++ b/fs/jffs2/security.c |
| @@ -50,7 +50,8 @@ int jffs2_init_security(struct inode *inode, struct inode *dir, |
| /* ---- XATTR Handler for "security.*" ----------------- */ |
| static int jffs2_security_getxattr(const struct xattr_handler *handler, |
| struct dentry *unused, struct inode *inode, |
| - const char *name, void *buffer, size_t size) |
| + const char *name, void *buffer, size_t size, |
| + int flags) |
| { |
| return do_jffs2_getxattr(inode, JFFS2_XPREFIX_SECURITY, |
| name, buffer, size); |
| diff --git a/fs/jffs2/xattr_trusted.c b/fs/jffs2/xattr_trusted.c |
| index cc3f24883e7d..95ed9ce1eaaf 100644 |
| --- a/fs/jffs2/xattr_trusted.c |
| +++ b/fs/jffs2/xattr_trusted.c |
| @@ -18,7 +18,8 @@ |
| |
| static int jffs2_trusted_getxattr(const struct xattr_handler *handler, |
| struct dentry *unused, struct inode *inode, |
| - const char *name, void *buffer, size_t size) |
| + const char *name, void *buffer, size_t size, |
| + int flags) |
| { |
| return do_jffs2_getxattr(inode, JFFS2_XPREFIX_TRUSTED, |
| name, buffer, size); |
| diff --git a/fs/jffs2/xattr_user.c b/fs/jffs2/xattr_user.c |
| index fb945977c013..418bb8d2758f 100644 |
| --- a/fs/jffs2/xattr_user.c |
| +++ b/fs/jffs2/xattr_user.c |
| @@ -18,7 +18,8 @@ |
| |
| static int jffs2_user_getxattr(const struct xattr_handler *handler, |
| struct dentry *unused, struct inode *inode, |
| - const char *name, void *buffer, size_t size) |
| + const char *name, void *buffer, size_t size, |
| + int flags) |
| { |
| return do_jffs2_getxattr(inode, JFFS2_XPREFIX_USER, |
| name, buffer, size); |
| diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c |
| index f9273f6901c8..8728df337090 100644 |
| --- a/fs/jfs/xattr.c |
| +++ b/fs/jfs/xattr.c |
| @@ -925,7 +925,7 @@ static int __jfs_xattr_set(struct inode *inode, const char *name, |
| |
| static int jfs_xattr_get(const struct xattr_handler *handler, |
| struct dentry *unused, struct inode *inode, |
| - const char *name, void *value, size_t size) |
| + const char *name, void *value, size_t size, int flags) |
| { |
| name = xattr_full_name(handler, name); |
| return __jfs_getxattr(inode, name, value, size); |
| @@ -943,7 +943,8 @@ static int jfs_xattr_set(const struct xattr_handler *handler, |
| |
| static int jfs_xattr_get_os2(const struct xattr_handler *handler, |
| struct dentry *unused, struct inode *inode, |
| - const char *name, void *value, size_t size) |
| + const char *name, void *value, size_t size, |
| + int flags) |
| { |
| if (is_known_namespace(name)) |
| return -EOPNOTSUPP; |
| diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c |
| index d73950fc3d57..cfe021032c0c 100644 |
| --- a/fs/kernfs/inode.c |
| +++ b/fs/kernfs/inode.c |
| @@ -313,7 +313,8 @@ int kernfs_xattr_set(struct kernfs_node *kn, const char *name, |
| |
| static int kernfs_vfs_xattr_get(const struct xattr_handler *handler, |
| struct dentry *unused, struct inode *inode, |
| - const char *suffix, void *value, size_t size) |
| + const char *suffix, void *value, size_t size, |
| + int flags) |
| { |
| const char *name = xattr_full_name(handler, suffix); |
| struct kernfs_node *kn = inode->i_private; |
| diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c |
| index c65c4b41e2c1..32174a2a1a26 100644 |
| --- a/fs/nfs/nfs4proc.c |
| +++ b/fs/nfs/nfs4proc.c |
| @@ -7498,7 +7498,8 @@ static int nfs4_xattr_set_nfs4_acl(const struct xattr_handler *handler, |
| |
| static int nfs4_xattr_get_nfs4_acl(const struct xattr_handler *handler, |
| struct dentry *unused, struct inode *inode, |
| - const char *key, void *buf, size_t buflen) |
| + const char *key, void *buf, size_t buflen, |
| + int flags) |
| { |
| return nfs4_proc_get_acl(inode, buf, buflen); |
| } |
| @@ -7524,7 +7525,8 @@ static int nfs4_xattr_set_nfs4_label(const struct xattr_handler *handler, |
| |
| static int nfs4_xattr_get_nfs4_label(const struct xattr_handler *handler, |
| struct dentry *unused, struct inode *inode, |
| - const char *key, void *buf, size_t buflen) |
| + const char *key, void *buf, size_t buflen, |
| + int flags) |
| { |
| if (security_ismaclabel(key)) |
| return nfs4_get_security_label(inode, buf, buflen); |
| diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c |
| index 36ae47a4aef6..a0adc5ba37a1 100644 |
| --- a/fs/ocfs2/xattr.c |
| +++ b/fs/ocfs2/xattr.c |
| @@ -7242,7 +7242,8 @@ int ocfs2_init_security_and_acl(struct inode *dir, |
| */ |
| static int ocfs2_xattr_security_get(const struct xattr_handler *handler, |
| struct dentry *unused, struct inode *inode, |
| - const char *name, void *buffer, size_t size) |
| + const char *name, void *buffer, size_t size, |
| + int flags) |
| { |
| return ocfs2_xattr_get(inode, OCFS2_XATTR_INDEX_SECURITY, |
| name, buffer, size); |
| @@ -7315,7 +7316,8 @@ const struct xattr_handler ocfs2_xattr_security_handler = { |
| */ |
| static int ocfs2_xattr_trusted_get(const struct xattr_handler *handler, |
| struct dentry *unused, struct inode *inode, |
| - const char *name, void *buffer, size_t size) |
| + const char *name, void *buffer, size_t size, |
| + int flags) |
| { |
| return ocfs2_xattr_get(inode, OCFS2_XATTR_INDEX_TRUSTED, |
| name, buffer, size); |
| @@ -7342,7 +7344,8 @@ const struct xattr_handler ocfs2_xattr_trusted_handler = { |
| */ |
| static int ocfs2_xattr_user_get(const struct xattr_handler *handler, |
| struct dentry *unused, struct inode *inode, |
| - const char *name, void *buffer, size_t size) |
| + const char *name, void *buffer, size_t size, |
| + int flags) |
| { |
| struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
| |
| diff --git a/fs/orangefs/xattr.c b/fs/orangefs/xattr.c |
| index 9a5b757fbd2f..2cc3bc61235b 100644 |
| --- a/fs/orangefs/xattr.c |
| +++ b/fs/orangefs/xattr.c |
| @@ -542,7 +542,8 @@ static int orangefs_xattr_get_default(const struct xattr_handler *handler, |
| struct inode *inode, |
| const char *name, |
| void *buffer, |
| - size_t size) |
| + size_t size, |
| + int flags) |
| { |
| return orangefs_inode_getxattr(inode, name, buffer, size); |
| |
| diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c |
| index fdd72f1a9c5e..7f0323ce2cc6 100644 |
| --- a/fs/overlayfs/super.c |
| +++ b/fs/overlayfs/super.c |
| @@ -988,7 +988,7 @@ static unsigned int ovl_split_lowerdirs(char *str) |
| 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) |
| + const char *name, void *buffer, size_t size, int flags) |
| { |
| return ovl_xattr_get(dentry, inode, handler->name, buffer, size); |
| } |
| @@ -1054,7 +1054,8 @@ ovl_posix_acl_xattr_set(const struct xattr_handler *handler, |
| |
| static int ovl_own_xattr_get(const struct xattr_handler *handler, |
| struct dentry *dentry, struct inode *inode, |
| - const char *name, void *buffer, size_t size) |
| + const char *name, void *buffer, size_t size, |
| + int flags) |
| { |
| return -EOPNOTSUPP; |
| } |
| @@ -1070,7 +1071,8 @@ static int ovl_own_xattr_set(const struct xattr_handler *handler, |
| |
| 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) |
| + const char *name, void *buffer, size_t size, |
| + int flags) |
| { |
| return ovl_xattr_get(dentry, inode, name, buffer, size); |
| } |
| diff --git a/fs/posix_acl.c b/fs/posix_acl.c |
| index f3309a7edb49..9ddc1bf0dc5e 100644 |
| --- a/fs/posix_acl.c |
| +++ b/fs/posix_acl.c |
| @@ -877,7 +877,7 @@ EXPORT_SYMBOL (posix_acl_to_xattr); |
| static int |
| posix_acl_xattr_get(const struct xattr_handler *handler, |
| struct dentry *unused, struct inode *inode, |
| - const char *name, void *value, size_t size) |
| + const char *name, void *value, size_t size, int flags) |
| { |
| struct posix_acl *acl; |
| int error; |
| diff --git a/fs/reiserfs/xattr_security.c b/fs/reiserfs/xattr_security.c |
| index 8965c8e5e172..1fd1359a98ba 100644 |
| --- a/fs/reiserfs/xattr_security.c |
| +++ b/fs/reiserfs/xattr_security.c |
| @@ -11,7 +11,8 @@ |
| |
| static int |
| security_get(const struct xattr_handler *handler, struct dentry *unused, |
| - struct inode *inode, const char *name, void *buffer, size_t size) |
| + struct inode *inode, const char *name, void *buffer, size_t size, |
| + int flags) |
| { |
| if (IS_PRIVATE(inode)) |
| return -EPERM; |
| diff --git a/fs/reiserfs/xattr_trusted.c b/fs/reiserfs/xattr_trusted.c |
| index d853cea2afcd..f54b848e9504 100644 |
| --- a/fs/reiserfs/xattr_trusted.c |
| +++ b/fs/reiserfs/xattr_trusted.c |
| @@ -10,7 +10,8 @@ |
| |
| static int |
| trusted_get(const struct xattr_handler *handler, struct dentry *unused, |
| - struct inode *inode, const char *name, void *buffer, size_t size) |
| + struct inode *inode, const char *name, void *buffer, size_t size, |
| + int flags) |
| { |
| if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode)) |
| return -EPERM; |
| diff --git a/fs/reiserfs/xattr_user.c b/fs/reiserfs/xattr_user.c |
| index 65d9cd10a5ea..ddd98cdab24d 100644 |
| --- a/fs/reiserfs/xattr_user.c |
| +++ b/fs/reiserfs/xattr_user.c |
| @@ -9,7 +9,8 @@ |
| |
| static int |
| user_get(const struct xattr_handler *handler, struct dentry *unused, |
| - struct inode *inode, const char *name, void *buffer, size_t size) |
| + struct inode *inode, const char *name, void *buffer, size_t size, |
| + int flags) |
| { |
| if (!reiserfs_xattrs_user(inode->i_sb)) |
| return -EOPNOTSUPP; |
| diff --git a/fs/squashfs/xattr.c b/fs/squashfs/xattr.c |
| index e1e3f3dd5a06..d8d58c990652 100644 |
| --- a/fs/squashfs/xattr.c |
| +++ b/fs/squashfs/xattr.c |
| @@ -204,7 +204,7 @@ static int squashfs_xattr_handler_get(const struct xattr_handler *handler, |
| struct dentry *unused, |
| struct inode *inode, |
| const char *name, |
| - void *buffer, size_t size) |
| + void *buffer, size_t size, int flags) |
| { |
| return squashfs_xattr_get(inode, handler->flags, name, |
| buffer, size); |
| diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c |
| index 6b1e9830b274..cd38f19e410e 100644 |
| --- a/fs/ubifs/xattr.c |
| +++ b/fs/ubifs/xattr.c |
| @@ -671,7 +671,8 @@ int ubifs_init_security(struct inode *dentry, struct inode *inode, |
| |
| static int xattr_get(const struct xattr_handler *handler, |
| struct dentry *dentry, struct inode *inode, |
| - const char *name, void *buffer, size_t size) |
| + const char *name, void *buffer, size_t size, |
| + int flags) |
| { |
| dbg_gen("xattr '%s', ino %lu ('%pd'), buf size %zd", name, |
| inode->i_ino, dentry, size); |
| diff --git a/fs/xattr.c b/fs/xattr.c |
| index b3444e06cded..50b1fb199c62 100644 |
| --- a/fs/xattr.c |
| +++ b/fs/xattr.c |
| @@ -368,7 +368,7 @@ vfs_getxattr_alloc(struct user_namespace *mnt_userns, struct dentry *dentry, |
| return PTR_ERR(handler); |
| if (!handler->get) |
| return -EOPNOTSUPP; |
| - error = handler->get(handler, dentry, inode, name, NULL, 0); |
| + error = handler->get(handler, dentry, inode, name, NULL, 0, 0); |
| if (error < 0) |
| return error; |
| |
| @@ -379,33 +379,21 @@ vfs_getxattr_alloc(struct user_namespace *mnt_userns, struct dentry *dentry, |
| memset(value, 0, error + 1); |
| } |
| |
| - error = handler->get(handler, dentry, inode, name, value, error); |
| + error = handler->get(handler, dentry, inode, name, value, error, 0); |
| *xattr_value = value; |
| return error; |
| } |
| |
| ssize_t |
| -__vfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name, |
| - void *value, size_t size) |
| +__vfs_getxattr(struct user_namespace *mnt_userns, struct dentry *dentry, |
| + struct inode *inode, const char *name, void *value, size_t size, |
| + int flags) |
| { |
| const struct xattr_handler *handler; |
| - |
| - handler = xattr_resolve_name(inode, &name); |
| - if (IS_ERR(handler)) |
| - return PTR_ERR(handler); |
| - if (!handler->get) |
| - return -EOPNOTSUPP; |
| - return handler->get(handler, dentry, inode, name, value, size); |
| -} |
| -EXPORT_SYMBOL(__vfs_getxattr); |
| - |
| -ssize_t |
| -vfs_getxattr(struct user_namespace *mnt_userns, struct dentry *dentry, |
| - const char *name, void *value, size_t size) |
| -{ |
| - struct inode *inode = dentry->d_inode; |
| int error; |
| |
| + if (flags & XATTR_NOSECURITY) |
| + goto nolsm; |
| error = xattr_permission(mnt_userns, inode, name, MAY_READ); |
| if (error) |
| return error; |
| @@ -428,7 +416,20 @@ vfs_getxattr(struct user_namespace *mnt_userns, struct dentry *dentry, |
| return ret; |
| } |
| nolsm: |
| - return __vfs_getxattr(dentry, inode, name, value, size); |
| + handler = xattr_resolve_name(inode, &name); |
| + if (IS_ERR(handler)) |
| + return PTR_ERR(handler); |
| + if (!handler->get) |
| + return -EOPNOTSUPP; |
| + return handler->get(handler, dentry, inode, name, value, size, flags); |
| +} |
| +EXPORT_SYMBOL(__vfs_getxattr); |
| + |
| +ssize_t |
| +vfs_getxattr(struct user_namespace *mnt_userns, struct dentry *dentry, |
| + const char *name, void *value, size_t size) |
| +{ |
| + return __vfs_getxattr(mnt_userns, dentry, dentry->d_inode, name, value, size, 0); |
| } |
| EXPORT_SYMBOL_GPL(vfs_getxattr); |
| |
| diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c |
| index 12be32f66dc1..585f1f7c69b2 100644 |
| --- a/fs/xfs/xfs_xattr.c |
| +++ b/fs/xfs/xfs_xattr.c |
| @@ -19,7 +19,8 @@ |
| |
| static int |
| xfs_xattr_get(const struct xattr_handler *handler, struct dentry *unused, |
| - struct inode *inode, const char *name, void *value, size_t size) |
| + struct inode *inode, const char *name, void *value, size_t size, |
| + int flags) |
| { |
| struct xfs_da_args args = { |
| .dp = XFS_I(inode), |
| diff --git a/include/linux/xattr.h b/include/linux/xattr.h |
| index 4c379d23ec6e..d04b68e1b0da 100644 |
| --- a/include/linux/xattr.h |
| +++ b/include/linux/xattr.h |
| @@ -32,10 +32,10 @@ struct xattr_handler { |
| const char *prefix; |
| int flags; /* fs private flags */ |
| bool (*list)(struct dentry *dentry); |
| - int (*get)(const struct xattr_handler *, struct dentry *dentry, |
| + int (*get)(const struct xattr_handler *handler, struct dentry *dentry, |
| struct inode *inode, const char *name, void *buffer, |
| - size_t size); |
| - int (*set)(const struct xattr_handler *, |
| + size_t size, int flags); |
| + int (*set)(const struct xattr_handler *handler, |
| struct user_namespace *mnt_userns, struct dentry *dentry, |
| struct inode *inode, const char *name, const void *buffer, |
| size_t size, int flags); |
| @@ -49,7 +49,8 @@ struct xattr { |
| size_t value_len; |
| }; |
| |
| -ssize_t __vfs_getxattr(struct dentry *, struct inode *, const char *, void *, size_t); |
| +ssize_t __vfs_getxattr(struct user_namespace *, struct dentry *, struct inode *, |
| + const char *, void *, size_t); |
| ssize_t vfs_getxattr(struct user_namespace *, struct dentry *, const char *, |
| void *, size_t); |
| ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size); |
| diff --git a/include/uapi/linux/xattr.h b/include/uapi/linux/xattr.h |
| index 9463db2dfa9d..d22191a3cf09 100644 |
| --- a/include/uapi/linux/xattr.h |
| +++ b/include/uapi/linux/xattr.h |
| @@ -18,8 +18,11 @@ |
| #if __UAPI_DEF_XATTR |
| #define __USE_KERNEL_XATTR_DEFS |
| |
| -#define XATTR_CREATE 0x1 /* set value, fail if attr already exists */ |
| -#define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */ |
| +#define XATTR_CREATE 0x1 /* set value, fail if attr already exists */ |
| +#define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */ |
| +#ifdef __KERNEL__ /* following is kernel internal, colocated for maintenance */ |
| +#define XATTR_NOSECURITY 0x4 /* get value, do not involve security check */ |
| +#endif |
| #endif |
| |
| /* Namespaces */ |
| diff --git a/mm/shmem.c b/mm/shmem.c |
| index b2db4ed0fbc7..5907c3a67574 100644 |
| --- a/mm/shmem.c |
| +++ b/mm/shmem.c |
| @@ -3209,7 +3209,8 @@ static int shmem_initxattrs(struct inode *inode, |
| |
| static int shmem_xattr_handler_get(const struct xattr_handler *handler, |
| struct dentry *unused, struct inode *inode, |
| - const char *name, void *buffer, size_t size) |
| + const char *name, void *buffer, size_t size, |
| + int flags) |
| { |
| struct shmem_inode_info *info = SHMEM_I(inode); |
| |
| diff --git a/net/socket.c b/net/socket.c |
| index 84a8049c2b09..29fd3b2a1fae 100644 |
| --- a/net/socket.c |
| +++ b/net/socket.c |
| @@ -314,7 +314,8 @@ static const struct dentry_operations sockfs_dentry_operations = { |
| |
| static int sockfs_xattr_get(const struct xattr_handler *handler, |
| struct dentry *dentry, struct inode *inode, |
| - const char *suffix, void *value, size_t size) |
| + const char *suffix, void *value, size_t size, |
| + int flags) |
| { |
| if (value) { |
| if (dentry->d_name.len + 1 > size) |
| diff --git a/security/commoncap.c b/security/commoncap.c |
| index 1c519c875217..660d3d41aed8 100644 |
| --- a/security/commoncap.c |
| +++ b/security/commoncap.c |
| @@ -297,7 +297,8 @@ int cap_inode_need_killpriv(struct dentry *dentry) |
| struct inode *inode = d_backing_inode(dentry); |
| int error; |
| |
| - error = __vfs_getxattr(dentry, inode, XATTR_NAME_CAPS, NULL, 0); |
| + error = __vfs_getxattr(&init_user_ns, dentry, inode, XATTR_NAME_CAPS, |
| + NULL, 0, XATTR_NOSECURITY); |
| return error > 0; |
| } |
| |
| @@ -660,8 +661,9 @@ int get_vfs_caps_from_disk(struct user_namespace *mnt_userns, |
| return -ENODATA; |
| |
| fs_ns = inode->i_sb->s_user_ns; |
| - size = __vfs_getxattr((struct dentry *)dentry, inode, |
| - XATTR_NAME_CAPS, &data, XATTR_CAPS_SZ); |
| + size = __vfs_getxattr(&init_user_ns, (struct dentry *)dentry, inode, |
| + XATTR_NAME_CAPS, &data, XATTR_CAPS_SZ, |
| + XATTR_NOSECURITY); |
| if (size == -ENODATA || size == -EOPNOTSUPP) |
| /* no data, that's ok */ |
| return -ENODATA; |
| diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c |
| index 0de367aaa2d3..59e88fb378c6 100644 |
| --- a/security/integrity/evm/evm_main.c |
| +++ b/security/integrity/evm/evm_main.c |
| @@ -101,7 +101,9 @@ static int evm_find_protected_xattrs(struct dentry *dentry) |
| return -EOPNOTSUPP; |
| |
| list_for_each_entry_lockless(xattr, &evm_config_xattrnames, list) { |
| - error = __vfs_getxattr(dentry, inode, xattr->name, NULL, 0); |
| + error = __vfs_getxattr(&init_user_ns, dentry, inode, |
| + xattr->name, NULL, 0, |
| + XATTR_NOSECURITY); |
| if (error < 0) { |
| if (error == -ENODATA) |
| continue; |
| diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c |
| index ddd097790d47..1f29b4d43914 100644 |
| --- a/security/selinux/hooks.c |
| +++ b/security/selinux/hooks.c |
| @@ -505,7 +505,8 @@ static int sb_check_xattr_support(struct super_block *sb) |
| goto fallback; |
| } |
| |
| - rc = __vfs_getxattr(root, root_inode, XATTR_NAME_SELINUX, NULL, 0); |
| + rc = __vfs_getxattr(&init_user_ns, root, root_inode, |
| + XATTR_NAME_SELINUX, NULL, 0, XATTR_NOSECURITY); |
| if (rc < 0 && rc != -ENODATA) { |
| if (rc == -EOPNOTSUPP) { |
| pr_warn("SELinux: (dev %s, type %s) has no security xattr handler\n", |
| @@ -1360,12 +1361,16 @@ static int inode_doinit_use_xattr(struct inode *inode, struct dentry *dentry, |
| return -ENOMEM; |
| |
| context[len] = '\0'; |
| - rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, context, len); |
| + rc = __vfs_getxattr(&init_user_ns, dentry, inode, |
| + XATTR_NAME_SELINUX, context, len, |
| + XATTR_NOSECURITY); |
| if (rc == -ERANGE) { |
| kfree(context); |
| |
| /* Need a larger buffer. Query for the right size. */ |
| - rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, NULL, 0); |
| + rc = __vfs_getxattr(&init_user_ns, dentry, inode, |
| + XATTR_NAME_SELINUX, NULL, 0, |
| + XATTR_NOSECURITY); |
| if (rc < 0) |
| return rc; |
| |
| @@ -1375,8 +1380,9 @@ static int inode_doinit_use_xattr(struct inode *inode, struct dentry *dentry, |
| return -ENOMEM; |
| |
| context[len] = '\0'; |
| - rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, |
| - context, len); |
| + rc = __vfs_getxattr(&init_user_ns, dentry, inode, |
| + XATTR_NAME_SELINUX, context, len, |
| + XATTR_NOSECURITY); |
| } |
| if (rc < 0) { |
| kfree(context); |
| diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c |
| index 12a45e61c1a5..ed0693643166 100644 |
| --- a/security/smack/smack_lsm.c |
| +++ b/security/smack/smack_lsm.c |
| @@ -289,7 +289,8 @@ static struct smack_known *smk_fetch(const char *name, struct inode *ip, |
| if (buffer == NULL) |
| return ERR_PTR(-ENOMEM); |
| |
| - rc = __vfs_getxattr(dp, ip, name, buffer, SMK_LONGLABEL); |
| + rc = __vfs_getxattr(&init_user_ns, dp, ip, name, buffer, SMK_LONGLABEL, |
| + XATTR_NOSECURITY); |
| if (rc < 0) |
| skp = ERR_PTR(rc); |
| else if (rc == 0) |
| @@ -3432,9 +3433,9 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) |
| TRANS_TRUE, TRANS_TRUE_SIZE, |
| 0); |
| } else { |
| - rc = __vfs_getxattr(dp, inode, |
| + rc = __vfs_getxattr(&init_user_ns, dp, inode, |
| XATTR_NAME_SMACKTRANSMUTE, trattr, |
| - TRANS_TRUE_SIZE); |
| + TRANS_TRUE_SIZE, XATTR_NOSECURITY); |
| if (rc >= 0 && strncmp(trattr, TRANS_TRUE, |
| TRANS_TRUE_SIZE) != 0) |
| rc = -EINVAL; |
| -- |
| 2.17.1 |
| |