All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexander Kozhevnikov <alexander.kozhevnikov@huawei.com>
To: <paul@paul-moore.com>
Cc: <alexander.kozhevnikov@huawei.com>, <artem.kuzin@huawei.com>,
	<hw.likun@huawei.com>, <igor.baranov@huawei.com>,
	<jamorris@linux.microsoft.com>,
	<linux-security-module@vger.kernel.org>,
	<selinux@vger.kernel.org>, <stephen.smalley.work@gmail.com>,
	<xiujianfeng@huawei.com>, <yusongping@huawei.com>,
	<anton.sirazetdinov@huawei.com>
Subject: [RFC PATCH 5/7] SELINUXNS: Migrate all open files and all vma to new namespace
Date: Mon, 18 Apr 2022 17:45:50 +0800	[thread overview]
Message-ID: <20220418094552.128898-6-alexander.kozhevnikov@huawei.com> (raw)
In-Reply-To: <20220418094552.128898-1-alexander.kozhevnikov@huawei.com>

From: Igor Baranov <igor.baranov@huawei.com>

When process switched to another namespace and loads a new policy, the
following problem occurs: the current open files in their
file_security_struct contain the sid's relevant to the loaded policy
in the old namespace. Under the new policy, they have completely
random (incorrect) values, and, as a rule, accessing such descriptors
leads to failure. For example, a process gets EACCES when writing to its
own stdout.

Our solution: reinitialize sid's and isid's to actual values in new policy
of all opened files, as well as of files referenced by process's VMA.

Signed-off-by: Alexander Kozhevnikov <alexander.kozhevnikov@huawei.com>
Signed-off-by: Igor Baranov <igor.baranov@huawei.com>
---
 security/selinux/hooks.c     | 94 +++++++++++++++++++++++++++++++++++-
 security/selinux/selinuxfs.c |  2 +-
 2 files changed, 93 insertions(+), 3 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index b618c4e0ef36..74d32b6a4855 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -91,6 +91,7 @@
 #include <uapi/linux/mount.h>
 #include <linux/fsnotify.h>
 #include <linux/fanotify.h>
+#include <linux/sched/mm.h>
 
 #include "avc.h"
 #include "objsec.h"
@@ -4159,8 +4160,7 @@ static int selinux_file_open(struct file *file)
 	 * Task label is already saved in the file security
 	 * struct as its SID.
 	 */
-	//TODO: namespace?
-	fsec->isid = isec->sid;
+	fsec->isid = update_sid(isec);
 	fsec->pseqno = avc_policy_seqno(current_selinux_state);
 	/*
 	 * Since the inode label or policy seqno may have changed
@@ -7659,6 +7659,8 @@ static void delayed_superblock_init(struct super_block *sb, void *unused)
 	selinux_set_mnt_opts(sb, NULL, 0, NULL);
 }
 
+static void migrate_files(void);
+
 void selinux_complete_init(void)
 {
 	pr_debug("SELinux:  Completing initialization.\n");
@@ -7666,6 +7668,9 @@ void selinux_complete_init(void)
 	/* Set up any superblocks initialized prior to the policy load. */
 	pr_debug("SELinux:  Setting up existing superblocks.\n");
 	iterate_supers(delayed_superblock_init, NULL);
