aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss
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
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')
-rw-r--r--security/selinux/ss/mls.c2
-rw-r--r--security/selinux/ss/policydb.c47
-rw-r--r--security/selinux/ss/policydb.h7
-rw-r--r--security/selinux/ss/services.c540
4 files changed, 339 insertions, 257 deletions
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index b5407f16c2a4..3f2b2706b5bb 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -532,7 +532,7 @@ int mls_compute_sid(struct context *scontext,
532 } 532 }
533 /* Fallthrough */ 533 /* Fallthrough */
534 case AVTAB_CHANGE: 534 case AVTAB_CHANGE:
535 if (tclass == SECCLASS_PROCESS) 535 if (tclass == policydb.process_class)
536 /* Use the process MLS attributes. */ 536 /* Use the process MLS attributes. */
537 return mls_context_cpy(newcontext, scontext); 537 return mls_context_cpy(newcontext, scontext);
538 else 538 else
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)) {
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index 55152d498b53..cdcc5700946f 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -254,7 +254,9 @@ struct policydb {
254 254
255 unsigned int reject_unknown : 1; 255 unsigned int reject_unknown : 1;
256 unsigned int allow_unknown : 1; 256 unsigned int allow_unknown : 1;
257 u32 *undefined_perms; 257
258 u16 process_class;
259 u32 process_trans_perms;
258}; 260};
259 261
260extern void policydb_destroy(struct policydb *p); 262extern void policydb_destroy(struct policydb *p);
@@ -295,5 +297,8 @@ static inline int next_entry(void *buf, struct policy_file *fp, size_t bytes)
295 return 0; 297 return 0;
296} 298}
297 299
300extern u16 string_to_security_class(struct policydb *p, const char *name);
301extern u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name);
302
298#endif /* _SS_POLICYDB_H_ */ 303#endif /* _SS_POLICYDB_H_ */
299 304
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index ff17820d35ec..e19baa81fdec 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -70,11 +70,6 @@ unsigned int policydb_loaded_version;
70int selinux_policycap_netpeer; 70int selinux_policycap_netpeer;
71int selinux_policycap_openperm; 71int selinux_policycap_openperm;
72 72
73/*
74 * This is declared in avc.c
75 */
76extern const struct selinux_class_perm selinux_class_perm;
77
78static DEFINE_RWLOCK(policy_rwlock); 73static DEFINE_RWLOCK(policy_rwlock);
79 74
80static struct sidtab sidtab; 75static struct sidtab sidtab;
@@ -98,6 +93,158 @@ static int context_struct_compute_av(struct context *scontext,
98 u16 tclass, 93 u16 tclass,
99 u32 requested, 94 u32 requested,
100 struct av_decision *avd); 95 struct av_decision *avd);
96
97struct selinux_mapping {
98 u16 value; /* policy value */
99 unsigned num_perms;
100 u32 perms[sizeof(u32) * 8];
101};
102
103static struct selinux_mapping *current_mapping;
104static u16 current_mapping_size;
105
106static int selinux_set_mapping(struct policydb *pol,
107 struct security_class_mapping *map,
108 struct selinux_mapping **out_map_p,
109 u16 *out_map_size)
110{
111 struct selinux_mapping *out_map = NULL;
112 size_t size = sizeof(struct selinux_mapping);
113 u16 i, j;
114 unsigned k;
115 bool print_unknown_handle = false;
116
117 /* Find number of classes in the input mapping */
118 if (!map)
119 return -EINVAL;
120 i = 0;
121 while (map[i].name)
122 i++;
123
124 /* Allocate space for the class records, plus one for class zero */
125 out_map = kcalloc(++i, size, GFP_ATOMIC);
126 if (!out_map)
127 return -ENOMEM;
128
129 /* Store the raw class and permission values */
130 j = 0;
131 while (map[j].name) {
132 struct security_class_mapping *p_in = map + (j++);
133 struct selinux_mapping *p_out = out_map + j;
134
135 /* An empty class string skips ahead */
136 if (!strcmp(p_in->name, "")) {
137 p_out->num_perms = 0;
138 continue;
139 }
140
141 p_out->value = string_to_security_class(pol, p_in->name);
142 if (!p_out->value) {
143 printk(KERN_INFO
144 "SELinux: Class %s not defined in policy.\n",
145 p_in->name);
146 if (pol->reject_unknown)
147 goto err;
148 p_out->num_perms = 0;
149 print_unknown_handle = true;
150 continue;
151 }
152
153 k = 0;
154 while (p_in->perms && p_in->perms[k]) {
155 /* An empty permission string skips ahead */
156 if (!*p_in->perms[k]) {
157 k++;
158 continue;
159 }
160 p_out->perms[k] = string_to_av_perm(pol, p_out->value,
161 p_in->perms[k]);
162 if (!p_out->perms[k]) {
163 printk(KERN_INFO
164 "SELinux: Permission %s in class %s not defined in policy.\n",
165 p_in->perms[k], p_in->name);
166 if (pol->reject_unknown)
167 goto err;
168 print_unknown_handle = true;
169 }
170
171 k++;
172 }
173 p_out->num_perms = k;
174 }
175
176 if (print_unknown_handle)
177 printk(KERN_INFO "SELinux: the above unknown classes and permissions will be %s\n",
178 pol->allow_unknown ? "allowed" : "denied");
179
180 *out_map_p = out_map;
181 *out_map_size = i;
182 return 0;
183err:
184 kfree(out_map);
185 return -EINVAL;
186}
187
188/*
189 * Get real, policy values from mapped values
190 */
191
192static u16 unmap_class(u16 tclass)
193{
194 if (tclass < current_mapping_size)
195 return current_mapping[tclass].value;
196
197 return tclass;
198}
199
200static u32 unmap_perm(u16 tclass, u32 tperm)
201{
202 if (tclass < current_mapping_size) {
203 unsigned i;
204 u32 kperm = 0;
205
206 for (i = 0; i < current_mapping[tclass].num_perms; i++)
207 if (tperm & (1<<i)) {
208 kperm |= current_mapping[tclass].perms[i];
209 tperm &= ~(1<<i);
210 }
211 return kperm;
212 }
213
214 return tperm;
215}
216
217static void map_decision(u16 tclass, struct av_decision *avd,
218 int allow_unknown)
219{
220 if (tclass < current_mapping_size) {
221 unsigned i, n = current_mapping[tclass].num_perms;
222 u32 result;
223
224 for (i = 0, result = 0; i < n; i++) {
225 if (avd->allowed & current_mapping[tclass].perms[i])
226 result |= 1<<i;
227 if (allow_unknown && !current_mapping[tclass].perms[i])
228 result |= 1<<i;
229 }
230 avd->allowed = result;
231
232 for (i = 0, result = 0; i < n; i++)
233 if (avd->auditallow & current_mapping[tclass].perms[i])
234 result |= 1<<i;
235 avd->auditallow = result;
236
237 for (i = 0, result = 0; i < n; i++) {
238 if (avd->auditdeny & current_mapping[tclass].perms[i])
239 result |= 1<<i;
240 if (!allow_unknown && !current_mapping[tclass].perms[i])
241 result |= 1<<i;
242 }
243 avd->auditdeny = result;
244 }
245}
246
247
101/* 248/*
102 * Return the boolean value of a constraint expression 249 * Return the boolean value of a constraint expression
103 * when it is applied to the specified source and target 250 * when it is applied to the specified source and target
@@ -467,7 +614,6 @@ static int context_struct_compute_av(struct context *scontext,
467 struct class_datum *tclass_datum; 614 struct class_datum *tclass_datum;
468 struct ebitmap *sattr, *tattr; 615 struct ebitmap *sattr, *tattr;
469 struct ebitmap_node *snode, *tnode; 616 struct ebitmap_node *snode, *tnode;
470 const struct selinux_class_perm *kdefs = &selinux_class_perm;
471 unsigned int i, j; 617 unsigned int i, j;
472 618
473 /* 619 /*
@@ -477,9 +623,9 @@ static int context_struct_compute_av(struct context *scontext,
477 * to remain in the correct class. 623 * to remain in the correct class.
478 */ 624 */
479 if (policydb_loaded_version < POLICYDB_VERSION_NLCLASS) 625 if (policydb_loaded_version < POLICYDB_VERSION_NLCLASS)
480 if (tclass >= SECCLASS_NETLINK_ROUTE_SOCKET && 626 if (tclass >= unmap_class(SECCLASS_NETLINK_ROUTE_SOCKET) &&
481 tclass <= SECCLASS_NETLINK_DNRT_SOCKET) 627 tclass <= unmap_class(SECCLASS_NETLINK_DNRT_SOCKET))
482 tclass = SECCLASS_NETLINK_SOCKET; 628 tclass = unmap_class(SECCLASS_NETLINK_SOCKET);
483 629
484 /* 630 /*
485 * Initialize the access vectors to the default values. 631 * Initialize the access vectors to the default values.
@@ -490,33 +636,11 @@ static int context_struct_compute_av(struct context *scontext,
490 avd->seqno = latest_granting; 636 avd->seqno = latest_granting;
491 avd->flags = 0; 637 avd->flags = 0;
492 638
493 /* 639 if (unlikely(!tclass || tclass > policydb.p_classes.nprim)) {
494 * Check for all the invalid cases. 640 if (printk_ratelimit())
495 * - tclass 0 641 printk(KERN_WARNING "SELinux: Invalid class %hu\n", tclass);
496 * - tclass > policy and > kernel 642 return -EINVAL;
497 * - tclass > policy but is a userspace class 643 }
498 * - tclass > policy but we do not allow unknowns
499 */
500 if (unlikely(!tclass))
501 goto inval_class;
502 if (unlikely(tclass > policydb.p_classes.nprim))
503 if (tclass > kdefs->cts_len ||
504 !kdefs->class_to_string[tclass] ||
505 !policydb.allow_unknown)
506 goto inval_class;
507
508 /*
509 * Kernel class and we allow unknown so pad the allow decision
510 * the pad will be all 1 for unknown classes.
511 */
512 if (tclass <= kdefs->cts_len && policydb.allow_unknown)
513 avd->allowed = policydb.undefined_perms[tclass - 1];
514
515 /*
516 * Not in policy. Since decision is completed (all 1 or all 0) return.
517 */
518 if (unlikely(tclass > policydb.p_classes.nprim))
519 return 0;
520 644
521 tclass_datum = policydb.class_val_to_struct[tclass - 1]; 645 tclass_datum = policydb.class_val_to_struct[tclass - 1];
522 646
@@ -568,8 +692,8 @@ static int context_struct_compute_av(struct context *scontext,
568 * role is changing, then check the (current_role, new_role) 692 * role is changing, then check the (current_role, new_role)
569 * pair. 693 * pair.
570 */ 694 */
571 if (tclass == SECCLASS_PROCESS && 695 if (tclass == policydb.process_class &&
572 (avd->allowed & (PROCESS__TRANSITION | PROCESS__DYNTRANSITION)) && 696 (avd->allowed & policydb.process_trans_perms) &&
573 scontext->role != tcontext->role) { 697 scontext->role != tcontext->role) {
574 for (ra = policydb.role_allow; ra; ra = ra->next) { 698 for (ra = policydb.role_allow; ra; ra = ra->next) {
575 if (scontext->role == ra->role && 699 if (scontext->role == ra->role &&
@@ -577,8 +701,7 @@ static int context_struct_compute_av(struct context *scontext,
577 break; 701 break;
578 } 702 }
579 if (!ra) 703 if (!ra)
580 avd->allowed &= ~(PROCESS__TRANSITION | 704 avd->allowed &= ~policydb.process_trans_perms;
581 PROCESS__DYNTRANSITION);
582 } 705 }
583 706
584 /* 707 /*
@@ -590,21 +713,6 @@ static int context_struct_compute_av(struct context *scontext,
590 tclass, requested, avd); 713 tclass, requested, avd);
591 714
592 return 0; 715 return 0;
593
594inval_class:
595 if (!tclass || tclass > kdefs->cts_len ||
596 !kdefs->class_to_string[tclass]) {
597 if (printk_ratelimit())
598 printk(KERN_ERR "SELinux: %s: unrecognized class %d\n",
599 __func__, tclass);
600 return -EINVAL;
601 }
602
603 /*
604 * Known to the kernel, but not to the policy.
605 * Handle as a denial (allowed is 0).
606 */
607 return 0;
608} 716}
609 717
610static int security_validtrans_handle_fail(struct context *ocontext, 718static int security_validtrans_handle_fail(struct context *ocontext,
@@ -636,13 +744,14 @@ out:
636} 744}
637 745
638int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, 746int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
639 u16 tclass) 747 u16 orig_tclass)
640{ 748{
641 struct context *ocontext; 749 struct context *ocontext;
642 struct context *ncontext; 750 struct context *ncontext;
643 struct context *tcontext; 751 struct context *tcontext;
644 struct class_datum *tclass_datum; 752 struct class_datum *tclass_datum;
645 struct constraint_node *constraint; 753 struct constraint_node *constraint;
754 u16 tclass;
646 int rc = 0; 755 int rc = 0;
647 756
648 if (!ss_initialized) 757 if (!ss_initialized)
@@ -650,6 +759,8 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
650 759
651 read_lock(&policy_rwlock); 760 read_lock(&policy_rwlock);
652 761
762 tclass = unmap_class(orig_tclass);
763
653 /* 764 /*
654 * Remap extended Netlink classes for old policy versions. 765 * Remap extended Netlink classes for old policy versions.
655 * Do this here rather than socket_type_to_security_class() 766 * Do this here rather than socket_type_to_security_class()
@@ -657,9 +768,9 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
657 * to remain in the correct class. 768 * to remain in the correct class.
658 */ 769 */
659 if (policydb_loaded_version < POLICYDB_VERSION_NLCLASS) 770 if (policydb_loaded_version < POLICYDB_VERSION_NLCLASS)
660 if (tclass >= SECCLASS_NETLINK_ROUTE_SOCKET && 771 if (tclass >= unmap_class(SECCLASS_NETLINK_ROUTE_SOCKET) &&
661 tclass <= SECCLASS_NETLINK_DNRT_SOCKET) 772 tclass <= unmap_class(SECCLASS_NETLINK_DNRT_SOCKET))
662 tclass = SECCLASS_NETLINK_SOCKET; 773 tclass = unmap_class(SECCLASS_NETLINK_SOCKET);
663 774
664 if (!tclass || tclass > policydb.p_classes.nprim) { 775 if (!tclass || tclass > policydb.p_classes.nprim) {
665 printk(KERN_ERR "SELinux: %s: unrecognized class %d\n", 776 printk(KERN_ERR "SELinux: %s: unrecognized class %d\n",
@@ -792,6 +903,38 @@ out:
792} 903}
793 904
794 905
906static int security_compute_av_core(u32 ssid,
907 u32 tsid,
908 u16 tclass,
909 u32 requested,
910 struct av_decision *avd)
911{
912 struct context *scontext = NULL, *tcontext = NULL;
913 int rc = 0;
914
915 scontext = sidtab_search(&sidtab, ssid);
916 if (!scontext) {
917 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
918 __func__, ssid);
919 return -EINVAL;
920 }
921 tcontext = sidtab_search(&sidtab, tsid);
922 if (!tcontext) {
923 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
924 __func__, tsid);
925 return -EINVAL;
926 }
927
928 rc = context_struct_compute_av(scontext, tcontext, tclass,
929 requested, avd);
930
931 /* permissive domain? */
932 if (ebitmap_get_bit(&policydb.permissive_map, scontext->type))
933 avd->flags |= AVD_FLAGS_PERMISSIVE;
934
935 return rc;
936}
937
795/** 938/**
796 * security_compute_av - Compute access vector decisions. 939 * security_compute_av - Compute access vector decisions.
797 * @ssid: source security identifier 940 * @ssid: source security identifier
@@ -807,12 +950,45 @@ out:
807 */ 950 */
808int security_compute_av(u32 ssid, 951int security_compute_av(u32 ssid,
809 u32 tsid, 952 u32 tsid,
810 u16 tclass, 953 u16 orig_tclass,
811 u32 requested, 954 u32 orig_requested,
812 struct av_decision *avd) 955 struct av_decision *avd)
813{ 956{
814 struct context *scontext = NULL, *tcontext = NULL; 957 u16 tclass;
815 int rc = 0; 958 u32 requested;
959 int rc;
960
961 if (!ss_initialized)
962 goto allow;
963
964 read_lock(&policy_rwlock);
965 requested = unmap_perm(orig_tclass, orig_requested);
966 tclass = unmap_class(orig_tclass);
967 if (unlikely(orig_tclass && !tclass)) {
968 if (policydb.allow_unknown)
969 goto allow;
970 return -EINVAL;
971 }
972 rc = security_compute_av_core(ssid, tsid, tclass, requested, avd);
973 map_decision(orig_tclass, avd, policydb.allow_unknown);
974 read_unlock(&policy_rwlock);
975 return rc;
976allow:
977 avd->allowed = 0xffffffff;
978 avd->auditallow = 0;
979 avd->auditdeny = 0xffffffff;
980 avd->seqno = latest_granting;
981 avd->flags = 0;
982 return 0;
983}
984
985int security_compute_av_user(u32 ssid,
986 u32 tsid,
987 u16 tclass,
988 u32 requested,
989 struct av_decision *avd)
990{
991 int rc;
816 992
817 if (!ss_initialized) { 993 if (!ss_initialized) {
818 avd->allowed = 0xffffffff; 994 avd->allowed = 0xffffffff;
@@ -823,29 +999,7 @@ int security_compute_av(u32 ssid,
823 } 999 }
824 1000
825 read_lock(&policy_rwlock); 1001 read_lock(&policy_rwlock);
826 1002 rc = security_compute_av_core(ssid, tsid, tclass, requested, avd);
827 scontext = sidtab_search(&sidtab, ssid);
828 if (!scontext) {
829 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
830 __func__, ssid);
831 rc = -EINVAL;
832 goto out;
833 }
834 tcontext = sidtab_search(&sidtab, tsid);
835 if (!tcontext) {
836 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
837 __func__, tsid);
838 rc = -EINVAL;
839 goto out;
840 }
841
842 rc = context_struct_compute_av(scontext, tcontext, tclass,
843 requested, avd);
844
845 /* permissive domain? */
846 if (ebitmap_get_bit(&policydb.permissive_map, scontext->type))
847 avd->flags |= AVD_FLAGS_PERMISSIVE;
848out:
849 read_unlock(&policy_rwlock); 1003 read_unlock(&policy_rwlock);
850 return rc; 1004 return rc;
851} 1005}
@@ -1204,20 +1358,22 @@ out:
1204 1358
1205static int security_compute_sid(u32 ssid, 1359static int security_compute_sid(u32 ssid,
1206 u32 tsid, 1360 u32 tsid,
1207 u16 tclass, 1361 u16 orig_tclass,
1208 u32 specified, 1362 u32 specified,
1209 u32 *out_sid) 1363 u32 *out_sid,
1364 bool kern)
1210{ 1365{
1211 struct context *scontext = NULL, *tcontext = NULL, newcontext; 1366 struct context *scontext = NULL, *tcontext = NULL, newcontext;
1212 struct role_trans *roletr = NULL; 1367 struct role_trans *roletr = NULL;
1213 struct avtab_key avkey; 1368 struct avtab_key avkey;
1214 struct avtab_datum *avdatum; 1369 struct avtab_datum *avdatum;
1215 struct avtab_node *node; 1370 struct avtab_node *node;
1371 u16 tclass;
1216 int rc = 0; 1372 int rc = 0;
1217 1373
1218 if (!ss_initialized) { 1374 if (!ss_initialized) {
1219 switch (tclass) { 1375 switch (orig_tclass) {
1220 case SECCLASS_PROCESS: 1376 case SECCLASS_PROCESS: /* kernel value */
1221 *out_sid = ssid; 1377 *out_sid = ssid;
1222 break; 1378 break;
1223 default: 1379 default:
@@ -1231,6 +1387,11 @@ static int security_compute_sid(u32 ssid,
1231 1387
1232 read_lock(&policy_rwlock); 1388 read_lock(&policy_rwlock);
1233 1389
1390 if (kern)
1391 tclass = unmap_class(orig_tclass);
1392 else
1393 tclass = orig_tclass;
1394
1234 scontext = sidtab_search(&sidtab, ssid); 1395 scontext = sidtab_search(&sidtab, ssid);
1235 if (!scontext) { 1396 if (!scontext) {
1236 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", 1397 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
@@ -1260,13 +1421,11 @@ static int security_compute_sid(u32 ssid,
1260 } 1421 }
1261 1422
1262 /* Set the role and type to default values. */ 1423 /* Set the role and type to default values. */
1263 switch (tclass) { 1424 if (tclass == policydb.process_class) {
1264 case SECCLASS_PROCESS:
1265 /* Use the current role and type of process. */ 1425 /* Use the current role and type of process. */
1266 newcontext.role = scontext->role; 1426 newcontext.role = scontext->role;
1267 newcontext.type = scontext->type; 1427 newcontext.type = scontext->type;
1268 break; 1428 } else {
1269 default:
1270 /* Use the well-defined object role. */ 1429 /* Use the well-defined object role. */
1271 newcontext.role = OBJECT_R_VAL; 1430 newcontext.role = OBJECT_R_VAL;
1272 /* Use the type of the related object. */ 1431 /* Use the type of the related object. */
@@ -1297,8 +1456,7 @@ static int security_compute_sid(u32 ssid,
1297 } 1456 }
1298 1457
1299 /* Check for class-specific changes. */ 1458 /* Check for class-specific changes. */
1300 switch (tclass) { 1459 if (tclass == policydb.process_class) {
1301 case SECCLASS_PROCESS:
1302 if (specified & AVTAB_TRANSITION) { 1460 if (specified & AVTAB_TRANSITION) {
1303 /* Look for a role transition rule. */ 1461 /* Look for a role transition rule. */
1304 for (roletr = policydb.role_tr; roletr; 1462 for (roletr = policydb.role_tr; roletr;
@@ -1311,9 +1469,6 @@ static int security_compute_sid(u32 ssid,
1311 } 1469 }
1312 } 1470 }
1313 } 1471 }
1314 break;
1315 default:
1316 break;
1317 } 1472 }
1318 1473
1319 /* Set the MLS attributes. 1474 /* Set the MLS attributes.
@@ -1358,7 +1513,17 @@ int security_transition_sid(u32 ssid,
1358 u16 tclass, 1513 u16 tclass,
1359 u32 *out_sid) 1514 u32 *out_sid)
1360{ 1515{
1361 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, out_sid); 1516 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,
1517 out_sid, true);
1518}
1519
1520int security_transition_sid_user(u32 ssid,
1521 u32 tsid,
1522 u16 tclass,
1523 u32 *out_sid)
1524{
1525 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,
1526 out_sid, false);
1362} 1527}
1363 1528
1364/** 1529/**
@@ -1379,7 +1544,8 @@ int security_member_sid(u32 ssid,
1379 u16 tclass, 1544 u16 tclass,
1380 u32 *out_sid) 1545 u32 *out_sid)
1381{ 1546{
1382 return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, out_sid); 1547 return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, out_sid,
1548 false);
1383} 1549}
1384 1550
1385/** 1551/**
@@ -1400,144 +1566,8 @@ int security_change_sid(u32 ssid,
1400 u16 tclass, 1566 u16 tclass,
1401 u32 *out_sid) 1567 u32 *out_sid)
1402{ 1568{
1403 return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, out_sid); 1569 return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, out_sid,
1404} 1570 false);
1405
1406/*
1407 * Verify that each kernel class that is defined in the
1408 * policy is correct
1409 */
1410static int validate_classes(struct policydb *p)
1411{
1412 int i, j;
1413 struct class_datum *cladatum;
1414 struct perm_datum *perdatum;
1415 u32 nprim, tmp, common_pts_len, perm_val, pol_val;
1416 u16 class_val;
1417 const struct selinux_class_perm *kdefs = &selinux_class_perm;
1418 const char *def_class, *def_perm, *pol_class;
1419 struct symtab *perms;
1420 bool print_unknown_handle = 0;
1421
1422 if (p->allow_unknown) {
1423 u32 num_classes = kdefs->cts_len;
1424 p->undefined_perms = kcalloc(num_classes, sizeof(u32), GFP_KERNEL);
1425 if (!p->undefined_perms)
1426 return -ENOMEM;
1427 }
1428
1429 for (i = 1; i < kdefs->cts_len; i++) {
1430 def_class = kdefs->class_to_string[i];
1431 if (!def_class)
1432 continue;
1433 if (i > p->p_classes.nprim) {
1434 printk(KERN_INFO
1435 "SELinux: class %s not defined in policy\n",
1436 def_class);
1437 if (p->reject_unknown)
1438 return -EINVAL;
1439 if (p->allow_unknown)
1440 p->undefined_perms[i-1] = ~0U;
1441 print_unknown_handle = 1;
1442 continue;
1443 }
1444 pol_class = p->p_class_val_to_name[i-1];
1445 if (strcmp(pol_class, def_class)) {
1446 printk(KERN_ERR
1447 "SELinux: class %d is incorrect, found %s but should be %s\n",
1448 i, pol_class, def_class);
1449 return -EINVAL;
1450 }
1451 }
1452 for (i = 0; i < kdefs->av_pts_len; i++) {
1453 class_val = kdefs->av_perm_to_string[i].tclass;
1454 perm_val = kdefs->av_perm_to_string[i].value;
1455 def_perm = kdefs->av_perm_to_string[i].name;
1456 if (class_val > p->p_classes.nprim)
1457 continue;
1458 pol_class = p->p_class_val_to_name[class_val-1];
1459 cladatum = hashtab_search(p->p_classes.table, pol_class);
1460 BUG_ON(!cladatum);
1461 perms = &cladatum->permissions;
1462 nprim = 1 << (perms->nprim - 1);
1463 if (perm_val > nprim) {
1464 printk(KERN_INFO
1465 "SELinux: permission %s in class %s not defined in policy\n",
1466 def_perm, pol_class);
1467 if (p->reject_unknown)
1468 return -EINVAL;
1469 if (p->allow_unknown)
1470 p->undefined_perms[class_val-1] |= perm_val;
1471 print_unknown_handle = 1;
1472 continue;
1473 }
1474 perdatum = hashtab_search(perms->table, def_perm);
1475 if (perdatum == NULL) {
1476 printk(KERN_ERR
1477 "SELinux: permission %s in class %s not found in policy, bad policy\n",
1478 def_perm, pol_class);
1479 return -EINVAL;
1480 }
1481 pol_val = 1 << (perdatum->value - 1);
1482 if (pol_val != perm_val) {
1483 printk(KERN_ERR
1484 "SELinux: permission %s in class %s has incorrect value\n",
1485 def_perm, pol_class);
1486 return -EINVAL;
1487 }
1488 }
1489 for (i = 0; i < kdefs->av_inherit_len; i++) {
1490 class_val = kdefs->av_inherit[i].tclass;
1491 if (class_val > p->p_classes.nprim)
1492 continue;
1493 pol_class = p->p_class_val_to_name[class_val-1];
1494 cladatum = hashtab_search(p->p_classes.table, pol_class);
1495 BUG_ON(!cladatum);
1496 if (!cladatum->comdatum) {
1497 printk(KERN_ERR
1498 "SELinux: class %s should have an inherits clause but does not\n",
1499 pol_class);
1500 return -EINVAL;
1501 }
1502 tmp = kdefs->av_inherit[i].common_base;
1503 common_pts_len = 0;
1504 while (!(tmp & 0x01)) {
1505 common_pts_len++;
1506 tmp >>= 1;
1507 }
1508 perms = &cladatum->comdatum->permissions;
1509 for (j = 0; j < common_pts_len; j++) {
1510 def_perm = kdefs->av_inherit[i].common_pts[j];
1511 if (j >= perms->nprim) {
1512 printk(KERN_INFO
1513 "SELinux: permission %s in class %s not defined in policy\n",
1514 def_perm, pol_class);
1515 if (p->reject_unknown)
1516 return -EINVAL;
1517 if (p->allow_unknown)
1518 p->undefined_perms[class_val-1] |= (1 << j);
1519 print_unknown_handle = 1;
1520 continue;
1521 }
1522 perdatum = hashtab_search(perms->table, def_perm);
1523 if (perdatum == NULL) {
1524 printk(KERN_ERR
1525 "SELinux: permission %s in class %s not found in policy, bad policy\n",
1526 def_perm, pol_class);
1527 return -EINVAL;
1528 }
1529 if (perdatum->value != j + 1) {
1530 printk(KERN_ERR
1531 "SELinux: permission %s in class %s has incorrect value\n",
1532 def_perm, pol_class);
1533 return -EINVAL;
1534 }
1535 }
1536 }
1537 if (print_unknown_handle)
1538 printk(KERN_INFO "SELinux: the above unknown classes and permissions will be %s\n",
1539 (security_get_allow_unknown() ? "allowed" : "denied"));
1540 return 0;
1541} 1571}
1542 1572
1543/* Clone the SID into the new SID table. */ 1573/* Clone the SID into the new SID table. */
@@ -1710,8 +1740,10 @@ int security_load_policy(void *data, size_t len)
1710{ 1740{
1711 struct policydb oldpolicydb, newpolicydb; 1741 struct policydb oldpolicydb, newpolicydb;
1712 struct sidtab oldsidtab, newsidtab; 1742 struct sidtab oldsidtab, newsidtab;
1743 struct selinux_mapping *oldmap, *map = NULL;
1713 struct convert_context_args args; 1744 struct convert_context_args args;
1714 u32 seqno; 1745 u32 seqno;
1746 u16 map_size;
1715 int rc = 0; 1747 int rc = 0;
1716 struct policy_file file = { data, len }, *fp = &file; 1748 struct policy_file file = { data, len }, *fp = &file;
1717 1749
@@ -1721,16 +1753,14 @@ int security_load_policy(void *data, size_t len)
1721 avtab_cache_destroy(); 1753 avtab_cache_destroy();
1722 return -EINVAL; 1754 return -EINVAL;
1723 } 1755 }
1724 if (policydb_load_isids(&policydb, &sidtab)) { 1756 if (selinux_set_mapping(&policydb, secclass_map,
1757 &current_mapping,
1758 &current_mapping_size)) {
1725 policydb_destroy(&policydb); 1759 policydb_destroy(&policydb);
1726 avtab_cache_destroy(); 1760 avtab_cache_destroy();
1727 return -EINVAL; 1761 return -EINVAL;
1728 } 1762 }
1729 /* Verify that the kernel defined classes are correct. */ 1763 if (policydb_load_isids(&policydb, &sidtab)) {
1730 if (validate_classes(&policydb)) {
1731 printk(KERN_ERR
1732 "SELinux: the definition of a class is incorrect\n");
1733 sidtab_destroy(&sidtab);
1734 policydb_destroy(&policydb); 1764 policydb_destroy(&policydb);
1735 avtab_cache_destroy(); 1765 avtab_cache_destroy();
1736 return -EINVAL; 1766 return -EINVAL;
@@ -1759,13 +1789,9 @@ int security_load_policy(void *data, size_t len)
1759 return -ENOMEM; 1789 return -ENOMEM;
1760 } 1790 }
1761 1791
1762 /* Verify that the kernel defined classes are correct. */ 1792 if (selinux_set_mapping(&newpolicydb, secclass_map,
1763 if (validate_classes(&newpolicydb)) { 1793 &map, &map_size))
1764 printk(KERN_ERR
1765 "SELinux: the definition of a class is incorrect\n");
1766 rc = -EINVAL;
1767 goto err; 1794 goto err;
1768 }
1769 1795
1770 rc = security_preserve_bools(&newpolicydb); 1796 rc = security_preserve_bools(&newpolicydb);
1771 if (rc) { 1797 if (rc) {
@@ -1799,6 +1825,9 @@ int security_load_policy(void *data, size_t len)
1799 memcpy(&policydb, &newpolicydb, sizeof policydb); 1825 memcpy(&policydb, &newpolicydb, sizeof policydb);
1800 sidtab_set(&sidtab, &newsidtab); 1826 sidtab_set(&sidtab, &newsidtab);
1801 security_load_policycaps(); 1827 security_load_policycaps();
1828 oldmap = current_mapping;
1829 current_mapping = map;
1830 current_mapping_size = map_size;
1802 seqno = ++latest_granting; 1831 seqno = ++latest_granting;
1803 policydb_loaded_version = policydb.policyvers; 1832 policydb_loaded_version = policydb.policyvers;
1804 write_unlock_irq(&policy_rwlock); 1833 write_unlock_irq(&policy_rwlock);
@@ -1806,6 +1835,7 @@ int security_load_policy(void *data, size_t len)
1806 /* Free the old policydb and SID table. */ 1835 /* Free the old policydb and SID table. */
1807 policydb_destroy(&oldpolicydb); 1836 policydb_destroy(&oldpolicydb);
1808 sidtab_destroy(&oldsidtab); 1837 sidtab_destroy(&oldsidtab);
1838 kfree(oldmap);
1809 1839
1810 avc_ss_reset(seqno); 1840 avc_ss_reset(seqno);
1811 selnl_notify_policyload(seqno); 1841 selnl_notify_policyload(seqno);
@@ -1815,6 +1845,7 @@ int security_load_policy(void *data, size_t len)
1815 return 0; 1845 return 0;
1816 1846
1817err: 1847err:
1848 kfree(map);
1818 sidtab_destroy(&newsidtab); 1849 sidtab_destroy(&newsidtab);
1819 policydb_destroy(&newpolicydb); 1850 policydb_destroy(&newpolicydb);
1820 return rc; 1851 return rc;
@@ -2091,7 +2122,7 @@ out_unlock:
2091 } 2122 }
2092 for (i = 0, j = 0; i < mynel; i++) { 2123 for (i = 0, j = 0; i < mynel; i++) {
2093 rc = avc_has_perm_noaudit(fromsid, mysids[i], 2124 rc = avc_has_perm_noaudit(fromsid, mysids[i],
2094 SECCLASS_PROCESS, 2125 SECCLASS_PROCESS, /* kernel value */
2095 PROCESS__TRANSITION, AVC_STRICT, 2126 PROCESS__TRANSITION, AVC_STRICT,
2096 NULL); 2127 NULL);
2097 if (!rc) 2128 if (!rc)
@@ -2119,10 +2150,11 @@ out:
2119 */ 2150 */
2120int security_genfs_sid(const char *fstype, 2151int security_genfs_sid(const char *fstype,
2121 char *path, 2152 char *path,
2122 u16 sclass, 2153 u16 orig_sclass,
2123 u32 *sid) 2154 u32 *sid)
2124{ 2155{
2125 int len; 2156 int len;
2157 u16 sclass;
2126 struct genfs *genfs; 2158 struct genfs *genfs;
2127 struct ocontext *c; 2159 struct ocontext *c;
2128 int rc = 0, cmp = 0; 2160 int rc = 0, cmp = 0;
@@ -2132,6 +2164,8 @@ int security_genfs_sid(const char *fstype,
2132 2164
2133 read_lock(&policy_rwlock); 2165 read_lock(&policy_rwlock);
2134 2166
2167 sclass = unmap_class(orig_sclass);
2168
2135 for (genfs = policydb.genfs; genfs; genfs = genfs->next) { 2169 for (genfs = policydb.genfs; genfs; genfs = genfs->next) {
2136 cmp = strcmp(fstype, genfs->fstype); 2170 cmp = strcmp(fstype, genfs->fstype);
2137 if (cmp <= 0) 2171 if (cmp <= 0)