[PATCH] !!!! HERE BE DRAGONS - UNTESTED !!!!

From: Christian Brauner
Date: Thu Dec 09 2021 - 14:07:02 EST


---
security/integrity/ima/ima_fs.c | 43 +++++++++++++++++++++++++++++----
1 file changed, 38 insertions(+), 5 deletions(-)

diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index 583462b29cb5..d5b302b925b8 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -317,10 +317,14 @@ static ssize_t ima_read_policy(char *path)
static ssize_t ima_write_policy(struct file *file, const char __user *buf,
size_t datalen, loff_t *ppos)
{
- struct ima_namespace *ns = get_current_ns();
+ struct ima_namespace *ns;
+ struct user_namespace *user_ns;
char *data;
ssize_t result;

+ user_ns = ima_filp_private(filp);
+ ns = user_ns->ima_ns
+
if (datalen >= PAGE_SIZE)
datalen = PAGE_SIZE - 1;

@@ -373,26 +377,51 @@ static const struct seq_operations ima_policy_seqops = {
};
#endif

+static struct user_namespace *ima_filp_private(struct file *filp)
+{
+ if (!(filp->f_flags & O_WRONLY)) {
+#ifdef CONFIG_IMA_READ_POLICY
+ struct seq_file *seq;
+
+ seq = filp->private_data;
+ return seq->private;
+#endif
+ }
+ return filp->private_data;
+}
+
/*
* ima_open_policy: sequentialize access to the policy file
*/
static int ima_open_policy(struct inode *inode, struct file *filp)
{
- struct ima_namespace *ns = get_current_ns();
+ struct user_namespace *user_ns = current_user_ns();
+ struct ima_namespace *ns = user_ns->ima_ns;

if (!(filp->f_flags & O_WRONLY)) {
#ifndef CONFIG_IMA_READ_POLICY
return -EACCES;
#else
+ int err;
+ struct seq_file *seq;
+
if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
return -EACCES;
- if (!mac_admin_ns_capable(ima_user_ns(ns)))
+ if (!mac_admin_ns_capable(user_ns))
return -EPERM;
- return seq_open(filp, &ima_policy_seqops);
+ err = seq_open(filp, &ima_policy_seqops);
+ if (err)
+ return err;
+
+ seq = filp->private_data;
+ seq->private = user_ns;
+ return 0;
#endif
}
if (test_and_set_bit(IMA_FS_BUSY, &ns->ima_fs_flags))
return -EBUSY;
+
+ filp->private_data = user_ns;
return 0;
}

@@ -405,9 +434,13 @@ static int ima_open_policy(struct inode *inode, struct file *filp)
*/
static int ima_release_policy(struct inode *inode, struct file *file)
{
- struct ima_namespace *ns = get_current_ns();
+ struct ima_namespace *ns;
+ struct user_namespace *user_ns;
const char *cause = ns->valid_policy ? "completed" : "failed";

+ user_ns = ima_filp_private(filp);
+ ns = user_ns->ima_ns
+
if ((file->f_flags & O_ACCMODE) == O_RDONLY)
return seq_release(inode, file);

--
2.30.2