aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss/services.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/ss/services.c')
-rw-r--r--security/selinux/ss/services.c144
1 files changed, 125 insertions, 19 deletions
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 40660ffd49b6..b5f017f07a75 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -1587,19 +1587,18 @@ int security_get_user_sids(u32 fromsid,
1587 u32 *nel) 1587 u32 *nel)
1588{ 1588{
1589 struct context *fromcon, usercon; 1589 struct context *fromcon, usercon;
1590 u32 *mysids, *mysids2, sid; 1590 u32 *mysids = NULL, *mysids2, sid;
1591 u32 mynel = 0, maxnel = SIDS_NEL; 1591 u32 mynel = 0, maxnel = SIDS_NEL;
1592 struct user_datum *user; 1592 struct user_datum *user;
1593 struct role_datum *role; 1593 struct role_datum *role;
1594 struct av_decision avd;
1595 struct ebitmap_node *rnode, *tnode; 1594 struct ebitmap_node *rnode, *tnode;
1596 int rc = 0, i, j; 1595 int rc = 0, i, j;
1597 1596
1598 if (!ss_initialized) { 1597 *sids = NULL;
1599 *sids = NULL; 1598 *nel = 0;
1600 *nel = 0; 1599
1600 if (!ss_initialized)
1601 goto out; 1601 goto out;
1602 }
1603 1602
1604 POLICY_RDLOCK; 1603 POLICY_RDLOCK;
1605 1604
@@ -1635,17 +1634,9 @@ int security_get_user_sids(u32 fromsid,
1635 if (mls_setup_user_range(fromcon, user, &usercon)) 1634 if (mls_setup_user_range(fromcon, user, &usercon))
1636 continue; 1635 continue;
1637 1636
1638 rc = context_struct_compute_av(fromcon, &usercon,
1639 SECCLASS_PROCESS,
1640 PROCESS__TRANSITION,
1641 &avd);
1642 if (rc || !(avd.allowed & PROCESS__TRANSITION))
1643 continue;
1644 rc = sidtab_context_to_sid(&sidtab, &usercon, &sid); 1637 rc = sidtab_context_to_sid(&sidtab, &usercon, &sid);
1645 if (rc) { 1638 if (rc)
1646 kfree(mysids);
1647 goto out_unlock; 1639 goto out_unlock;
1648 }
1649 if (mynel < maxnel) { 1640 if (mynel < maxnel) {
1650 mysids[mynel++] = sid; 1641 mysids[mynel++] = sid;
1651 } else { 1642 } else {
@@ -1653,7 +1644,6 @@ int security_get_user_sids(u32 fromsid,
1653 mysids2 = kcalloc(maxnel, sizeof(*mysids2), GFP_ATOMIC); 1644 mysids2 = kcalloc(maxnel, sizeof(*mysids2), GFP_ATOMIC);
1654 if (!mysids2) { 1645 if (!mysids2) {
1655 rc = -ENOMEM; 1646 rc = -ENOMEM;
1656 kfree(mysids);
1657 goto out_unlock; 1647 goto out_unlock;
1658 } 1648 }
1659 memcpy(mysids2, mysids, mynel * sizeof(*mysids2)); 1649 memcpy(mysids2, mysids, mynel * sizeof(*mysids2));
@@ -1664,11 +1654,32 @@ int security_get_user_sids(u32 fromsid,
1664 } 1654 }
1665 } 1655 }
1666 1656
1667 *sids = mysids;
1668 *nel = mynel;
1669
1670out_unlock: 1657out_unlock:
1671 POLICY_RDUNLOCK; 1658 POLICY_RDUNLOCK;
1659 if (rc || !mynel) {
1660 kfree(mysids);
1661 goto out;
1662 }
1663
1664 mysids2 = kcalloc(mynel, sizeof(*mysids2), GFP_KERNEL);
1665 if (!mysids2) {
1666 rc = -ENOMEM;
1667 kfree(mysids);
1668 goto out;
1669 }
1670 for (i = 0, j = 0; i < mynel; i++) {
1671 rc = avc_has_perm_noaudit(fromsid, mysids[i],
1672 SECCLASS_PROCESS,
1673 PROCESS__TRANSITION, AVC_STRICT,
1674 NULL);
1675 if (!rc)
1676 mysids2[j++] = mysids[i];
1677 cond_resched();
1678 }
1679 rc = 0;
1680 kfree(mysids);
1681 *sids = mysids2;
1682 *nel = j;
1672out: 1683out:
1673 return rc; 1684 return rc;
1674} 1685}
@@ -1996,6 +2007,101 @@ out:
1996 return rc; 2007 return rc;
1997} 2008}
1998 2009
2010static int get_classes_callback(void *k, void *d, void *args)
2011{
2012 struct class_datum *datum = d;
2013 char *name = k, **classes = args;
2014 int value = datum->value - 1;
2015
2016 classes[value] = kstrdup(name, GFP_ATOMIC);
2017 if (!classes[value])
2018 return -ENOMEM;
2019
2020 return 0;
2021}
2022
2023int security_get_classes(char ***classes, int *nclasses)
2024{
2025 int rc = -ENOMEM;
2026
2027 POLICY_RDLOCK;
2028
2029 *nclasses = policydb.p_classes.nprim;
2030 *classes = kcalloc(*nclasses, sizeof(*classes), GFP_ATOMIC);
2031 if (!*classes)
2032 goto out;
2033
2034 rc = hashtab_map(policydb.p_classes.table, get_classes_callback,
2035 *classes);
2036 if (rc < 0) {
2037 int i;
2038 for (i = 0; i < *nclasses; i++)
2039 kfree((*classes)[i]);
2040 kfree(*classes);
2041 }
2042
2043out:
2044 POLICY_RDUNLOCK;
2045 return rc;
2046}
2047
2048static int get_permissions_callback(void *k, void *d, void *args)
2049{
2050 struct perm_datum *datum = d;
2051 char *name = k, **perms = args;
2052 int value = datum->value - 1;
2053
2054 perms[value] = kstrdup(name, GFP_ATOMIC);
2055 if (!perms[value])
2056 return -ENOMEM;
2057
2058 return 0;
2059}
2060
2061int security_get_permissions(char *class, char ***perms, int *nperms)
2062{
2063 int rc = -ENOMEM, i;
2064 struct class_datum *match;
2065
2066 POLICY_RDLOCK;
2067
2068 match = hashtab_search(policydb.p_classes.table, class);
2069 if (!match) {
2070 printk(KERN_ERR "%s: unrecognized class %s\n",
2071 __FUNCTION__, class);
2072 rc = -EINVAL;
2073 goto out;
2074 }
2075
2076 *nperms = match->permissions.nprim;
2077 *perms = kcalloc(*nperms, sizeof(*perms), GFP_ATOMIC);
2078 if (!*perms)
2079 goto out;
2080
2081 if (match->comdatum) {
2082 rc = hashtab_map(match->comdatum->permissions.table,
2083 get_permissions_callback, *perms);
2084 if (rc < 0)
2085 goto err;
2086 }
2087
2088 rc = hashtab_map(match->permissions.table, get_permissions_callback,
2089 *perms);
2090 if (rc < 0)
2091 goto err;
2092
2093out:
2094 POLICY_RDUNLOCK;
2095 return rc;
2096
2097err:
2098 POLICY_RDUNLOCK;
2099 for (i = 0; i < *nperms; i++)
2100 kfree((*perms)[i]);
2101 kfree(*perms);
2102 return rc;
2103}
2104
1999struct selinux_audit_rule { 2105struct selinux_audit_rule {
2000 u32 au_seqno; 2106 u32 au_seqno;
2001 struct context au_ctxt; 2107 struct context au_ctxt;