+
+	if (current_selinux_state->id != 0)
+		migrate_files();
 }
 
 /* SELinux requires early initialization in order to label
@@ -7816,3 +7821,88 @@ int selinux_disable(struct selinux_state *state)
 	return 0;
 }
 #endif
+
+
+/* TODO: check&return errors? */
+static void migrate_fds(void)
+{
+	unsigned int fd;
+	struct files_struct *files = current->files;
+	u32 tsid = current_sid();
+
+	rcu_read_lock();
+	for (fd = 0; fd < files_fdtable(files)->max_fds; fd++) {
+		struct inode *inode;
+		struct file_security_struct *fsec;
+		struct file *file = fcheck_files(files, fd);
+
+		if (!file)
+			continue;
+
+		fsec = selinux_file(file);
+
+		fsec->sid = fsec->fown_sid = tsid;
+		inode = file_inode(file);
+		if (inode) {
+			get_file(file);
+			rcu_read_unlock();
+			fsec->isid = update_sid(inode_security(inode));
+			rcu_read_lock();
+			fput(file);
+		}
+	}
+	rcu_read_unlock();
+}
+
+static int migrate_vmas(void)
+{
+	int ret;
+	struct mempolicy *task_mempolicy;
+	struct vm_area_struct *vma;
+	u32 tsid = current_sid();
+	struct mm_struct *mm =  mm_access(current, PTRACE_MODE_READ | PTRACE_MODE_FSCREDS);
+
+	if (IS_ERR_OR_NULL(mm))
+		return PTR_ERR(mm);
+
+	ret = mmap_read_lock_killable(mm);
+	if (ret)
+		goto out_put_mm;
+
+	task_mempolicy = get_task_policy(current);
+	mpol_get(task_mempolicy);
+
+	for (vma = mm->mmap; vma; vma = vma->vm_next) {
+		struct file *file = vma->vm_file;
+		struct file_security_struct *fsec;
+		struct inode *inode;
+
+		if (!file)
+			continue;
+
+		fsec = selinux_file(file);
+
+		inode = file_inode(file);
+		if (inode)
+			fsec->isid = update_sid(inode_security(inode));
+
+		fsec->sid = fsec->fown_sid = tsid;
+	}
+
+	mpol_put(task_mempolicy);
+	mmap_read_unlock(mm);
+
+out_put_mm:
+	mmput(mm);
+
+	return ret;
+}
+
+/* TODO return error? */
+void migrate_files(void)
+{
+	migrate_fds();
+
+/* TODO: return error */
+	migrate_vmas();
+}
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 2da27f2fc2e3..18c5383b87a9 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -2306,7 +2306,7 @@ static int selinuxfs_compare(struct super_block *sb, struct fs_context *fc)
 {
 	struct selinux_fs_info *fsi = sb->s_fs_info;
 
-	return (current_selinux_state == fsi->state);
+	return (current_selinux_state->id == fsi->state->id);
 }
 
 static int sel_get_tree(struct fs_context *fc)
-- 
2.34.1


  parent reply	other threads:[~2022-04-18  9:46 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <22c0d7a1-b658-64ce-f099-0b3617ef8e38@huawei.com>
     [not found] ` <CAEjxPJ5-w83HMRGuDHHqMthkju3bxT0gZ-EiiTE=t5UhQqQ_ug@mail.gmail.com>
2021-07-19 13:54   ` issues about selinux namespace xiujianfeng
2021-07-20  2:56     ` Paul Moore
2021-07-21 13:12       ` xiujianfeng
2022-02-16 12:52       ` [RFC PATCH 0/1] SELinux-namespaces Igor Baranov
2022-02-16 12:52         ` [RFC PATCH 1/1] selinuxns: Replace state pointer with namespace id Igor Baranov
2022-02-16 17:08         ` [RFC PATCH 0/1] SELinux-namespaces Casey Schaufler
2022-02-16 20:47         ` Paul Moore
2022-04-18  9:45           ` [RFC PATCH 0/7] SELinux-namespace Alexander Kozhevnikov
2022-04-18  9:45             ` [RFC PATCH 1/7] LSM: Infrastructure management of the superblock Alexander Kozhevnikov
2022-04-18  9:45             ` [RFC PATCH 2/7] selinux: support per-namespace superblock security structures Alexander Kozhevnikov
2022-04-18  9:45             ` [RFC PATCH 3/7] SELINUXNS: Fix initilization of the superblock security under spinlock Alexander Kozhevnikov
2022-04-18  9:45             ` [RFC PATCH 4/7] SELINUXNS: Namespacing for xattrs Alexander Kozhevnikov
2022-04-18  9:45             ` Alexander Kozhevnikov [this message]
2022-04-18  9:45             ` [RFC PATCH 6/7] SELINUXNS: Fixing superblock security structure memory leakage Alexander Kozhevnikov
2022-04-18  9:45             ` [RFC PATCH 7/7] SELINUXNS: Fixing concurrency issues Alexander Kozhevnikov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220418094552.128898-6-alexander.kozhevnikov@huawei.com \
    --to=alexander.kozhevnikov@huawei.com \
    --cc=anton.sirazetdinov@huawei.com \
    --cc=artem.kuzin@huawei.com \
    --cc=hw.likun@huawei.com \
    --cc=igor.baranov@huawei.com \
    --cc=jamorris@linux.microsoft.com \
    --cc=linux-security-module@vger.kernel.org \
    --cc=paul@paul-moore.com \
    --cc=selinux@vger.kernel.org \
    --cc=stephen.smalley.work@gmail.com \
    --cc=xiujianfeng@huawei.com \
    --cc=yusongping@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.