diff options
Diffstat (limited to 'security/selinux/ss/services.c')
-rw-r--r-- | security/selinux/ss/services.c | 76 |
1 files changed, 41 insertions, 35 deletions
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 014120474e69..92b89dc99bcd 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -266,8 +266,11 @@ static int context_struct_compute_av(struct context *scontext, | |||
266 | struct constraint_node *constraint; | 266 | struct constraint_node *constraint; |
267 | struct role_allow *ra; | 267 | struct role_allow *ra; |
268 | struct avtab_key avkey; | 268 | struct avtab_key avkey; |
269 | struct avtab_datum *avdatum; | 269 | struct avtab_node *node; |
270 | struct class_datum *tclass_datum; | 270 | struct class_datum *tclass_datum; |
271 | struct ebitmap *sattr, *tattr; | ||
272 | struct ebitmap_node *snode, *tnode; | ||
273 | unsigned int i, j; | ||
271 | 274 | ||
272 | /* | 275 | /* |
273 | * Remap extended Netlink classes for old policy versions. | 276 | * Remap extended Netlink classes for old policy versions. |
@@ -300,21 +303,34 @@ static int context_struct_compute_av(struct context *scontext, | |||
300 | * If a specific type enforcement rule was defined for | 303 | * If a specific type enforcement rule was defined for |
301 | * this permission check, then use it. | 304 | * this permission check, then use it. |
302 | */ | 305 | */ |
303 | avkey.source_type = scontext->type; | ||
304 | avkey.target_type = tcontext->type; | ||
305 | avkey.target_class = tclass; | 306 | avkey.target_class = tclass; |
306 | avdatum = avtab_search(&policydb.te_avtab, &avkey, AVTAB_AV); | 307 | avkey.specified = AVTAB_AV; |
307 | if (avdatum) { | 308 | sattr = &policydb.type_attr_map[scontext->type - 1]; |
308 | if (avdatum->specified & AVTAB_ALLOWED) | 309 | tattr = &policydb.type_attr_map[tcontext->type - 1]; |
309 | avd->allowed = avtab_allowed(avdatum); | 310 | ebitmap_for_each_bit(sattr, snode, i) { |
310 | if (avdatum->specified & AVTAB_AUDITDENY) | 311 | if (!ebitmap_node_get_bit(snode, i)) |
311 | avd->auditdeny = avtab_auditdeny(avdatum); | 312 | continue; |
312 | if (avdatum->specified & AVTAB_AUDITALLOW) | 313 | ebitmap_for_each_bit(tattr, tnode, j) { |
313 | avd->auditallow = avtab_auditallow(avdatum); | 314 | if (!ebitmap_node_get_bit(tnode, j)) |
314 | } | 315 | continue; |
316 | avkey.source_type = i + 1; | ||
317 | avkey.target_type = j + 1; | ||
318 | for (node = avtab_search_node(&policydb.te_avtab, &avkey); | ||
319 | node != NULL; | ||
320 | node = avtab_search_node_next(node, avkey.specified)) { | ||
321 | if (node->key.specified == AVTAB_ALLOWED) | ||
322 | avd->allowed |= node->datum.data; | ||
323 | else if (node->key.specified == AVTAB_AUDITALLOW) | ||
324 | avd->auditallow |= node->datum.data; | ||
325 | else if (node->key.specified == AVTAB_AUDITDENY) | ||
326 | avd->auditdeny &= node->datum.data; | ||
327 | } | ||
315 | 328 | ||
316 | /* Check conditional av table for additional permissions */ | 329 | /* Check conditional av table for additional permissions */ |
317 | cond_compute_av(&policydb.te_cond_avtab, &avkey, avd); | 330 | cond_compute_av(&policydb.te_cond_avtab, &avkey, avd); |
331 | |||
332 | } | ||
333 | } | ||
318 | 334 | ||
319 | /* | 335 | /* |
320 | * Remove any permissions prohibited by a constraint (this includes | 336 | * Remove any permissions prohibited by a constraint (this includes |
@@ -797,7 +813,6 @@ static int security_compute_sid(u32 ssid, | |||
797 | struct avtab_key avkey; | 813 | struct avtab_key avkey; |
798 | struct avtab_datum *avdatum; | 814 | struct avtab_datum *avdatum; |
799 | struct avtab_node *node; | 815 | struct avtab_node *node; |
800 | unsigned int type_change = 0; | ||
801 | int rc = 0; | 816 | int rc = 0; |
802 | 817 | ||
803 | if (!ss_initialized) { | 818 | if (!ss_initialized) { |
@@ -862,33 +877,23 @@ static int security_compute_sid(u32 ssid, | |||
862 | avkey.source_type = scontext->type; | 877 | avkey.source_type = scontext->type; |
863 | avkey.target_type = tcontext->type; | 878 | avkey.target_type = tcontext->type; |
864 | avkey.target_class = tclass; | 879 | avkey.target_class = tclass; |
865 | avdatum = avtab_search(&policydb.te_avtab, &avkey, AVTAB_TYPE); | 880 | avkey.specified = specified; |
881 | avdatum = avtab_search(&policydb.te_avtab, &avkey); | ||
866 | 882 | ||
867 | /* If no permanent rule, also check for enabled conditional rules */ | 883 | /* If no permanent rule, also check for enabled conditional rules */ |
868 | if(!avdatum) { | 884 | if(!avdatum) { |
869 | node = avtab_search_node(&policydb.te_cond_avtab, &avkey, specified); | 885 | node = avtab_search_node(&policydb.te_cond_avtab, &avkey); |
870 | for (; node != NULL; node = avtab_search_node_next(node, specified)) { | 886 | for (; node != NULL; node = avtab_search_node_next(node, specified)) { |
871 | if (node->datum.specified & AVTAB_ENABLED) { | 887 | if (node->key.specified & AVTAB_ENABLED) { |
872 | avdatum = &node->datum; | 888 | avdatum = &node->datum; |
873 | break; | 889 | break; |
874 | } | 890 | } |
875 | } | 891 | } |
876 | } | 892 | } |
877 | 893 | ||
878 | type_change = (avdatum && (avdatum->specified & specified)); | 894 | if (avdatum) { |
879 | if (type_change) { | ||
880 | /* Use the type from the type transition/member/change rule. */ | 895 | /* Use the type from the type transition/member/change rule. */ |
881 | switch (specified) { | 896 | newcontext.type = avdatum->data; |
882 | case AVTAB_TRANSITION: | ||
883 | newcontext.type = avtab_transition(avdatum); | ||
884 | break; | ||
885 | case AVTAB_MEMBER: | ||
886 | newcontext.type = avtab_member(avdatum); | ||
887 | break; | ||
888 | case AVTAB_CHANGE: | ||
889 | newcontext.type = avtab_change(avdatum); | ||
890 | break; | ||
891 | } | ||
892 | } | 897 | } |
893 | 898 | ||
894 | /* Check for class-specific changes. */ | 899 | /* Check for class-specific changes. */ |
@@ -1502,6 +1507,7 @@ int security_get_user_sids(u32 fromsid, | |||
1502 | struct user_datum *user; | 1507 | struct user_datum *user; |
1503 | struct role_datum *role; | 1508 | struct role_datum *role; |
1504 | struct av_decision avd; | 1509 | struct av_decision avd; |
1510 | struct ebitmap_node *rnode, *tnode; | ||
1505 | int rc = 0, i, j; | 1511 | int rc = 0, i, j; |
1506 | 1512 | ||
1507 | if (!ss_initialized) { | 1513 | if (!ss_initialized) { |
@@ -1532,13 +1538,13 @@ int security_get_user_sids(u32 fromsid, | |||
1532 | } | 1538 | } |
1533 | memset(mysids, 0, maxnel*sizeof(*mysids)); | 1539 | memset(mysids, 0, maxnel*sizeof(*mysids)); |
1534 | 1540 | ||
1535 | for (i = ebitmap_startbit(&user->roles); i < ebitmap_length(&user->roles); i++) { | 1541 | ebitmap_for_each_bit(&user->roles, rnode, i) { |
1536 | if (!ebitmap_get_bit(&user->roles, i)) | 1542 | if (!ebitmap_node_get_bit(rnode, i)) |
1537 | continue; | 1543 | continue; |
1538 | role = policydb.role_val_to_struct[i]; | 1544 | role = policydb.role_val_to_struct[i]; |
1539 | usercon.role = i+1; | 1545 | usercon.role = i+1; |
1540 | for (j = ebitmap_startbit(&role->types); j < ebitmap_length(&role->types); j++) { | 1546 | ebitmap_for_each_bit(&role->types, tnode, j) { |
1541 | if (!ebitmap_get_bit(&role->types, j)) | 1547 | if (!ebitmap_node_get_bit(tnode, j)) |
1542 | continue; | 1548 | continue; |
1543 | usercon.type = j+1; | 1549 | usercon.type = j+1; |
1544 | 1550 | ||