Re: [PATCH] Permissive domain in userspace (Re: Some ideas in SE-PostgreSQL enhancement)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



KaiGai Kohei wrote:
> If we have an entry something like "/selinux/permissive" to return
> whether the given domain is permissive or not, I think we don't need
> to have the flags field on security_compute_av(). It can be checked
> on the creation of userspace avc entry, and checked it on later access
> controls.

The attached patch exposes a new entry in selinuxfs, which enables
userspace stuff to make a query whether the given context is permissive
domain, or not.
If the given context is permissive domain, userspace stuffs can mark
its entry as a permissive one on creation of avc entries, to avoid
policy enforcement on permissive domains.

It now checks security:{check_context} permission, but it should be
discussed what permission to be checked here.

The attached check_permissive.c is an example to use the interface.

  [kaigai@saba ~]$ ./check_permissive staff_u:staff_r:staff_t:s0
  staff_u:staff_r:staff_t:s0 is a permissive domain
  [kaigai@saba ~]$ ./check_permissive user_u:user_r:user_t:s0
  user_u:user_r:user_t:s0 is NOT a permissive domain

Thanks,
-- 
OSS Platform Development Division, NEC
KaiGai Kohei <kaigai@xxxxxxxxxxxxx>
 Signed-off-by: KaiGai Kohei <kaigai@xxxxxxxxxxxxx>
--
 security/selinux/selinuxfs.c |   24 ++++++++++++++++++++++++
 1 files changed, 24 insertions(+), 0 deletions(-)

diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index d3c8b98..10accc0 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -122,6 +122,7 @@ enum sel_inos {
 	SEL_COMPAT_NET,	/* whether to use old compat network packet controls */
 	SEL_REJECT_UNKNOWN, /* export unknown reject handling to userspace */
 	SEL_DENY_UNKNOWN, /* export unknown deny handling to userspace */
+	SEL_PERMISSIVE,	/* check whether permissive domain or not */
 	SEL_INO_NEXT,	/* The next inode number to use */
 };
 
@@ -513,6 +514,7 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size);
 static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size);
 static ssize_t sel_write_user(struct file *file, char *buf, size_t size);
 static ssize_t sel_write_member(struct file *file, char *buf, size_t size);
+static ssize_t sel_write_permissive(struct file *file, char *buf, size_t size);
 
 static ssize_t (*write_op[])(struct file *, char *, size_t) = {
 	[SEL_ACCESS] = sel_write_access,
@@ -521,6 +523,7 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = {
 	[SEL_USER] = sel_write_user,
 	[SEL_MEMBER] = sel_write_member,
 	[SEL_CONTEXT] = sel_write_context,
+	[SEL_PERMISSIVE] = sel_write_permissive,
 };
 
 static ssize_t selinux_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos)
@@ -841,6 +844,26 @@ out:
 	return length;
 }
 
+static ssize_t sel_write_permissive(struct file *file, char *buf, size_t size)
+{
+	u32 sid;
+	ssize_t rc;
+
+	/*
+	 * MEMO: Is it correct to check security:{check_context} here?
+	 * Or, we should add something like security:{check_permissive}?
+	 */
+	rc = task_has_security(current, SECURITY__CHECK_CONTEXT);
+	if (rc)
+		return rc;
+
+	rc = security_context_to_sid(buf, size, &sid);
+	if (rc < 0)
+		return rc;
+
+	return security_permissive_sid(sid);
+}
+
 static struct inode *sel_make_inode(struct super_block *sb, int mode)
 {
 	struct inode *ret = new_inode(sb);
@@ -1668,6 +1691,7 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
 		[SEL_COMPAT_NET] = {"compat_net", &sel_compat_net_ops, S_IRUGO|S_IWUSR},
 		[SEL_REJECT_UNKNOWN] = {"reject_unknown", &sel_handle_unknown_ops, S_IRUGO},
 		[SEL_DENY_UNKNOWN] = {"deny_unknown", &sel_handle_unknown_ops, S_IRUGO},
+		[SEL_PERMISSIVE] = {"permissive", &transaction_ops, S_IRUGO|S_IWUGO},
 		/* last one */ {""}
 	};
 	ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <selinux/selinux.h>

int main(int argc, char *argv[])
{
	const char *path = "/selinux/permissive";
	int fd, rc;

	if (argv[1] == NULL) {
		fprintf(stderr, "usage: %s <context>\n", argv[0]);
		return -1;
	}

	fd = open(path, O_RDWR);
	if (fd < 0) {
		fprintf(stderr, "could not open %s (%s)\n",
			path, strerror(errno));
		return -1;
	}

	rc = write(fd, argv[1], strlen(argv[1]));
	if (rc < 0) {
		fprintf(stderr, "error: write('%s', '%s') (%s)\n",
			path, argv[1], strerror(errno));
		return -1;
	}

	printf("%s is %s permissive domain\n",
	       argv[1], rc ? "a" : "NOT a");

	close(fd);

	return 0;
}

[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux