summaryrefslogtreecommitdiff
path: root/security
diff options
context:
space:
mode:
authorChristian Brauner <brauner@kernel.org>2023-01-13 12:49:22 +0100
committerChristian Brauner (Microsoft) <brauner@kernel.org>2023-01-19 09:24:28 +0100
commit4609e1f18e19c3b302e1eb4858334bca1532f780 (patch)
tree1e050d9bce359b0d808dc9ee9273ef2d6d2eaebc /security
parent8782a9aea3ab4d697ad67d1f8ebca38a4e1c24ab (diff)
fs: port ->permission() to pass mnt_idmap
Convert to struct mnt_idmap. Last cycle we merged the necessary infrastructure in 256c8aed2b42 ("fs: introduce dedicated idmap type for mounts"). This is just the conversion to struct mnt_idmap. Currently we still pass around the plain namespace that was attached to a mount. This is in general pretty convenient but it makes it easy to conflate namespaces that are relevant on the filesystem with namespaces that are relevent on the mount level. Especially for non-vfs developers without detailed knowledge in this area this can be a potential source for bugs. Once the conversion to struct mnt_idmap is done all helpers down to the really low-level helpers will take a struct mnt_idmap argument instead of two namespace arguments. This way it becomes impossible to conflate the two eliminating the possibility of any bugs. All of the vfs and all filesystems only operate on struct mnt_idmap. Acked-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org>
Diffstat (limited to 'security')
-rw-r--r--security/apparmor/domain.c2
-rw-r--r--security/commoncap.c5
-rw-r--r--security/integrity/evm/evm_crypto.c6
-rw-r--r--security/integrity/evm/evm_main.c4
-rw-r--r--security/integrity/ima/ima_appraise.c2
-rw-r--r--security/integrity/ima/ima_template_lib.c2
-rw-r--r--security/security.c4
-rw-r--r--security/selinux/hooks.c4
-rw-r--r--security/smack/smack_lsm.c4
9 files changed, 17 insertions, 16 deletions
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index 6dd3cc5309bf..a8da32fecbe7 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -313,7 +313,7 @@ static int aa_xattrs_match(const struct linux_binprm *bprm,
d = bprm->file->f_path.dentry;
for (i = 0; i < attach->xattr_count; i++) {
- size = vfs_getxattr_alloc(&init_user_ns, d, attach->xattrs[i],
+ size = vfs_getxattr_alloc(&nop_mnt_idmap, d, attach->xattrs[i],
&value, value_size, GFP_KERNEL);
if (size >= 0) {
u32 index, perm;
diff --git a/security/commoncap.c b/security/commoncap.c
index 1164278b97fd..01b68f9311ca 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -377,7 +377,7 @@ static bool is_v3header(int size, const struct vfs_cap_data *cap)
* by the integrity subsystem, which really wants the unconverted values -
* so that's good.
*/
-int cap_inode_getsecurity(struct user_namespace *mnt_userns,
+int cap_inode_getsecurity(struct mnt_idmap *idmap,
struct inode *inode, const char *name, void **buffer,
bool alloc)
{
@@ -391,6 +391,7 @@ int cap_inode_getsecurity(struct user_namespace *mnt_userns,
struct vfs_ns_cap_data *nscap = NULL;
struct dentry *dentry;
struct user_namespace *fs_ns;
+ struct user_namespace *mnt_userns = mnt_idmap_owner(idmap);
if (strcmp(name, "capability") != 0)
return -EOPNOTSUPP;
@@ -398,7 +399,7 @@ int cap_inode_getsecurity(struct user_namespace *mnt_userns,
dentry = d_find_any_alias(inode);
if (!dentry)
return -EINVAL;
- size = vfs_getxattr_alloc(mnt_userns, dentry, XATTR_NAME_CAPS, &tmpbuf,
+ size = vfs_getxattr_alloc(idmap, dentry, XATTR_NAME_CAPS, &tmpbuf,
sizeof(struct vfs_ns_cap_data), GFP_NOFS);
dput(dentry);
/* gcc11 complains if we don't check for !tmpbuf */
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
index fa5ff13fa8c9..b202edc2ff65 100644
--- a/security/integrity/evm/evm_crypto.c
+++ b/security/integrity/evm/evm_crypto.c
@@ -265,7 +265,7 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry,
req_xattr_value_len);
continue;
}
- size = vfs_getxattr_alloc(&init_user_ns, dentry, xattr->name,
+ size = vfs_getxattr_alloc(&nop_mnt_idmap, dentry, xattr->name,
&xattr_value, xattr_size, GFP_NOFS);
if (size == -ENOMEM) {
error = -ENOMEM;
@@ -274,7 +274,7 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry,
if (size < 0)
continue;
- user_space_size = vfs_getxattr(&init_user_ns, dentry,
+ 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",
@@ -331,7 +331,7 @@ static int evm_is_immutable(struct dentry *dentry, struct inode *inode)
return 1;
/* Do this the hard way */
- rc = vfs_getxattr_alloc(&init_user_ns, dentry, XATTR_NAME_EVM,
+ rc = vfs_getxattr_alloc(&nop_mnt_idmap, dentry, XATTR_NAME_EVM,
(char **)&xattr_data, 0, GFP_NOFS);
if (rc <= 0) {
if (rc == -ENODATA)
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index e5a6a3bb1209..45bcd08a9224 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -184,7 +184,7 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
/* if status is not PASS, try to check again - against -ENOMEM */
/* first need to know the sig type */
- rc = vfs_getxattr_alloc(&init_user_ns, dentry, XATTR_NAME_EVM,
+ rc = vfs_getxattr_alloc(&nop_mnt_idmap, dentry, XATTR_NAME_EVM,
(char **)&xattr_data, 0, GFP_NOFS);
if (rc <= 0) {
evm_status = INTEGRITY_FAIL;
@@ -453,7 +453,7 @@ static int evm_xattr_change(struct user_namespace *mnt_userns,
char *xattr_data = NULL;
int rc = 0;
- rc = vfs_getxattr_alloc(&init_user_ns, dentry, xattr_name, &xattr_data,
+ rc = vfs_getxattr_alloc(&nop_mnt_idmap, dentry, xattr_name, &xattr_data,
0, GFP_NOFS);
if (rc < 0) {
rc = 1;
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index ee6f7e237f2e..734a6818a545 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -225,7 +225,7 @@ int ima_read_xattr(struct dentry *dentry,
{
int ret;
- ret = vfs_getxattr_alloc(&init_user_ns, dentry, XATTR_NAME_IMA,
+ ret = vfs_getxattr_alloc(&nop_mnt_idmap, dentry, XATTR_NAME_IMA,
(char **)xattr_value, xattr_len, GFP_NOFS);
if (ret == -EOPNOTSUPP)
ret = 0;
diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c
index 4564faae7d67..6cd0add524cd 100644
--- a/security/integrity/ima/ima_template_lib.c
+++ b/security/integrity/ima/ima_template_lib.c
@@ -598,7 +598,7 @@ int ima_eventevmsig_init(struct ima_event_data *event_data,
if (!event_data->file)
return 0;
- rc = vfs_getxattr_alloc(&init_user_ns, file_dentry(event_data->file),
+ rc = vfs_getxattr_alloc(&nop_mnt_idmap, file_dentry(event_data->file),
XATTR_NAME_EVM, (char **)&xattr_data, 0,
GFP_NOFS);
if (rc <= 0 || xattr_data->type != EVM_XATTR_PORTABLE_DIGSIG) {
diff --git a/security/security.c b/security/security.c
index fceab8e0ff87..df7182fb1291 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1498,7 +1498,7 @@ int security_inode_killpriv(struct user_namespace *mnt_userns,
return call_int_hook(inode_killpriv, 0, mnt_userns, dentry);
}
-int security_inode_getsecurity(struct user_namespace *mnt_userns,
+int security_inode_getsecurity(struct mnt_idmap *idmap,
struct inode *inode, const char *name,
void **buffer, bool alloc)
{
@@ -1511,7 +1511,7 @@ int security_inode_getsecurity(struct user_namespace *mnt_userns,
* Only one module will provide an attribute with a given name.
*/
hlist_for_each_entry(hp, &security_hook_heads.inode_getsecurity, list) {
- rc = hp->hook.inode_getsecurity(mnt_userns, inode, name, buffer, alloc);
+ rc = hp->hook.inode_getsecurity(idmap, inode, name, buffer, alloc);
if (rc != LSM_RET_DEFAULT(inode_getsecurity))
return rc;
}
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 3c5be76a9199..a32a814a694d 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3383,7 +3383,7 @@ static int selinux_path_notify(const struct path *path, u64 mask,
*
* Permission check is handled by selinux_inode_getxattr hook.
*/
-static int selinux_inode_getsecurity(struct user_namespace *mnt_userns,
+static int selinux_inode_getsecurity(struct mnt_idmap *idmap,
struct inode *inode, const char *name,
void **buffer, bool alloc)
{
@@ -6595,7 +6595,7 @@ static int selinux_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
static int selinux_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
{
int len = 0;
- len = selinux_inode_getsecurity(&init_user_ns, inode,
+ len = selinux_inode_getsecurity(&nop_mnt_idmap, inode,
XATTR_SELINUX_SUFFIX, ctx, true);
if (len < 0)
return len;
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 9a82a15685d1..15983032220a 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -1462,7 +1462,7 @@ static int smack_inode_remove_acl(struct user_namespace *mnt_userns,
/**
* smack_inode_getsecurity - get smack xattrs
- * @mnt_userns: active user namespace
+ * @idmap: idmap of the mount
* @inode: the object
* @name: attribute name
* @buffer: where to put the result
@@ -1470,7 +1470,7 @@ static int smack_inode_remove_acl(struct user_namespace *mnt_userns,
*
* Returns the size of the attribute or an error code
*/
-static int smack_inode_getsecurity(struct user_namespace *mnt_userns,
+static int smack_inode_getsecurity(struct mnt_idmap *idmap,
struct inode *inode, const char *name,
void **buffer, bool alloc)
{