From aa893269de6277b44be88e25dcd5331c934c29c4 Mon Sep 17 00:00:00 2001
From: Eric Paris <eparis@redhat.com>
Date: Tue, 20 Mar 2012 14:35:12 -0400
Subject: SELinux: allow default source/target selectors for user/role/range

When new objects are created we have great and flexible rules to
determine the type of the new object.  We aren't quite as flexible or
mature when it comes to determining the user, role, and range.  This
patch adds a new ability to specify the place a new objects user, role,
and range should come from.  For users and roles it can come from either
the source or the target of the operation.  aka for files the user can
either come from the source (the running process and todays default) or
it can come from the target (aka the parent directory of the new file)

examples always are done with
directory context: system_u:object_r:mnt_t:s0-s0:c0.c512
process context: unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

[no rule]
	unconfined_u:object_r:mnt_t:s0   test_none
[default user source]
	unconfined_u:object_r:mnt_t:s0   test_user_source
[default user target]
	system_u:object_r:mnt_t:s0       test_user_target
[default role source]
	unconfined_u:unconfined_r:mnt_t:s0 test_role_source
[default role target]
	unconfined_u:object_r:mnt_t:s0   test_role_target
[default range source low]
	unconfined_u:object_r:mnt_t:s0 test_range_source_low
[default range source high]
	unconfined_u:object_r:mnt_t:s0:c0.c1023 test_range_source_high
[default range source low-high]
	unconfined_u:object_r:mnt_t:s0-s0:c0.c1023 test_range_source_low-high
[default range target low]
	unconfined_u:object_r:mnt_t:s0 test_range_target_low
[default range target high]
	unconfined_u:object_r:mnt_t:s0:c0.c512 test_range_target_high
[default range target low-high]
	unconfined_u:object_r:mnt_t:s0-s0:c0.c512 test_range_target_low-high

Signed-off-by: Eric Paris <eparis@redhat.com>
---
 security/selinux/include/security.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'security/selinux/include/security.h')

diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index d871e8ad2103..ba53400195c0 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -31,13 +31,14 @@
 #define POLICYDB_VERSION_BOUNDARY	24
 #define POLICYDB_VERSION_FILENAME_TRANS	25
 #define POLICYDB_VERSION_ROLETRANS	26
+#define POLICYDB_VERSION_NEW_OBJECT_DEFAULTS	27
 
 /* Range of policy versions we understand*/
 #define POLICYDB_VERSION_MIN   POLICYDB_VERSION_BASE
 #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
 #define POLICYDB_VERSION_MAX	CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
 #else
-#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_ROLETRANS
+#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_NEW_OBJECT_DEFAULTS
 #endif
 
 /* Mask for just the mount related flags */
-- 
cgit v1.2.3


From eed7795d0a2c9b2e934afc088e903fa2c17b7958 Mon Sep 17 00:00:00 2001
From: Eric Paris <eparis@redhat.com>
Date: Tue, 20 Mar 2012 14:35:12 -0400
Subject: SELinux: add default_type statements

Because Fedora shipped userspace based on my development tree we now
have policy version 27 in the wild defining only default user, role, and
range.  Thus to add default_type we need a policy.28.

Signed-off-by: Eric Paris <eparis@redhat.com>
---
 security/selinux/include/security.h |  3 ++-
 security/selinux/ss/policydb.c      | 19 +++++++++++++++++++
 security/selinux/ss/policydb.h      |  3 ++-
 security/selinux/ss/services.c      | 14 ++++++++++----
 4 files changed, 33 insertions(+), 6 deletions(-)

(limited to 'security/selinux/include/security.h')

diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index ba53400195c0..dde2005407aa 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -32,13 +32,14 @@
 #define POLICYDB_VERSION_FILENAME_TRANS	25
 #define POLICYDB_VERSION_ROLETRANS	26
 #define POLICYDB_VERSION_NEW_OBJECT_DEFAULTS	27
+#define POLICYDB_VERSION_DEFAULT_TYPE	28
 
 /* Range of policy versions we understand*/
 #define POLICYDB_VERSION_MIN   POLICYDB_VERSION_BASE
 #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
 #define POLICYDB_VERSION_MAX	CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
 #else
-#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_NEW_OBJECT_DEFAULTS
+#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_DEFAULT_TYPE
 #endif
 
 /* Mask for just the mount related flags */
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 2bb9c2fd5f1a..9cd9b7c661ec 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -138,6 +138,11 @@ static struct policydb_compat_info policydb_compat[] = {
 		.sym_num	= SYM_NUM,
 		.ocon_num	= OCON_NUM,
 	},
+	{
+		.version	= POLICYDB_VERSION_DEFAULT_TYPE,
+		.sym_num	= SYM_NUM,
+		.ocon_num	= OCON_NUM,
+	},
 };
 
 static struct policydb_compat_info *policydb_lookup_compat(int version)
@@ -1321,6 +1326,13 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
 		cladatum->default_range = le32_to_cpu(buf[2]);
 	}
 
+	if (p->policyvers >= POLICYDB_VERSION_DEFAULT_TYPE) {
+		rc = next_entry(buf, fp, sizeof(u32) * 1);
+		if (rc)
+			goto bad;
+		cladatum->default_type = le32_to_cpu(buf[0]);
+	}
+
 	rc = hashtab_insert(h, key, cladatum);
 	if (rc)
 		goto bad;
@@ -2857,6 +2869,13 @@ static int class_write(void *vkey, void *datum, void *ptr)
 			return rc;
 	}
 
+	if (p->policyvers >= POLICYDB_VERSION_DEFAULT_TYPE) {
+		buf[0] = cpu_to_le32(cladatum->default_type);
+		rc = put_entry(buf, sizeof(uint32_t), 1, fp);
+		if (rc)
+			return rc;
+	}
+
 	return 0;
 }
 
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index a949f1ad43bb..da637471d4ce 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -60,11 +60,12 @@ struct class_datum {
 	struct symtab permissions;	/* class-specific permission symbol table */
 	struct constraint_node *constraints;	/* constraints on class permissions */
 	struct constraint_node *validatetrans;	/* special transition rules */
-	/* Options how a new object user and role should be decided */
+/* Options how a new object user, role, and type should be decided */
 #define DEFAULT_SOURCE         1
 #define DEFAULT_TARGET         2
 	char default_user;
 	char default_role;
+	char default_type;
 /* Options how a new object range should be decided */
 #define DEFAULT_SOURCE_LOW     1
 #define DEFAULT_SOURCE_HIGH    2
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 2ea108c2c048..1ded0ec7e8c2 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -1472,12 +1472,18 @@ static int security_compute_sid(u32 ssid,
 	}
 
 	/* Set the type to default values. */
-	if ((tclass == policydb.process_class) || (sock == true)) {
-		/* Use the type of process. */
+	if (cladatum && cladatum->default_type == DEFAULT_SOURCE) {
 		newcontext.type = scontext->type;
-	} else {
-		/* Use the type of the related object. */
+	} else if (cladatum && cladatum->default_type == DEFAULT_TARGET) {
 		newcontext.type = tcontext->type;
+	} else {
+		if ((tclass == policydb.process_class) || (sock == true)) {
+			/* Use the type of process. */
+			newcontext.type = scontext->type;
+		} else {
+			/* Use the type of the related object. */
+			newcontext.type = tcontext->type;
+		}
 	}
 
 	/* Look for a type transition/member/change rule. */
-- 
cgit v1.2.3