diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index 86131d9c89c..6962d15f549 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c @@ -1385,6 +1385,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; @@ -2945,6 +2952,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 6ffc75f519a..725d5945a97 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 e1705aa3ac8..9ddca68b69b 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -1639,12 +1639,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. */