blob: 069b3daad4292a42ee9e3ed170745b4a4da9aecb [file] [log] [blame]
From f0ab9bac26c34a547e5aff7bbf825cbbc77cb0f8 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>
[rebase515(groeck):
Squashed:
FROMLIST: Add flags option to get xattr method paired to __vfs_getxattr
FIXUP: FROMLIST: Add flags option to get xattr method paired to __vfs_getxattr
FIXUP: ima: Define new template fields xattrnames, xattrlengths and xattrvalues
]
Signed-off-by: Guenter Roeck <groeck@google.com>
[rebase61(tzungbi):
Squashed:
FIXUP: NFSv4.1: Enable access to the NFSv4.1 'dacl' and 'sacl' attributes
]
Signed-off-by: Tzung-Bi Shih <tzungbi@chromium.org>
---
Documentation/filesystems/locking.rst | 2 +-
fs/9p/xattr.c | 3 +-
fs/afs/xattr.c | 10 +++----
fs/btrfs/xattr.c | 3 +-
fs/ceph/xattr.c | 3 +-
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_hurd.c | 3 +-
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 | 2 +-
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 | 15 ++++++----
fs/ntfs3/xattr.c | 2 +-
fs/ocfs2/xattr.c | 9 ++++--
fs/orangefs/xattr.c | 3 +-
fs/reiserfs/xattr_security.c | 3 +-
fs/reiserfs/xattr_trusted.c | 3 +-
fs/reiserfs/xattr_user.c | 3 +-
fs/smb/client/xattr.c | 2 +-
fs/squashfs/xattr.c | 2 +-
fs/ubifs/xattr.c | 3 +-
fs/xattr.c | 43 ++++++++++++++-------------
fs/xfs/xfs_xattr.c | 3 +-
include/linux/xattr.h | 5 ++--
include/uapi/linux/xattr.h | 7 +++--
mm/shmem.c | 3 +-
net/socket.c | 3 +-
security/commoncap.c | 8 +++--
security/integrity/evm/evm_main.c | 13 ++++----
security/selinux/hooks.c | 16 ++++++----
security/smack/smack_lsm.c | 7 +++--
48 files changed, 147 insertions(+), 96 deletions(-)
diff --git a/Documentation/filesystems/locking.rst b/Documentation/filesystems/locking.rst
index 7be2900806c85330b9589f32e4a887b0b6857fde..b99fd5c2bab06999a9593b9075e9a5ad25c5c281 100644
--- a/Documentation/filesystems/locking.rst
+++ b/Documentation/filesystems/locking.rst
@@ -135,7 +135,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 mnt_idmap *idmap,
struct dentry *dentry, struct inode *inode, const char *name,
diff --git a/fs/9p/xattr.c b/fs/9p/xattr.c
index e00cf8109b3f31cb77ffb900b56ca67df480a791..a44d4038784fbec5083410b509b1d19923f79250 100644
--- a/fs/9p/xattr.c
+++ b/fs/9p/xattr.c
@@ -144,7 +144,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 9048d8ccc715f5efe001ad99ceca5a4fdb32cee6..048e9478eb92e9c54ea44ffe8cab607f655fdafe 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 96828a13dd43d9ae0beb1562072c93657763c6d4..b08e3f4cb53d992769fd11b0b8ed1e0f93547506 100644
--- a/fs/btrfs/xattr.c
+++ b/fs/btrfs/xattr.c
@@ -363,7 +363,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 0deae4a0f5f169b4738019487ca4a25624d3f014..c4bf9e3c07526f33277f5af931011eb330e1267e 100644
--- a/fs/ceph/xattr.c
+++ b/fs/ceph/xattr.c
@@ -1310,7 +1310,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/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index 992d9c7e64ae66f2cb094d949653e693a325c4b6..2cfa32738037c6f55d3cdcddb12a4b36d7b6409d 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -1053,7 +1053,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;
@@ -1185,7 +1186,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 e2483acc436663bb269b01db815cabfc38a35060..ee4a06fac17df33d239927ba4bbcf7486b209866 100644
--- a/fs/ecryptfs/mmap.c
+++ b/fs/ecryptfs/mmap.c
@@ -422,8 +422,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 09d341675e890e6bc9a975cc0024bf5429b78ca6..464941caacfa6a12bdab5b2f7c3568be6ee8acf9 100644
--- a/fs/erofs/xattr.c
+++ b/fs/erofs/xattr.c
@@ -137,7 +137,8 @@ static bool erofs_xattr_trusted_list(struct dentry *dentry)
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)
{
if (handler->flags == EROFS_XATTR_INDEX_USER &&
!test_opt(&EROFS_I_SB(inode)->opt, XATTR_USER))
diff --git a/fs/ext2/xattr_security.c b/fs/ext2/xattr_security.c
index db47b8ab153e7d3bf6e90cd29c2e775d9910d261..9b01627af5abaa14c6fb6581b91679e67597ff11 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 995f931228ce8b2c38c75e80e7da51f8007cac74..3b2fd0e0cef2c31bc7bc0d2f93c42cfd2bf10456 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 dd15072310818b678959c974df5a6a504ea43af3..d581979fd45da7bb66ad726cd703bf643fd0dbf7 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_hurd.c b/fs/ext4/xattr_hurd.c
index 8a5842e4cd95c6a06f346f7c74767199be3316b3..7966bb36aae3abf899772acbb2dc8d9ad0f22dbc 100644
--- a/fs/ext4/xattr_hurd.c
+++ b/fs/ext4/xattr_hurd.c
@@ -21,7 +21,8 @@ ext4_xattr_hurd_list(struct dentry *dentry)
static int
ext4_xattr_hurd_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 776cf11d24ca10e016184304a15979d2c2898b94..b145a899d4b2a704fda57296f0915e4990a2ea76 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 9811eb0ab276232cf2ec249f333184fb773c23f1..825075b029fe477356c0533a726734c290905a20 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 4b70bf4e76263383c437994b37f49bd48766ce9d..d12c3898b2818b1ea01c7bd77ba189f50f340494 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 a657284faee30ad381c85f8f032f71709cdb1265..8b896d73aeaf5956a0140ca65eee4fabb3db96f7 100644
--- a/fs/f2fs/xattr.c
+++ b/fs/f2fs/xattr.c
@@ -45,7 +45,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);
@@ -101,7 +101,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 49c01559580f4eb7427ac372f122497af308dcdd..d654de6dbefe726e1dd11da4a5832624fafff782 100644
--- a/fs/fuse/xattr.c
+++ b/fs/fuse/xattr.c
@@ -180,7 +180,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;
diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c
index 4fea70c0fe3d17f1059e216888ecd470452cac68..348ee299e902ff6f06bb152035179d84108cf912 100644
--- a/fs/gfs2/xattr.c
+++ b/fs/gfs2/xattr.c
@@ -602,7 +602,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 6341bb248247751776a1876630fbb2db15959a0c..428ce5be8ba92bdecb8360af6d3f6081490a4356 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 58021e73c00bf7816d7b02f4a598bde2c7b0e723..12ac339aba46d59e28e47c4065bbf6578ec682a0 100644
--- a/fs/hfsplus/xattr.c
+++ b/fs/hfsplus/xattr.c
@@ -838,7 +838,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 90f68ec119cddd86f8b0a7cf4eb9ad3c5188ac58..7c9706f5f481bd3e90cab013efe1b6cf4c993295 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 fdbaebc1c49a01896716c57b5599e9a01acc009a..481f308ddd63c6b4ee8c0aea2e632dfc7ac4de68 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 6464b6c3d58d69182dcbd169f73ff911bf4f07c9..4d1366308d40663265fc5c5d90730e2bc50fef20 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 437f3a2c1b5441759d191fc9002cee82bf1c6287..c8d070e426e02af032dd94a893859fc6a3bc5702 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 b7c5da2d89bdf19259d12895429c3c95791913a3..627970116817cac54aeae2efbaafe299e4c452c8 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 f64edce4927b2ee7885f751754aa542bce878cbc..33ac4b94cfed4481660377aa6581c9dd1b3df07f 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 8577ad494e056bc7c85cec768ed4ca123b07a85e..df4aa6ca2c966833f0e7605001431fada7594b5d 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 922719a343a77a21afc60c92e42d8e689010acb6..41b45929f17fa4ea22b36b66107ecc3d7c3d56aa 100644
--- a/fs/kernfs/inode.c
+++ b/fs/kernfs/inode.c
@@ -320,7 +320,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 794343790ea8bbba5493f0374d5297c45f87dd4f..61f2088f25aa0cbedc181b76acb641c9edf7cf9b 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -7710,7 +7710,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, NFS4ACL_ACL);
}
@@ -7734,7 +7735,8 @@ static int nfs4_xattr_set_nfs4_dacl(const struct xattr_handler *handler,
static int nfs4_xattr_get_nfs4_dacl(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, NFS4ACL_DACL);
}
@@ -7757,7 +7759,8 @@ static int nfs4_xattr_set_nfs4_sacl(const struct xattr_handler *handler,
static int nfs4_xattr_get_nfs4_sacl(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, NFS4ACL_SACL);
}
@@ -7785,7 +7788,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);
@@ -7863,7 +7867,8 @@ static int nfs4_xattr_set_nfs4_user(const struct xattr_handler *handler,
static int nfs4_xattr_get_nfs4_user(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)
{
u32 mask;
ssize_t ret;
diff --git a/fs/ntfs3/xattr.c b/fs/ntfs3/xattr.c
index 29fd391899e59dfde9b29e920f7303862b7167ff..ced43b2485b03aa6c5fc71b853c92993b3ea3e4c 100644
--- a/fs/ntfs3/xattr.c
+++ b/fs/ntfs3/xattr.c
@@ -734,7 +734,7 @@ ssize_t ntfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
static int ntfs_getxattr(const struct xattr_handler *handler, struct dentry *de,
struct inode *inode, const char *name, void *buffer,
- size_t size)
+ size_t size, int flags)
{
int err;
struct ntfs_inode *ni = ntfs_i(inode);
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 6510ad783c912c8408105a8c0a6a0e95ee6bd0b2..8733a5134f3a2ff82b690f1da1b3a1d7e2a7fb9f 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -7236,7 +7236,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);
@@ -7331,7 +7332,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);
@@ -7358,7 +7360,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 68b62689a63e248f73881dffc7861e0ff1bc9335..b5e12244cec34232c45143eca0689784444aedf0 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/reiserfs/xattr_security.c b/fs/reiserfs/xattr_security.c
index 078dd8cc312fc2000dbd30bf2b8091f4e55a3682..de8438cd5f95750ac4778db45d8236b126933950 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 0c0c74d8db0eda0788336ff02f4ceca91183fe22..6556210ff3ca52a80e0e019ddae9db3eac036119 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 88195181e1d7ee963e64fb8072b9a1593ba6bce1..1f24029fcaff606a46709f22556b5e079b09de3c 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/smb/client/xattr.c b/fs/smb/client/xattr.c
index 4ad5531686d81aa4e9395f58ceb04be13520b5a2..11f5de61fd45d1e60968b258125321cae6bc3f32 100644
--- a/fs/smb/client/xattr.c
+++ b/fs/smb/client/xattr.c
@@ -257,7 +257,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/squashfs/xattr.c b/fs/squashfs/xattr.c
index e1e3f3dd5a06b9e06869381edfb9e633222b1286..d8d58c990652aacd44e65338f09347ddaed2c91a 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 406c82eab51386b6bbcb41c75802f9dff30e1b79..354404264324ca24cd7cfcc23bea930727f5b0c5 100644
--- a/fs/ubifs/xattr.c
+++ b/fs/ubifs/xattr.c
@@ -689,7 +689,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 efd4736bc94b09ba4363dd8b691e09deabf4acef..10873ea88b658006f3cd445d9719e6373d155ad1 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -391,7 +391,7 @@ vfs_getxattr_alloc(struct mnt_idmap *idmap, 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;
@@ -402,36 +402,24 @@ vfs_getxattr_alloc(struct mnt_idmap *idmap, 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 mnt_idmap *idmap, struct dentry *dentry,
+ struct inode *inode, const char *name, void *value, size_t size,
+ int flags)
{
const struct xattr_handler *handler;
+ int error;
if (is_posix_acl_xattr(name))
return -EOPNOTSUPP;
- 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 mnt_idmap *idmap, 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(idmap, inode, name, MAY_READ);
if (error)
return error;
@@ -454,7 +442,20 @@ vfs_getxattr(struct mnt_idmap *idmap, 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 mnt_idmap *idmap, struct dentry *dentry,
+ const char *name, void *value, size_t size)
+{
+ return __vfs_getxattr(idmap, 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 43e5c219aaed568ffb5a711b4583b2cdf1723d9c..8f4dfda157194425b6a89e46736c5dec89cf4c33 100644
--- a/fs/xfs/xfs_xattr.c
+++ b/fs/xfs/xfs_xattr.c
@@ -113,7 +113,8 @@ xfs_attr_change(
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 d20051865800800df5d24a0edd7a485b296ba9fa..f314722bc4774e29bf8c10fec2e148da492e3758 100644
--- a/include/linux/xattr.h
+++ b/include/linux/xattr.h
@@ -40,7 +40,7 @@ struct xattr_handler {
bool (*list)(struct dentry *dentry);
int (*get)(const struct xattr_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 *,
struct mnt_idmap *idmap, struct dentry *dentry,
struct inode *inode, const char *name, const void *buffer,
@@ -71,7 +71,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 mnt_idmap *, struct dentry *, struct inode *,
+ const char *, void *, size_t, int flags);
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);
diff --git a/include/uapi/linux/xattr.h b/include/uapi/linux/xattr.h
index 9463db2dfa9d412dbf13051763416b7464876c0f..d22191a3cf09fa69dd071246ee77f29c8aa9b145 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 02e62fccc80d4973b6626988eed07ff2482980d1..8c1f7f05b750df0825a399d47007c20c796ae20a 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -3645,7 +3645,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 c8b08b32f097ec5dfde66b42701be720ab05c826..a721dcf6cd5eb07fa7f30cc475bd357080504334 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -369,7 +369,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 bc05211041979c120831742d25f2e6133435166c..7d85ee9d76d816f33a5c7c5a3ce98506ce0b46c3 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -298,7 +298,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;
}
@@ -651,8 +652,9 @@ int get_vfs_caps_from_disk(struct mnt_idmap *idmap,
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 ff9a939dad8e42d83bff26150fe9b283fdf53494..0d068c0591abcfbe264fed98ce15710284eb0249 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -140,7 +140,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;
@@ -337,8 +339,9 @@ int evm_read_protected_xattrs(struct dentry *dentry, u8 *buffer,
int rc, size, total_size = 0;
list_for_each_entry_lockless(xattr, &evm_config_xattrnames, list) {
- rc = __vfs_getxattr(dentry, d_backing_inode(dentry),
- xattr->name, NULL, 0);
+ rc = __vfs_getxattr(&init_user_ns, dentry,
+ d_backing_inode(dentry),
+ xattr->name, NULL, 0, 0);
if (rc < 0 && rc == -ENODATA)
continue;
else if (rc < 0)
@@ -366,10 +369,10 @@ int evm_read_protected_xattrs(struct dentry *dentry, u8 *buffer,
case 'v':
size = rc;
if (buffer) {
- rc = __vfs_getxattr(dentry,
+ rc = __vfs_getxattr(&init_user_ns, dentry,
d_backing_inode(dentry), xattr->name,
buffer + total_size,
- buffer_size - total_size);
+ buffer_size - total_size, 0);
if (rc < 0)
return rc;
}
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 10350534de6d65b3a4103ae9babe42fac3682261..133ecf55478cbf38408de82972d06ec3a1025863 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -514,7 +514,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",
@@ -1356,12 +1357,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;
@@ -1371,8 +1376,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 65130a791f5730c4f1e1eb6e442d0c31684c66ad..3b371cb0e105f89e13ad3bbe72dbe2c1824b8abf 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -301,7 +301,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)
@@ -3587,9 +3588,9 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
* If there is a transmute attribute on the
* directory mark the inode.
*/
- rc = __vfs_getxattr(dp, inode,
+ rc = __vfs_getxattr(&nop_mnt_idmap, 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.34.1