aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss/policydb.c
diff options
context:
space:
mode:
authorStephen Smalley <sds@tycho.nsa.gov>2009-09-30 13:37:50 -0400
committerJames Morris <jmorris@namei.org>2009-10-07 06:56:42 -0400
commitc6d3aaa4e35c71a32a86ececacd4eea7ecfc316c (patch)
tree1a5475b4370655a22670fd6eb35e54d8b131b362 /security/selinux/ss/policydb.c
parent23acb98de5a4109a60b5fe3f0439389218b039d7 (diff)
selinux: dynamic class/perm discovery
Modify SELinux to dynamically discover class and permission values upon policy load, based on the dynamic object class/perm discovery logic from libselinux. A mapping is created between kernel-private class and permission indices used outside the security server and the policy values used within the security server. The mappings are only applied upon kernel-internal computations; similar mappings for the private indices of userspace object managers is handled on a per-object manager basis by the userspace AVC. The interfaces for compute_av and transition_sid are split for kernel vs. userspace; the userspace functions are distinguished by a _user suffix. The kernel-private class indices are no longer tied to the policy values and thus do not need to skip indices for userspace classes; thus the kernel class index values are compressed. The flask.h definitions were regenerated by deleting the userspace classes from refpolicy's definitions and then regenerating the headers. Going forward, we can just maintain the flask.h, av_permissions.h, and classmap.h definitions separately from policy as they are no longer tied to the policy values. The next patch introduces a utility to automate generation of flask.h and av_permissions.h from the classmap.h definitions. The older kernel class and permission string tables are removed and replaced by a single security class mapping table that is walked at policy load to generate the mapping. The old kernel class validation logic is completely replaced by the mapping logic. The handle unknown logic is reworked. reject_unknown=1 is handled when the mappings are computed at policy load time, similar to the old handling by the class validation logic. allow_unknown=1 is handled when computing and mapping decisions - if the permission was not able to be mapped (i.e. undefined, mapped to zero), then it is automatically added to the allowed vector. If the class was not able to be mapped (i.e. undefined, mapped to zero), then all permissions are allowed for it if allow_unknown=1. avc_audit leverages the new security class mapping table to lookup the class and permission names from the kernel-private indices. The mdp program is updated to use the new table when generating the class definitions and allow rules for a minimal boot policy for the kernel. It should be noted that this policy will not include any userspace classes, nor will its policy index values for the kernel classes correspond with the ones in refpolicy (they will instead match the kernel-private indices). Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/selinux/ss/policydb.c')
-rw-r--r--security/selinux/ss/policydb.c47
1 files changed, 45 insertions, 2 deletions
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 72e4a54973aa..f03667213ea8 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -713,7 +713,6 @@ void policydb_destroy(struct policydb *p)
713 ebitmap_destroy(&p->type_attr_map[i]); 713 ebitmap_destroy(&p->type_attr_map[i]);
714 } 714 }
715 kfree(p->type_attr_map); 715 kfree(p->type_attr_map);
716 kfree(p->undefined_perms);
717 ebitmap_destroy(&p->policycaps); 716 ebitmap_destroy(&p->policycaps);
718 ebitmap_destroy(&p->permissive_map); 717 ebitmap_destroy(&p->permissive_map);
719 718
@@ -1640,6 +1639,40 @@ static int policydb_bounds_sanity_check(struct policydb *p)
1640 1639
1641extern int ss_initialized; 1640extern int ss_initialized;
1642 1641
1642u16 string_to_security_class(struct policydb *p, const char *name)
1643{
1644 struct class_datum *cladatum;
1645
1646 cladatum = hashtab_search(p->p_classes.table, name);
1647 if (!cladatum)
1648 return 0;
1649
1650 return cladatum->value;
1651}
1652
1653u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name)
1654{
1655 struct class_datum *cladatum;
1656 struct perm_datum *perdatum = NULL;
1657 struct common_datum *comdatum;
1658
1659 if (!tclass || tclass > p->p_classes.nprim)
1660 return 0;
1661
1662 cladatum = p->class_val_to_struct[tclass-1];
1663 comdatum = cladatum->comdatum;
1664 if (comdatum)
1665 perdatum = hashtab_search(comdatum->permissions.table,
1666 name);
1667 if (!perdatum)
1668 perdatum = hashtab_search(cladatum->permissions.table,
1669 name);
1670 if (!perdatum)
1671 return 0;
1672
1673 return 1U << (perdatum->value-1);
1674}
1675
1643/* 1676/*
1644 * Read the configuration data from a policy database binary 1677 * Read the configuration data from a policy database binary
1645 * representation file into a policy database structure. 1678 * representation file into a policy database structure.
@@ -1861,6 +1894,16 @@ int policydb_read(struct policydb *p, void *fp)
1861 if (rc) 1894 if (rc)
1862 goto bad; 1895 goto bad;
1863 1896
1897 p->process_class = string_to_security_class(p, "process");
1898 if (!p->process_class)
1899 goto bad;
1900 p->process_trans_perms = string_to_av_perm(p, p->process_class,
1901 "transition");
1902 p->process_trans_perms |= string_to_av_perm(p, p->process_class,
1903 "dyntransition");
1904 if (!p->process_trans_perms)
1905 goto bad;
1906
1864 for (i = 0; i < info->ocon_num; i++) { 1907 for (i = 0; i < info->ocon_num; i++) {
1865 rc = next_entry(buf, fp, sizeof(u32)); 1908 rc = next_entry(buf, fp, sizeof(u32));
1866 if (rc < 0) 1909 if (rc < 0)
@@ -2101,7 +2144,7 @@ int policydb_read(struct policydb *p, void *fp)
2101 goto bad; 2144 goto bad;
2102 rt->target_class = le32_to_cpu(buf[0]); 2145 rt->target_class = le32_to_cpu(buf[0]);
2103 } else 2146 } else
2104 rt->target_class = SECCLASS_PROCESS; 2147 rt->target_class = p->process_class;
2105 if (!policydb_type_isvalid(p, rt->source_type) || 2148 if (!policydb_type_isvalid(p, rt->source_type) ||
2106 !policydb_type_isvalid(p, rt->target_type) || 2149 !policydb_type_isvalid(p, rt->target_type) ||
2107 !policydb_class_isvalid(p, rt->target_class)) { 2150 !policydb_class_isvalid(p, rt->target_class)) {