diff options
-rw-r--r-- | security/selinux/include/security.h | 3 | ||||
-rw-r--r-- | security/selinux/ss/policydb.c | 19 | ||||
-rw-r--r-- | security/selinux/ss/policydb.h | 3 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 14 |
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. */ |