summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--security/selinux/include/security.h3
-rw-r--r--security/selinux/ss/policydb.c19
-rw-r--r--security/selinux/ss/policydb.h3
-rw-r--r--security/selinux/ss/services.c14
4 files changed, 33 insertions, 6 deletions
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index ba53400195c..dde2005407a 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 2bb9c2fd5f1..9cd9b7c661e 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 a949f1ad43b..da637471d4c 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 2ea108c2c04..1ded0ec7e8c 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. */