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.c49
1 files changed, 30 insertions, 19 deletions
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index e4249adaa880..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}