SELinux: add default_type statements
Eric Paris [Tue, 20 Mar 2012 18:35:12 +0000 (14:35 -0400)]
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
security/selinux/ss/policydb.c
security/selinux/ss/policydb.h
security/selinux/ss/services.c

index ba53400..dde2005 100644 (file)
 #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 */
index 2bb9c2f..9cd9b7c 100644 (file)
@@ -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;
 }
 
index a949f1a..da63747 100644 (file)
@@ -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
index 2ea108c..1ded0ec 100644 (file)
@@ -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. */