aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss/services.c
diff options
context:
space:
mode:
authorJames Morris <jmorris@namei.org>2010-02-28 17:36:31 -0500
committerJames Morris <jmorris@namei.org>2010-02-28 17:36:31 -0500
commitb4ccebdd37ff70d349321a198f416ba737a5e833 (patch)
tree275d717070346722c3aacd8355fb4f743216e03b /security/selinux/ss/services.c
parent30ff056c42c665b9ea535d8515890857ae382540 (diff)
parentef57471a73b67a7b65fd8708fd55c77cb7c619af (diff)
Merge branch 'next' into for-linus
Diffstat (limited to 'security/selinux/ss/services.c')
-rw-r--r--security/selinux/ss/services.c273
1 files changed, 154 insertions, 119 deletions
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index b3efae204ac..cf27b3ee1a9 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -26,6 +26,10 @@
26 * 26 *
27 * Added support for bounds domain and audit messaged on masked permissions 27 * Added support for bounds domain and audit messaged on masked permissions
28 * 28 *
29 * Updated: Guido Trentalancia <guido@trentalancia.com>
30 *
31 * Added support for runtime switching of the policy type
32 *
29 * Copyright (C) 2008, 2009 NEC Corporation 33 * Copyright (C) 2008, 2009 NEC Corporation
30 * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P. 34 * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P.
31 * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. 35 * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
@@ -87,11 +91,10 @@ static u32 latest_granting;
87static int context_struct_to_string(struct context *context, char **scontext, 91static int context_struct_to_string(struct context *context, char **scontext,
88 u32 *scontext_len); 92 u32 *scontext_len);
89 93
90static int context_struct_compute_av(struct context *scontext, 94static void context_struct_compute_av(struct context *scontext,
91 struct context *tcontext, 95 struct context *tcontext,
92 u16 tclass, 96 u16 tclass,
93 u32 requested, 97 struct av_decision *avd);
94 struct av_decision *avd);
95 98
96struct selinux_mapping { 99struct selinux_mapping {
97 u16 value; /* policy value */ 100 u16 value; /* policy value */
@@ -196,23 +199,6 @@ static u16 unmap_class(u16 tclass)
196 return tclass; 199 return tclass;
197} 200}
198 201
199static u32 unmap_perm(u16 tclass, u32 tperm)
200{
201 if (tclass < current_mapping_size) {
202 unsigned i;
203 u32 kperm = 0;
204
205 for (i = 0; i < current_mapping[tclass].num_perms; i++)
206 if (tperm & (1<<i)) {
207 kperm |= current_mapping[tclass].perms[i];
208 tperm &= ~(1<<i);
209 }
210 return kperm;
211 }
212
213 return tperm;
214}
215
216static void map_decision(u16 tclass, struct av_decision *avd, 202static void map_decision(u16 tclass, struct av_decision *avd,
217 int allow_unknown) 203 int allow_unknown)
218{ 204{
@@ -250,6 +236,10 @@ static void map_decision(u16 tclass, struct av_decision *avd,
250 } 236 }
251} 237}
252 238
239int security_mls_enabled(void)
240{
241 return policydb.mls_enabled;
242}
253 243
254/* 244/*
255 * Return the boolean value of a constraint expression 245 * Return the boolean value of a constraint expression
@@ -465,7 +455,8 @@ static void security_dump_masked_av(struct context *scontext,
465 char *scontext_name = NULL; 455 char *scontext_name = NULL;
466 char *tcontext_name = NULL; 456 char *tcontext_name = NULL;
467 char *permission_names[32]; 457 char *permission_names[32];
468 int index, length; 458 int index;
459 u32 length;
469 bool need_comma = false; 460 bool need_comma = false;
470 461
471 if (!permissions) 462 if (!permissions)
@@ -532,7 +523,6 @@ out:
532static void type_attribute_bounds_av(struct context *scontext, 523static void type_attribute_bounds_av(struct context *scontext,
533 struct context *tcontext, 524 struct context *tcontext,
534 u16 tclass, 525 u16 tclass,
535 u32 requested,
536 struct av_decision *avd) 526 struct av_decision *avd)
537{ 527{
538 struct context lo_scontext; 528 struct context lo_scontext;
@@ -553,7 +543,6 @@ static void type_attribute_bounds_av(struct context *scontext,
553 context_struct_compute_av(&lo_scontext, 543 context_struct_compute_av(&lo_scontext,
554 tcontext, 544 tcontext,
555 tclass, 545 tclass,
556 requested,
557 &lo_avd); 546 &lo_avd);
558 if ((lo_avd.allowed & avd->allowed) == avd->allowed) 547 if ((lo_avd.allowed & avd->allowed) == avd->allowed)
559 return; /* no masked permission */ 548 return; /* no masked permission */
@@ -569,7 +558,6 @@ static void type_attribute_bounds_av(struct context *scontext,
569 context_struct_compute_av(scontext, 558 context_struct_compute_av(scontext,
570 &lo_tcontext, 559 &lo_tcontext,
571 tclass, 560 tclass,
572 requested,
573 &lo_avd); 561 &lo_avd);
574 if ((lo_avd.allowed & avd->allowed) == avd->allowed) 562 if ((lo_avd.allowed & avd->allowed) == avd->allowed)
575 return; /* no masked permission */ 563 return; /* no masked permission */
@@ -586,7 +574,6 @@ static void type_attribute_bounds_av(struct context *scontext,
586 context_struct_compute_av(&lo_scontext, 574 context_struct_compute_av(&lo_scontext,
587 &lo_tcontext, 575 &lo_tcontext,
588 tclass, 576 tclass,
589 requested,
590 &lo_avd); 577 &lo_avd);
591 if ((lo_avd.allowed & avd->allowed) == avd->allowed) 578 if ((lo_avd.allowed & avd->allowed) == avd->allowed)
592 return; /* no masked permission */ 579 return; /* no masked permission */
@@ -607,11 +594,10 @@ static void type_attribute_bounds_av(struct context *scontext,
607 * Compute access vectors based on a context structure pair for 594 * Compute access vectors based on a context structure pair for
608 * the permissions in a particular class. 595 * the permissions in a particular class.
609 */ 596 */
610static int context_struct_compute_av(struct context *scontext, 597static void context_struct_compute_av(struct context *scontext,
611 struct context *tcontext, 598 struct context *tcontext,
612 u16 tclass, 599 u16 tclass,
613 u32 requested, 600 struct av_decision *avd)
614 struct av_decision *avd)
615{ 601{
616 struct constraint_node *constraint; 602 struct constraint_node *constraint;
617 struct role_allow *ra; 603 struct role_allow *ra;
@@ -622,19 +608,14 @@ static int context_struct_compute_av(struct context *scontext,
622 struct ebitmap_node *snode, *tnode; 608 struct ebitmap_node *snode, *tnode;
623 unsigned int i, j; 609 unsigned int i, j;
624 610
625 /*
626 * Initialize the access vectors to the default values.
627 */
628 avd->allowed = 0; 611 avd->allowed = 0;
629 avd->auditallow = 0; 612 avd->auditallow = 0;
630 avd->auditdeny = 0xffffffff; 613 avd->auditdeny = 0xffffffff;
631 avd->seqno = latest_granting;
632 avd->flags = 0;
633 614
634 if (unlikely(!tclass || tclass > policydb.p_classes.nprim)) { 615 if (unlikely(!tclass || tclass > policydb.p_classes.nprim)) {
635 if (printk_ratelimit()) 616 if (printk_ratelimit())
636 printk(KERN_WARNING "SELinux: Invalid class %hu\n", tclass); 617 printk(KERN_WARNING "SELinux: Invalid class %hu\n", tclass);
637 return -EINVAL; 618 return;
638 } 619 }
639 620
640 tclass_datum = policydb.class_val_to_struct[tclass - 1]; 621 tclass_datum = policydb.class_val_to_struct[tclass - 1];
@@ -705,9 +686,7 @@ static int context_struct_compute_av(struct context *scontext,
705 * permission and notice it to userspace via audit. 686 * permission and notice it to userspace via audit.
706 */ 687 */
707 type_attribute_bounds_av(scontext, tcontext, 688 type_attribute_bounds_av(scontext, tcontext,
708 tclass, requested, avd); 689 tclass, avd);
709
710 return 0;
711} 690}
712 691
713static int security_validtrans_handle_fail(struct context *ocontext, 692static int security_validtrans_handle_fail(struct context *ocontext,
@@ -864,7 +843,7 @@ int security_bounded_transition(u32 old_sid, u32 new_sid)
864 if (rc) { 843 if (rc) {
865 char *old_name = NULL; 844 char *old_name = NULL;
866 char *new_name = NULL; 845 char *new_name = NULL;
867 int length; 846 u32 length;
868 847
869 if (!context_struct_to_string(old_context, 848 if (!context_struct_to_string(old_context,
870 &old_name, &length) && 849 &old_name, &length) &&
@@ -886,110 +865,116 @@ out:
886 return rc; 865 return rc;
887} 866}
888 867
889 868static void avd_init(struct av_decision *avd)
890static int security_compute_av_core(u32 ssid,
891 u32 tsid,
892 u16 tclass,
893 u32 requested,
894 struct av_decision *avd)
895{ 869{
896 struct context *scontext = NULL, *tcontext = NULL; 870 avd->allowed = 0;
897 int rc = 0; 871 avd->auditallow = 0;
898 872 avd->auditdeny = 0xffffffff;
899 scontext = sidtab_search(&sidtab, ssid); 873 avd->seqno = latest_granting;
900 if (!scontext) { 874 avd->flags = 0;
901 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
902 __func__, ssid);
903 return -EINVAL;
904 }
905 tcontext = sidtab_search(&sidtab, tsid);
906 if (!tcontext) {
907 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
908 __func__, tsid);
909 return -EINVAL;
910 }
911
912 rc = context_struct_compute_av(scontext, tcontext, tclass,
913 requested, avd);
914
915 /* permissive domain? */
916 if (ebitmap_get_bit(&policydb.permissive_map, scontext->type))
917 avd->flags |= AVD_FLAGS_PERMISSIVE;
918
919 return rc;
920} 875}
921 876
877
922/** 878/**
923 * security_compute_av - Compute access vector decisions. 879 * security_compute_av - Compute access vector decisions.
924 * @ssid: source security identifier 880 * @ssid: source security identifier
925 * @tsid: target security identifier 881 * @tsid: target security identifier
926 * @tclass: target security class 882 * @tclass: target security class
927 * @requested: requested permissions
928 * @avd: access vector decisions 883 * @avd: access vector decisions
929 * 884 *
930 * Compute a set of access vector decisions based on the 885 * Compute a set of access vector decisions based on the
931 * SID pair (@ssid, @tsid) for the permissions in @tclass. 886 * SID pair (@ssid, @tsid) for the permissions in @tclass.
932 * Return -%EINVAL if any of the parameters are invalid or %0
933 * if the access vector decisions were computed successfully.
934 */ 887 */
935int security_compute_av(u32 ssid, 888void security_compute_av(u32 ssid,
936 u32 tsid, 889 u32 tsid,
937 u16 orig_tclass, 890 u16 orig_tclass,
938 u32 orig_requested, 891 struct av_decision *avd)
939 struct av_decision *avd)
940{ 892{
941 u16 tclass; 893 u16 tclass;
942 u32 requested; 894 struct context *scontext = NULL, *tcontext = NULL;
943 int rc;
944 895
945 read_lock(&policy_rwlock); 896 read_lock(&policy_rwlock);
946 897 avd_init(avd);
947 if (!ss_initialized) 898 if (!ss_initialized)
948 goto allow; 899 goto allow;
949 900
950 requested = unmap_perm(orig_tclass, orig_requested); 901 scontext = sidtab_search(&sidtab, ssid);
902 if (!scontext) {
903 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
904 __func__, ssid);
905 goto out;
906 }
907
908 /* permissive domain? */
909 if (ebitmap_get_bit(&policydb.permissive_map, scontext->type))
910 avd->flags |= AVD_FLAGS_PERMISSIVE;
911
912 tcontext = sidtab_search(&sidtab, tsid);
913 if (!tcontext) {
914 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
915 __func__, tsid);
916 goto out;
917 }
918
951 tclass = unmap_class(orig_tclass); 919 tclass = unmap_class(orig_tclass);
952 if (unlikely(orig_tclass && !tclass)) { 920 if (unlikely(orig_tclass && !tclass)) {
953 if (policydb.allow_unknown) 921 if (policydb.allow_unknown)
954 goto allow; 922 goto allow;
955 rc = -EINVAL;
956 goto out; 923 goto out;
957 } 924 }
958 rc = security_compute_av_core(ssid, tsid, tclass, requested, avd); 925 context_struct_compute_av(scontext, tcontext, tclass, avd);
959 map_decision(orig_tclass, avd, policydb.allow_unknown); 926 map_decision(orig_tclass, avd, policydb.allow_unknown);
960out: 927out:
961 read_unlock(&policy_rwlock); 928 read_unlock(&policy_rwlock);
962 return rc; 929 return;
963allow: 930allow:
964 avd->allowed = 0xffffffff; 931 avd->allowed = 0xffffffff;
965 avd->auditallow = 0;
966 avd->auditdeny = 0xffffffff;
967 avd->seqno = latest_granting;
968 avd->flags = 0;
969 rc = 0;
970 goto out; 932 goto out;
971} 933}
972 934
973int security_compute_av_user(u32 ssid, 935void security_compute_av_user(u32 ssid,
974 u32 tsid, 936 u32 tsid,
975 u16 tclass, 937 u16 tclass,
976 u32 requested, 938 struct av_decision *avd)
977 struct av_decision *avd)
978{ 939{
979 int rc; 940 struct context *scontext = NULL, *tcontext = NULL;
980 941
981 if (!ss_initialized) { 942 read_lock(&policy_rwlock);
982 avd->allowed = 0xffffffff; 943 avd_init(avd);
983 avd->auditallow = 0; 944 if (!ss_initialized)
984 avd->auditdeny = 0xffffffff; 945 goto allow;
985 avd->seqno = latest_granting; 946
986 return 0; 947 scontext = sidtab_search(&sidtab, ssid);
948 if (!scontext) {
949 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
950 __func__, ssid);
951 goto out;
987 } 952 }
988 953
989 read_lock(&policy_rwlock); 954 /* permissive domain? */
990 rc = security_compute_av_core(ssid, tsid, tclass, requested, avd); 955 if (ebitmap_get_bit(&policydb.permissive_map, scontext->type))
956 avd->flags |= AVD_FLAGS_PERMISSIVE;
957
958 tcontext = sidtab_search(&sidtab, tsid);
959 if (!tcontext) {
960 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
961 __func__, tsid);
962 goto out;
963 }
964
965 if (unlikely(!tclass)) {
966 if (policydb.allow_unknown)
967 goto allow;
968 goto out;
969 }
970
971 context_struct_compute_av(scontext, tcontext, tclass, avd);
972 out:
991 read_unlock(&policy_rwlock); 973 read_unlock(&policy_rwlock);
992 return rc; 974 return;
975allow:
976 avd->allowed = 0xffffffff;
977 goto out;
993} 978}
994 979
995/* 980/*
@@ -1565,7 +1550,10 @@ static int clone_sid(u32 sid,
1565{ 1550{
1566 struct sidtab *s = arg; 1551 struct sidtab *s = arg;
1567 1552
1568 return sidtab_insert(s, sid, context); 1553 if (sid > SECINITSID_NUM)
1554 return sidtab_insert(s, sid, context);
1555 else
1556 return 0;
1569} 1557}
1570 1558
1571static inline int convert_context_handle_invalid_context(struct context *context) 1559static inline int convert_context_handle_invalid_context(struct context *context)
@@ -1606,12 +1594,17 @@ static int convert_context(u32 key,
1606{ 1594{
1607 struct convert_context_args *args; 1595 struct convert_context_args *args;
1608 struct context oldc; 1596 struct context oldc;
1597 struct ocontext *oc;
1598 struct mls_range *range;
1609 struct role_datum *role; 1599 struct role_datum *role;
1610 struct type_datum *typdatum; 1600 struct type_datum *typdatum;
1611 struct user_datum *usrdatum; 1601 struct user_datum *usrdatum;
1612 char *s; 1602 char *s;
1613 u32 len; 1603 u32 len;
1614 int rc; 1604 int rc = 0;
1605
1606 if (key <= SECINITSID_NUM)
1607 goto out;
1615 1608
1616 args = p; 1609 args = p;
1617 1610
@@ -1673,9 +1666,39 @@ static int convert_context(u32 key,
1673 goto bad; 1666 goto bad;
1674 c->type = typdatum->value; 1667 c->type = typdatum->value;
1675 1668
1676 rc = mls_convert_context(args->oldp, args->newp, c); 1669 /* Convert the MLS fields if dealing with MLS policies */
1677 if (rc) 1670 if (args->oldp->mls_enabled && args->newp->mls_enabled) {
1678 goto bad; 1671 rc = mls_convert_context(args->oldp, args->newp, c);
1672 if (rc)
1673 goto bad;
1674 } else if (args->oldp->mls_enabled && !args->newp->mls_enabled) {
1675 /*
1676 * Switching between MLS and non-MLS policy:
1677 * free any storage used by the MLS fields in the
1678 * context for all existing entries in the sidtab.
1679 */
1680 mls_context_destroy(c);
1681 } else if (!args->oldp->mls_enabled && args->newp->mls_enabled) {
1682 /*
1683 * Switching between non-MLS and MLS policy:
1684 * ensure that the MLS fields of the context for all
1685 * existing entries in the sidtab are filled in with a
1686 * suitable default value, likely taken from one of the
1687 * initial SIDs.
1688 */
1689 oc = args->newp->ocontexts[OCON_ISID];
1690 while (oc && oc->sid[0] != SECINITSID_UNLABELED)
1691 oc = oc->next;
1692 if (!oc) {
1693 printk(KERN_ERR "SELinux: unable to look up"
1694 " the initial SIDs list\n");
1695 goto bad;
1696 }
1697 range = &oc->context[0].range;
1698 rc = mls_range_set(c, range);
1699 if (rc)
1700 goto bad;
1701 }
1679 1702
1680 /* Check the validity of the new context. */ 1703 /* Check the validity of the new context. */
1681 if (!policydb_context_isvalid(args->newp, c)) { 1704 if (!policydb_context_isvalid(args->newp, c)) {
@@ -1771,9 +1794,17 @@ int security_load_policy(void *data, size_t len)
1771 if (policydb_read(&newpolicydb, fp)) 1794 if (policydb_read(&newpolicydb, fp))
1772 return -EINVAL; 1795 return -EINVAL;
1773 1796
1774 if (sidtab_init(&newsidtab)) { 1797 /* If switching between different policy types, log MLS status */
1798 if (policydb.mls_enabled && !newpolicydb.mls_enabled)
1799 printk(KERN_INFO "SELinux: Disabling MLS support...\n");
1800 else if (!policydb.mls_enabled && newpolicydb.mls_enabled)
1801 printk(KERN_INFO "SELinux: Enabling MLS support...\n");
1802
1803 rc = policydb_load_isids(&newpolicydb, &newsidtab);
1804 if (rc) {
1805 printk(KERN_ERR "SELinux: unable to load the initial SIDs\n");
1775 policydb_destroy(&newpolicydb); 1806 policydb_destroy(&newpolicydb);
1776 return -ENOMEM; 1807 return rc;
1777 } 1808 }
1778 1809
1779 if (selinux_set_mapping(&newpolicydb, secclass_map, 1810 if (selinux_set_mapping(&newpolicydb, secclass_map,
@@ -1800,8 +1831,12 @@ int security_load_policy(void *data, size_t len)
1800 args.oldp = &policydb; 1831 args.oldp = &policydb;
1801 args.newp = &newpolicydb; 1832 args.newp = &newpolicydb;
1802 rc = sidtab_map(&newsidtab, convert_context, &args); 1833 rc = sidtab_map(&newsidtab, convert_context, &args);
1803 if (rc) 1834 if (rc) {
1835 printk(KERN_ERR "SELinux: unable to convert the internal"
1836 " representation of contexts in the new SID"
1837 " table\n");
1804 goto err; 1838 goto err;
1839 }
1805 1840
1806 /* Save the old policydb and SID table to free later. */ 1841 /* Save the old policydb and SID table to free later. */
1807 memcpy(&oldpolicydb, &policydb, sizeof policydb); 1842 memcpy(&oldpolicydb, &policydb, sizeof policydb);
@@ -2397,7 +2432,7 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid)
2397 u32 len; 2432 u32 len;
2398 int rc = 0; 2433 int rc = 0;
2399 2434
2400 if (!ss_initialized || !selinux_mls_enabled) { 2435 if (!ss_initialized || !policydb.mls_enabled) {
2401 *new_sid = sid; 2436 *new_sid = sid;
2402 goto out; 2437 goto out;
2403 } 2438 }
@@ -2498,7 +2533,7 @@ int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type,
2498 /* we don't need to check ss_initialized here since the only way both 2533 /* we don't need to check ss_initialized here since the only way both
2499 * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the 2534 * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the
2500 * security server was initialized and ss_initialized was true */ 2535 * security server was initialized and ss_initialized was true */
2501 if (!selinux_mls_enabled) { 2536 if (!policydb.mls_enabled) {
2502 *peer_sid = SECSID_NULL; 2537 *peer_sid = SECSID_NULL;
2503 return 0; 2538 return 0;
2504 } 2539 }
@@ -2555,7 +2590,7 @@ int security_get_classes(char ***classes, int *nclasses)
2555 read_lock(&policy_rwlock); 2590 read_lock(&policy_rwlock);
2556 2591
2557 *nclasses = policydb.p_classes.nprim; 2592 *nclasses = policydb.p_classes.nprim;
2558 *classes = kcalloc(*nclasses, sizeof(*classes), GFP_ATOMIC); 2593 *classes = kcalloc(*nclasses, sizeof(**classes), GFP_ATOMIC);
2559 if (!*classes) 2594 if (!*classes)
2560 goto out; 2595 goto out;
2561 2596
@@ -2602,7 +2637,7 @@ int security_get_permissions(char *class, char ***perms, int *nperms)
2602 } 2637 }
2603 2638
2604 *nperms = match->permissions.nprim; 2639 *nperms = match->permissions.nprim;
2605 *perms = kcalloc(*nperms, sizeof(*perms), GFP_ATOMIC); 2640 *perms = kcalloc(*nperms, sizeof(**perms), GFP_ATOMIC);
2606 if (!*perms) 2641 if (!*perms)
2607 goto out; 2642 goto out;
2608 2643