diff options
-rw-r--r-- | security/selinux/ss/services.c | 328 |
1 files changed, 157 insertions, 171 deletions
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 223c1ff6ef23..84e2a98d7cc5 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -701,11 +701,11 @@ static int security_validtrans_handle_fail(struct context *ocontext, | |||
701 | char *o = NULL, *n = NULL, *t = NULL; | 701 | char *o = NULL, *n = NULL, *t = NULL; |
702 | u32 olen, nlen, tlen; | 702 | u32 olen, nlen, tlen; |
703 | 703 | ||
704 | if (context_struct_to_string(ocontext, &o, &olen) < 0) | 704 | if (context_struct_to_string(ocontext, &o, &olen)) |
705 | goto out; | 705 | goto out; |
706 | if (context_struct_to_string(ncontext, &n, &nlen) < 0) | 706 | if (context_struct_to_string(ncontext, &n, &nlen)) |
707 | goto out; | 707 | goto out; |
708 | if (context_struct_to_string(tcontext, &t, &tlen) < 0) | 708 | if (context_struct_to_string(tcontext, &t, &tlen)) |
709 | goto out; | 709 | goto out; |
710 | audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, | 710 | audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, |
711 | "security_validate_transition: denied for" | 711 | "security_validate_transition: denied for" |
@@ -801,10 +801,11 @@ int security_bounded_transition(u32 old_sid, u32 new_sid) | |||
801 | struct context *old_context, *new_context; | 801 | struct context *old_context, *new_context; |
802 | struct type_datum *type; | 802 | struct type_datum *type; |
803 | int index; | 803 | int index; |
804 | int rc = -EINVAL; | 804 | int rc; |
805 | 805 | ||
806 | read_lock(&policy_rwlock); | 806 | read_lock(&policy_rwlock); |
807 | 807 | ||
808 | rc = -EINVAL; | ||
808 | old_context = sidtab_search(&sidtab, old_sid); | 809 | old_context = sidtab_search(&sidtab, old_sid); |
809 | if (!old_context) { | 810 | if (!old_context) { |
810 | printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n", | 811 | printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n", |
@@ -812,6 +813,7 @@ int security_bounded_transition(u32 old_sid, u32 new_sid) | |||
812 | goto out; | 813 | goto out; |
813 | } | 814 | } |
814 | 815 | ||
816 | rc = -EINVAL; | ||
815 | new_context = sidtab_search(&sidtab, new_sid); | 817 | new_context = sidtab_search(&sidtab, new_sid); |
816 | if (!new_context) { | 818 | if (!new_context) { |
817 | printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n", | 819 | printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n", |
@@ -819,11 +821,10 @@ int security_bounded_transition(u32 old_sid, u32 new_sid) | |||
819 | goto out; | 821 | goto out; |
820 | } | 822 | } |
821 | 823 | ||
824 | rc = 0; | ||
822 | /* type/domain unchanged */ | 825 | /* type/domain unchanged */ |
823 | if (old_context->type == new_context->type) { | 826 | if (old_context->type == new_context->type) |
824 | rc = 0; | ||
825 | goto out; | 827 | goto out; |
826 | } | ||
827 | 828 | ||
828 | index = new_context->type; | 829 | index = new_context->type; |
829 | while (true) { | 830 | while (true) { |
@@ -831,16 +832,15 @@ int security_bounded_transition(u32 old_sid, u32 new_sid) | |||
831 | BUG_ON(!type); | 832 | BUG_ON(!type); |
832 | 833 | ||
833 | /* not bounded anymore */ | 834 | /* not bounded anymore */ |
834 | if (!type->bounds) { | 835 | rc = -EPERM; |
835 | rc = -EPERM; | 836 | if (!type->bounds) |
836 | break; | 837 | break; |
837 | } | ||
838 | 838 | ||
839 | /* @newsid is bounded by @oldsid */ | 839 | /* @newsid is bounded by @oldsid */ |
840 | if (type->bounds == old_context->type) { | 840 | rc = 0; |
841 | rc = 0; | 841 | if (type->bounds == old_context->type) |
842 | break; | 842 | break; |
843 | } | 843 | |
844 | index = type->bounds; | 844 | index = type->bounds; |
845 | } | 845 | } |
846 | 846 | ||
@@ -1187,16 +1187,13 @@ static int string_to_context_struct(struct policydb *pol, | |||
1187 | if (rc) | 1187 | if (rc) |
1188 | goto out; | 1188 | goto out; |
1189 | 1189 | ||
1190 | if ((p - scontext) < scontext_len) { | 1190 | rc = -EINVAL; |
1191 | rc = -EINVAL; | 1191 | if ((p - scontext) < scontext_len) |
1192 | goto out; | 1192 | goto out; |
1193 | } | ||
1194 | 1193 | ||
1195 | /* Check the validity of the new context. */ | 1194 | /* Check the validity of the new context. */ |
1196 | if (!policydb_context_isvalid(pol, ctx)) { | 1195 | if (!policydb_context_isvalid(pol, ctx)) |
1197 | rc = -EINVAL; | ||
1198 | goto out; | 1196 | goto out; |
1199 | } | ||
1200 | rc = 0; | 1197 | rc = 0; |
1201 | out: | 1198 | out: |
1202 | if (rc) | 1199 | if (rc) |
@@ -1235,27 +1232,26 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len, | |||
1235 | 1232 | ||
1236 | if (force) { | 1233 | if (force) { |
1237 | /* Save another copy for storing in uninterpreted form */ | 1234 | /* Save another copy for storing in uninterpreted form */ |
1235 | rc = -ENOMEM; | ||
1238 | str = kstrdup(scontext2, gfp_flags); | 1236 | str = kstrdup(scontext2, gfp_flags); |
1239 | if (!str) { | 1237 | if (!str) |
1240 | kfree(scontext2); | 1238 | goto out; |
1241 | return -ENOMEM; | ||
1242 | } | ||
1243 | } | 1239 | } |
1244 | 1240 | ||
1245 | read_lock(&policy_rwlock); | 1241 | read_lock(&policy_rwlock); |
1246 | rc = string_to_context_struct(&policydb, &sidtab, | 1242 | rc = string_to_context_struct(&policydb, &sidtab, scontext2, |
1247 | scontext2, scontext_len, | 1243 | scontext_len, &context, def_sid); |
1248 | &context, def_sid); | ||
1249 | if (rc == -EINVAL && force) { | 1244 | if (rc == -EINVAL && force) { |
1250 | context.str = str; | 1245 | context.str = str; |
1251 | context.len = scontext_len; | 1246 | context.len = scontext_len; |
1252 | str = NULL; | 1247 | str = NULL; |
1253 | } else if (rc) | 1248 | } else if (rc) |
1254 | goto out; | 1249 | goto out_unlock; |
1255 | rc = sidtab_context_to_sid(&sidtab, &context, sid); | 1250 | rc = sidtab_context_to_sid(&sidtab, &context, sid); |
1256 | context_destroy(&context); | 1251 | context_destroy(&context); |
1257 | out: | 1252 | out_unlock: |
1258 | read_unlock(&policy_rwlock); | 1253 | read_unlock(&policy_rwlock); |
1254 | out: | ||
1259 | kfree(scontext2); | 1255 | kfree(scontext2); |
1260 | kfree(str); | 1256 | kfree(str); |
1261 | return rc; | 1257 | return rc; |
@@ -1319,11 +1315,11 @@ static int compute_sid_handle_invalid_context( | |||
1319 | char *s = NULL, *t = NULL, *n = NULL; | 1315 | char *s = NULL, *t = NULL, *n = NULL; |
1320 | u32 slen, tlen, nlen; | 1316 | u32 slen, tlen, nlen; |
1321 | 1317 | ||
1322 | if (context_struct_to_string(scontext, &s, &slen) < 0) | 1318 | if (context_struct_to_string(scontext, &s, &slen)) |
1323 | goto out; | 1319 | goto out; |
1324 | if (context_struct_to_string(tcontext, &t, &tlen) < 0) | 1320 | if (context_struct_to_string(tcontext, &t, &tlen)) |
1325 | goto out; | 1321 | goto out; |
1326 | if (context_struct_to_string(newcontext, &n, &nlen) < 0) | 1322 | if (context_struct_to_string(newcontext, &n, &nlen)) |
1327 | goto out; | 1323 | goto out; |
1328 | audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, | 1324 | audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, |
1329 | "security_compute_sid: invalid context %s" | 1325 | "security_compute_sid: invalid context %s" |
@@ -1569,22 +1565,17 @@ static int clone_sid(u32 sid, | |||
1569 | 1565 | ||
1570 | static inline int convert_context_handle_invalid_context(struct context *context) | 1566 | static inline int convert_context_handle_invalid_context(struct context *context) |
1571 | { | 1567 | { |
1572 | int rc = 0; | 1568 | char *s; |
1569 | u32 len; | ||
1573 | 1570 | ||
1574 | if (selinux_enforcing) { | 1571 | if (selinux_enforcing) |
1575 | rc = -EINVAL; | 1572 | return -EINVAL; |
1576 | } else { | 1573 | |
1577 | char *s; | 1574 | if (!context_struct_to_string(context, &s, &len)) { |
1578 | u32 len; | 1575 | printk(KERN_WARNING "SELinux: Context %s would be invalid if enforcing\n", s); |
1579 | 1576 | kfree(s); | |
1580 | if (!context_struct_to_string(context, &s, &len)) { | ||
1581 | printk(KERN_WARNING | ||
1582 | "SELinux: Context %s would be invalid if enforcing\n", | ||
1583 | s); | ||
1584 | kfree(s); | ||
1585 | } | ||
1586 | } | 1577 | } |
1587 | return rc; | 1578 | return 0; |
1588 | } | 1579 | } |
1589 | 1580 | ||
1590 | struct convert_context_args { | 1581 | struct convert_context_args { |
@@ -1621,17 +1612,17 @@ static int convert_context(u32 key, | |||
1621 | 1612 | ||
1622 | if (c->str) { | 1613 | if (c->str) { |
1623 | struct context ctx; | 1614 | struct context ctx; |
1615 | |||
1616 | rc = -ENOMEM; | ||
1624 | s = kstrdup(c->str, GFP_KERNEL); | 1617 | s = kstrdup(c->str, GFP_KERNEL); |
1625 | if (!s) { | 1618 | if (!s) |
1626 | rc = -ENOMEM; | ||
1627 | goto out; | 1619 | goto out; |
1628 | } | 1620 | |
1629 | rc = string_to_context_struct(args->newp, NULL, s, | 1621 | rc = string_to_context_struct(args->newp, NULL, s, |
1630 | c->len, &ctx, SECSID_NULL); | 1622 | c->len, &ctx, SECSID_NULL); |
1631 | kfree(s); | 1623 | kfree(s); |
1632 | if (!rc) { | 1624 | if (!rc) { |
1633 | printk(KERN_INFO | 1625 | printk(KERN_INFO "SELinux: Context %s became valid (mapped).\n", |
1634 | "SELinux: Context %s became valid (mapped).\n", | ||
1635 | c->str); | 1626 | c->str); |
1636 | /* Replace string with mapped representation. */ | 1627 | /* Replace string with mapped representation. */ |
1637 | kfree(c->str); | 1628 | kfree(c->str); |
@@ -1643,8 +1634,7 @@ static int convert_context(u32 key, | |||
1643 | goto out; | 1634 | goto out; |
1644 | } else { | 1635 | } else { |
1645 | /* Other error condition, e.g. ENOMEM. */ | 1636 | /* Other error condition, e.g. ENOMEM. */ |
1646 | printk(KERN_ERR | 1637 | printk(KERN_ERR "SELinux: Unable to map context %s, rc = %d.\n", |
1647 | "SELinux: Unable to map context %s, rc = %d.\n", | ||
1648 | c->str, -rc); | 1638 | c->str, -rc); |
1649 | goto out; | 1639 | goto out; |
1650 | } | 1640 | } |
@@ -1654,9 +1644,8 @@ static int convert_context(u32 key, | |||
1654 | if (rc) | 1644 | if (rc) |
1655 | goto out; | 1645 | goto out; |
1656 | 1646 | ||
1657 | rc = -EINVAL; | ||
1658 | |||
1659 | /* Convert the user. */ | 1647 | /* Convert the user. */ |
1648 | rc = -EINVAL; | ||
1660 | usrdatum = hashtab_search(args->newp->p_users.table, | 1649 | usrdatum = hashtab_search(args->newp->p_users.table, |
1661 | args->oldp->p_user_val_to_name[c->user - 1]); | 1650 | args->oldp->p_user_val_to_name[c->user - 1]); |
1662 | if (!usrdatum) | 1651 | if (!usrdatum) |
@@ -1664,6 +1653,7 @@ static int convert_context(u32 key, | |||
1664 | c->user = usrdatum->value; | 1653 | c->user = usrdatum->value; |
1665 | 1654 | ||
1666 | /* Convert the role. */ | 1655 | /* Convert the role. */ |
1656 | rc = -EINVAL; | ||
1667 | role = hashtab_search(args->newp->p_roles.table, | 1657 | role = hashtab_search(args->newp->p_roles.table, |
1668 | args->oldp->p_role_val_to_name[c->role - 1]); | 1658 | args->oldp->p_role_val_to_name[c->role - 1]); |
1669 | if (!role) | 1659 | if (!role) |
@@ -1671,6 +1661,7 @@ static int convert_context(u32 key, | |||
1671 | c->role = role->value; | 1661 | c->role = role->value; |
1672 | 1662 | ||
1673 | /* Convert the type. */ | 1663 | /* Convert the type. */ |
1664 | rc = -EINVAL; | ||
1674 | typdatum = hashtab_search(args->newp->p_types.table, | 1665 | typdatum = hashtab_search(args->newp->p_types.table, |
1675 | args->oldp->p_type_val_to_name[c->type - 1]); | 1666 | args->oldp->p_type_val_to_name[c->type - 1]); |
1676 | if (!typdatum) | 1667 | if (!typdatum) |
@@ -1700,6 +1691,7 @@ static int convert_context(u32 key, | |||
1700 | oc = args->newp->ocontexts[OCON_ISID]; | 1691 | oc = args->newp->ocontexts[OCON_ISID]; |
1701 | while (oc && oc->sid[0] != SECINITSID_UNLABELED) | 1692 | while (oc && oc->sid[0] != SECINITSID_UNLABELED) |
1702 | oc = oc->next; | 1693 | oc = oc->next; |
1694 | rc = -EINVAL; | ||
1703 | if (!oc) { | 1695 | if (!oc) { |
1704 | printk(KERN_ERR "SELinux: unable to look up" | 1696 | printk(KERN_ERR "SELinux: unable to look up" |
1705 | " the initial SIDs list\n"); | 1697 | " the initial SIDs list\n"); |
@@ -1719,19 +1711,20 @@ static int convert_context(u32 key, | |||
1719 | } | 1711 | } |
1720 | 1712 | ||
1721 | context_destroy(&oldc); | 1713 | context_destroy(&oldc); |
1714 | |||
1722 | rc = 0; | 1715 | rc = 0; |
1723 | out: | 1716 | out: |
1724 | return rc; | 1717 | return rc; |
1725 | bad: | 1718 | bad: |
1726 | /* Map old representation to string and save it. */ | 1719 | /* Map old representation to string and save it. */ |
1727 | if (context_struct_to_string(&oldc, &s, &len)) | 1720 | rc = context_struct_to_string(&oldc, &s, &len); |
1728 | return -ENOMEM; | 1721 | if (rc) |
1722 | return rc; | ||
1729 | context_destroy(&oldc); | 1723 | context_destroy(&oldc); |
1730 | context_destroy(c); | 1724 | context_destroy(c); |
1731 | c->str = s; | 1725 | c->str = s; |
1732 | c->len = len; | 1726 | c->len = len; |
1733 | printk(KERN_INFO | 1727 | printk(KERN_INFO "SELinux: Context %s became invalid (unmapped).\n", |
1734 | "SELinux: Context %s became invalid (unmapped).\n", | ||
1735 | c->str); | 1728 | c->str); |
1736 | rc = 0; | 1729 | rc = 0; |
1737 | goto out; | 1730 | goto out; |
@@ -2012,7 +2005,7 @@ int security_node_sid(u16 domain, | |||
2012 | u32 addrlen, | 2005 | u32 addrlen, |
2013 | u32 *out_sid) | 2006 | u32 *out_sid) |
2014 | { | 2007 | { |
2015 | int rc = 0; | 2008 | int rc; |
2016 | struct ocontext *c; | 2009 | struct ocontext *c; |
2017 | 2010 | ||
2018 | read_lock(&policy_rwlock); | 2011 | read_lock(&policy_rwlock); |
@@ -2021,10 +2014,9 @@ int security_node_sid(u16 domain, | |||
2021 | case AF_INET: { | 2014 | case AF_INET: { |
2022 | u32 addr; | 2015 | u32 addr; |
2023 | 2016 | ||
2024 | if (addrlen != sizeof(u32)) { | 2017 | rc = -EINVAL; |
2025 | rc = -EINVAL; | 2018 | if (addrlen != sizeof(u32)) |
2026 | goto out; | 2019 | goto out; |
2027 | } | ||
2028 | 2020 | ||
2029 | addr = *((u32 *)addrp); | 2021 | addr = *((u32 *)addrp); |
2030 | 2022 | ||
@@ -2038,10 +2030,9 @@ int security_node_sid(u16 domain, | |||
2038 | } | 2030 | } |
2039 | 2031 | ||
2040 | case AF_INET6: | 2032 | case AF_INET6: |
2041 | if (addrlen != sizeof(u64) * 2) { | 2033 | rc = -EINVAL; |
2042 | rc = -EINVAL; | 2034 | if (addrlen != sizeof(u64) * 2) |
2043 | goto out; | 2035 | goto out; |
2044 | } | ||
2045 | c = policydb.ocontexts[OCON_NODE6]; | 2036 | c = policydb.ocontexts[OCON_NODE6]; |
2046 | while (c) { | 2037 | while (c) { |
2047 | if (match_ipv6_addrmask(addrp, c->u.node6.addr, | 2038 | if (match_ipv6_addrmask(addrp, c->u.node6.addr, |
@@ -2052,6 +2043,7 @@ int security_node_sid(u16 domain, | |||
2052 | break; | 2043 | break; |
2053 | 2044 | ||
2054 | default: | 2045 | default: |
2046 | rc = 0; | ||
2055 | *out_sid = SECINITSID_NODE; | 2047 | *out_sid = SECINITSID_NODE; |
2056 | goto out; | 2048 | goto out; |
2057 | } | 2049 | } |
@@ -2069,6 +2061,7 @@ int security_node_sid(u16 domain, | |||
2069 | *out_sid = SECINITSID_NODE; | 2061 | *out_sid = SECINITSID_NODE; |
2070 | } | 2062 | } |
2071 | 2063 | ||
2064 | rc = 0; | ||
2072 | out: | 2065 | out: |
2073 | read_unlock(&policy_rwlock); | 2066 | read_unlock(&policy_rwlock); |
2074 | return rc; | 2067 | return rc; |
@@ -2113,24 +2106,22 @@ int security_get_user_sids(u32 fromsid, | |||
2113 | 2106 | ||
2114 | context_init(&usercon); | 2107 | context_init(&usercon); |
2115 | 2108 | ||
2109 | rc = -EINVAL; | ||
2116 | fromcon = sidtab_search(&sidtab, fromsid); | 2110 | fromcon = sidtab_search(&sidtab, fromsid); |
2117 | if (!fromcon) { | 2111 | if (!fromcon) |
2118 | rc = -EINVAL; | ||
2119 | goto out_unlock; | 2112 | goto out_unlock; |
2120 | } | ||
2121 | 2113 | ||
2114 | rc = -EINVAL; | ||
2122 | user = hashtab_search(policydb.p_users.table, username); | 2115 | user = hashtab_search(policydb.p_users.table, username); |
2123 | if (!user) { | 2116 | if (!user) |
2124 | rc = -EINVAL; | ||
2125 | goto out_unlock; | 2117 | goto out_unlock; |
2126 | } | 2118 | |
2127 | usercon.user = user->value; | 2119 | usercon.user = user->value; |
2128 | 2120 | ||
2121 | rc = -ENOMEM; | ||
2129 | mysids = kcalloc(maxnel, sizeof(*mysids), GFP_ATOMIC); | 2122 | mysids = kcalloc(maxnel, sizeof(*mysids), GFP_ATOMIC); |
2130 | if (!mysids) { | 2123 | if (!mysids) |
2131 | rc = -ENOMEM; | ||
2132 | goto out_unlock; | 2124 | goto out_unlock; |
2133 | } | ||
2134 | 2125 | ||
2135 | ebitmap_for_each_positive_bit(&user->roles, rnode, i) { | 2126 | ebitmap_for_each_positive_bit(&user->roles, rnode, i) { |
2136 | role = policydb.role_val_to_struct[i]; | 2127 | role = policydb.role_val_to_struct[i]; |
@@ -2147,12 +2138,11 @@ int security_get_user_sids(u32 fromsid, | |||
2147 | if (mynel < maxnel) { | 2138 | if (mynel < maxnel) { |
2148 | mysids[mynel++] = sid; | 2139 | mysids[mynel++] = sid; |
2149 | } else { | 2140 | } else { |
2141 | rc = -ENOMEM; | ||
2150 | maxnel += SIDS_NEL; | 2142 | maxnel += SIDS_NEL; |
2151 | mysids2 = kcalloc(maxnel, sizeof(*mysids2), GFP_ATOMIC); | 2143 | mysids2 = kcalloc(maxnel, sizeof(*mysids2), GFP_ATOMIC); |
2152 | if (!mysids2) { | 2144 | if (!mysids2) |
2153 | rc = -ENOMEM; | ||
2154 | goto out_unlock; | 2145 | goto out_unlock; |
2155 | } | ||
2156 | memcpy(mysids2, mysids, mynel * sizeof(*mysids2)); | 2146 | memcpy(mysids2, mysids, mynel * sizeof(*mysids2)); |
2157 | kfree(mysids); | 2147 | kfree(mysids); |
2158 | mysids = mysids2; | 2148 | mysids = mysids2; |
@@ -2160,7 +2150,7 @@ int security_get_user_sids(u32 fromsid, | |||
2160 | } | 2150 | } |
2161 | } | 2151 | } |
2162 | } | 2152 | } |
2163 | 2153 | rc = 0; | |
2164 | out_unlock: | 2154 | out_unlock: |
2165 | read_unlock(&policy_rwlock); | 2155 | read_unlock(&policy_rwlock); |
2166 | if (rc || !mynel) { | 2156 | if (rc || !mynel) { |
@@ -2168,9 +2158,9 @@ out_unlock: | |||
2168 | goto out; | 2158 | goto out; |
2169 | } | 2159 | } |
2170 | 2160 | ||
2161 | rc = -ENOMEM; | ||
2171 | mysids2 = kcalloc(mynel, sizeof(*mysids2), GFP_KERNEL); | 2162 | mysids2 = kcalloc(mynel, sizeof(*mysids2), GFP_KERNEL); |
2172 | if (!mysids2) { | 2163 | if (!mysids2) { |
2173 | rc = -ENOMEM; | ||
2174 | kfree(mysids); | 2164 | kfree(mysids); |
2175 | goto out; | 2165 | goto out; |
2176 | } | 2166 | } |
@@ -2211,7 +2201,7 @@ int security_genfs_sid(const char *fstype, | |||
2211 | u16 sclass; | 2201 | u16 sclass; |
2212 | struct genfs *genfs; | 2202 | struct genfs *genfs; |
2213 | struct ocontext *c; | 2203 | struct ocontext *c; |
2214 | int rc = 0, cmp = 0; | 2204 | int rc, cmp = 0; |
2215 | 2205 | ||
2216 | while (path[0] == '/' && path[1] == '/') | 2206 | while (path[0] == '/' && path[1] == '/') |
2217 | path++; | 2207 | path++; |
@@ -2219,6 +2209,7 @@ int security_genfs_sid(const char *fstype, | |||
2219 | read_lock(&policy_rwlock); | 2209 | read_lock(&policy_rwlock); |
2220 | 2210 | ||
2221 | sclass = unmap_class(orig_sclass); | 2211 | sclass = unmap_class(orig_sclass); |
2212 | *sid = SECINITSID_UNLABELED; | ||
2222 | 2213 | ||
2223 | for (genfs = policydb.genfs; genfs; genfs = genfs->next) { | 2214 | for (genfs = policydb.genfs; genfs; genfs = genfs->next) { |
2224 | cmp = strcmp(fstype, genfs->fstype); | 2215 | cmp = strcmp(fstype, genfs->fstype); |
@@ -2226,11 +2217,9 @@ int security_genfs_sid(const char *fstype, | |||
2226 | break; | 2217 | break; |
2227 | } | 2218 | } |
2228 | 2219 | ||
2229 | if (!genfs || cmp) { | 2220 | rc = -ENOENT; |
2230 | *sid = SECINITSID_UNLABELED; | 2221 | if (!genfs || cmp) |
2231 | rc = -ENOENT; | ||
2232 | goto out; | 2222 | goto out; |
2233 | } | ||
2234 | 2223 | ||
2235 | for (c = genfs->head; c; c = c->next) { | 2224 | for (c = genfs->head; c; c = c->next) { |
2236 | len = strlen(c->u.name); | 2225 | len = strlen(c->u.name); |
@@ -2239,21 +2228,18 @@ int security_genfs_sid(const char *fstype, | |||
2239 | break; | 2228 | break; |
2240 | } | 2229 | } |
2241 | 2230 | ||
2242 | if (!c) { | 2231 | rc = -ENOENT; |
2243 | *sid = SECINITSID_UNLABELED; | 2232 | if (!c) |
2244 | rc = -ENOENT; | ||
2245 | goto out; | 2233 | goto out; |
2246 | } | ||
2247 | 2234 | ||
2248 | if (!c->sid[0]) { | 2235 | if (!c->sid[0]) { |
2249 | rc = sidtab_context_to_sid(&sidtab, | 2236 | rc = sidtab_context_to_sid(&sidtab, &c->context[0], &c->sid[0]); |
2250 | &c->context[0], | ||
2251 | &c->sid[0]); | ||
2252 | if (rc) | 2237 | if (rc) |
2253 | goto out; | 2238 | goto out; |
2254 | } | 2239 | } |
2255 | 2240 | ||
2256 | *sid = c->sid[0]; | 2241 | *sid = c->sid[0]; |
2242 | rc = 0; | ||
2257 | out: | 2243 | out: |
2258 | read_unlock(&policy_rwlock); | 2244 | read_unlock(&policy_rwlock); |
2259 | return rc; | 2245 | return rc; |
@@ -2285,8 +2271,7 @@ int security_fs_use( | |||
2285 | if (c) { | 2271 | if (c) { |
2286 | *behavior = c->v.behavior; | 2272 | *behavior = c->v.behavior; |
2287 | if (!c->sid[0]) { | 2273 | if (!c->sid[0]) { |
2288 | rc = sidtab_context_to_sid(&sidtab, | 2274 | rc = sidtab_context_to_sid(&sidtab, &c->context[0], |
2289 | &c->context[0], | ||
2290 | &c->sid[0]); | 2275 | &c->sid[0]); |
2291 | if (rc) | 2276 | if (rc) |
2292 | goto out; | 2277 | goto out; |
@@ -2309,33 +2294,38 @@ out: | |||
2309 | 2294 | ||
2310 | int security_get_bools(int *len, char ***names, int **values) | 2295 | int security_get_bools(int *len, char ***names, int **values) |
2311 | { | 2296 | { |
2312 | int i, rc = -ENOMEM; | 2297 | int i, rc; |
2313 | 2298 | ||
2314 | read_lock(&policy_rwlock); | 2299 | read_lock(&policy_rwlock); |
2315 | *names = NULL; | 2300 | *names = NULL; |
2316 | *values = NULL; | 2301 | *values = NULL; |
2317 | 2302 | ||
2303 | rc = 0; | ||
2318 | *len = policydb.p_bools.nprim; | 2304 | *len = policydb.p_bools.nprim; |
2319 | if (!*len) { | 2305 | if (!*len) |
2320 | rc = 0; | ||
2321 | goto out; | 2306 | goto out; |
2322 | } | ||
2323 | 2307 | ||
2324 | *names = kcalloc(*len, sizeof(char *), GFP_ATOMIC); | 2308 | rc = -ENOMEM; |
2309 | *names = kcalloc(*len, sizeof(char *), GFP_ATOMIC); | ||
2325 | if (!*names) | 2310 | if (!*names) |
2326 | goto err; | 2311 | goto err; |
2327 | 2312 | ||
2328 | *values = kcalloc(*len, sizeof(int), GFP_ATOMIC); | 2313 | rc = -ENOMEM; |
2314 | *values = kcalloc(*len, sizeof(int), GFP_ATOMIC); | ||
2329 | if (!*values) | 2315 | if (!*values) |
2330 | goto err; | 2316 | goto err; |
2331 | 2317 | ||
2332 | for (i = 0; i < *len; i++) { | 2318 | for (i = 0; i < *len; i++) { |
2333 | size_t name_len; | 2319 | size_t name_len; |
2320 | |||
2334 | (*values)[i] = policydb.bool_val_to_struct[i]->state; | 2321 | (*values)[i] = policydb.bool_val_to_struct[i]->state; |
2335 | name_len = strlen(policydb.p_bool_val_to_name[i]) + 1; | 2322 | name_len = strlen(policydb.p_bool_val_to_name[i]) + 1; |
2336 | (*names)[i] = kmalloc(sizeof(char) * name_len, GFP_ATOMIC); | 2323 | |
2324 | rc = -ENOMEM; | ||
2325 | (*names)[i] = kmalloc(sizeof(char) * name_len, GFP_ATOMIC); | ||
2337 | if (!(*names)[i]) | 2326 | if (!(*names)[i]) |
2338 | goto err; | 2327 | goto err; |
2328 | |||
2339 | strncpy((*names)[i], policydb.p_bool_val_to_name[i], name_len); | 2329 | strncpy((*names)[i], policydb.p_bool_val_to_name[i], name_len); |
2340 | (*names)[i][name_len - 1] = 0; | 2330 | (*names)[i][name_len - 1] = 0; |
2341 | } | 2331 | } |
@@ -2355,17 +2345,16 @@ err: | |||
2355 | 2345 | ||
2356 | int security_set_bools(int len, int *values) | 2346 | int security_set_bools(int len, int *values) |
2357 | { | 2347 | { |
2358 | int i, rc = 0; | 2348 | int i, rc; |
2359 | int lenp, seqno = 0; | 2349 | int lenp, seqno = 0; |
2360 | struct cond_node *cur; | 2350 | struct cond_node *cur; |
2361 | 2351 | ||
2362 | write_lock_irq(&policy_rwlock); | 2352 | write_lock_irq(&policy_rwlock); |
2363 | 2353 | ||
2354 | rc = -EFAULT; | ||
2364 | lenp = policydb.p_bools.nprim; | 2355 | lenp = policydb.p_bools.nprim; |
2365 | if (len != lenp) { | 2356 | if (len != lenp) |
2366 | rc = -EFAULT; | ||
2367 | goto out; | 2357 | goto out; |
2368 | } | ||
2369 | 2358 | ||
2370 | for (i = 0; i < len; i++) { | 2359 | for (i = 0; i < len; i++) { |
2371 | if (!!values[i] != policydb.bool_val_to_struct[i]->state) { | 2360 | if (!!values[i] != policydb.bool_val_to_struct[i]->state) { |
@@ -2391,7 +2380,7 @@ int security_set_bools(int len, int *values) | |||
2391 | } | 2380 | } |
2392 | 2381 | ||
2393 | seqno = ++latest_granting; | 2382 | seqno = ++latest_granting; |
2394 | 2383 | rc = 0; | |
2395 | out: | 2384 | out: |
2396 | write_unlock_irq(&policy_rwlock); | 2385 | write_unlock_irq(&policy_rwlock); |
2397 | if (!rc) { | 2386 | if (!rc) { |
@@ -2405,16 +2394,15 @@ out: | |||
2405 | 2394 | ||
2406 | int security_get_bool_value(int bool) | 2395 | int security_get_bool_value(int bool) |
2407 | { | 2396 | { |
2408 | int rc = 0; | 2397 | int rc; |
2409 | int len; | 2398 | int len; |
2410 | 2399 | ||
2411 | read_lock(&policy_rwlock); | 2400 | read_lock(&policy_rwlock); |
2412 | 2401 | ||
2402 | rc = -EFAULT; | ||
2413 | len = policydb.p_bools.nprim; | 2403 | len = policydb.p_bools.nprim; |
2414 | if (bool >= len) { | 2404 | if (bool >= len) |
2415 | rc = -EFAULT; | ||
2416 | goto out; | 2405 | goto out; |
2417 | } | ||
2418 | 2406 | ||
2419 | rc = policydb.bool_val_to_struct[bool]->state; | 2407 | rc = policydb.bool_val_to_struct[bool]->state; |
2420 | out: | 2408 | out: |
@@ -2464,8 +2452,9 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid) | |||
2464 | struct context newcon; | 2452 | struct context newcon; |
2465 | char *s; | 2453 | char *s; |
2466 | u32 len; | 2454 | u32 len; |
2467 | int rc = 0; | 2455 | int rc; |
2468 | 2456 | ||
2457 | rc = 0; | ||
2469 | if (!ss_initialized || !policydb.mls_enabled) { | 2458 | if (!ss_initialized || !policydb.mls_enabled) { |
2470 | *new_sid = sid; | 2459 | *new_sid = sid; |
2471 | goto out; | 2460 | goto out; |
@@ -2474,19 +2463,20 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid) | |||
2474 | context_init(&newcon); | 2463 | context_init(&newcon); |
2475 | 2464 | ||
2476 | read_lock(&policy_rwlock); | 2465 | read_lock(&policy_rwlock); |
2466 | |||
2467 | rc = -EINVAL; | ||
2477 | context1 = sidtab_search(&sidtab, sid); | 2468 | context1 = sidtab_search(&sidtab, sid); |
2478 | if (!context1) { | 2469 | if (!context1) { |
2479 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", | 2470 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", |
2480 | __func__, sid); | 2471 | __func__, sid); |
2481 | rc = -EINVAL; | ||
2482 | goto out_unlock; | 2472 | goto out_unlock; |
2483 | } | 2473 | } |
2484 | 2474 | ||
2475 | rc = -EINVAL; | ||
2485 | context2 = sidtab_search(&sidtab, mls_sid); | 2476 | context2 = sidtab_search(&sidtab, mls_sid); |
2486 | if (!context2) { | 2477 | if (!context2) { |
2487 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", | 2478 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", |
2488 | __func__, mls_sid); | 2479 | __func__, mls_sid); |
2489 | rc = -EINVAL; | ||
2490 | goto out_unlock; | 2480 | goto out_unlock; |
2491 | } | 2481 | } |
2492 | 2482 | ||
@@ -2500,20 +2490,17 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid) | |||
2500 | /* Check the validity of the new context. */ | 2490 | /* Check the validity of the new context. */ |
2501 | if (!policydb_context_isvalid(&policydb, &newcon)) { | 2491 | if (!policydb_context_isvalid(&policydb, &newcon)) { |
2502 | rc = convert_context_handle_invalid_context(&newcon); | 2492 | rc = convert_context_handle_invalid_context(&newcon); |
2503 | if (rc) | 2493 | if (rc) { |
2504 | goto bad; | 2494 | if (!context_struct_to_string(&newcon, &s, &len)) { |
2495 | audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, | ||
2496 | "security_sid_mls_copy: invalid context %s", s); | ||
2497 | kfree(s); | ||
2498 | } | ||
2499 | goto out_unlock; | ||
2500 | } | ||
2505 | } | 2501 | } |
2506 | 2502 | ||
2507 | rc = sidtab_context_to_sid(&sidtab, &newcon, new_sid); | 2503 | rc = sidtab_context_to_sid(&sidtab, &newcon, new_sid); |
2508 | goto out_unlock; | ||
2509 | |||
2510 | bad: | ||
2511 | if (!context_struct_to_string(&newcon, &s, &len)) { | ||
2512 | audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, | ||
2513 | "security_sid_mls_copy: invalid context %s", s); | ||
2514 | kfree(s); | ||
2515 | } | ||
2516 | |||
2517 | out_unlock: | 2504 | out_unlock: |
2518 | read_unlock(&policy_rwlock); | 2505 | read_unlock(&policy_rwlock); |
2519 | context_destroy(&newcon); | 2506 | context_destroy(&newcon); |
@@ -2549,6 +2536,8 @@ int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type, | |||
2549 | struct context *nlbl_ctx; | 2536 | struct context *nlbl_ctx; |
2550 | struct context *xfrm_ctx; | 2537 | struct context *xfrm_ctx; |
2551 | 2538 | ||
2539 | *peer_sid = SECSID_NULL; | ||
2540 | |||
2552 | /* handle the common (which also happens to be the set of easy) cases | 2541 | /* handle the common (which also happens to be the set of easy) cases |
2553 | * right away, these two if statements catch everything involving a | 2542 | * right away, these two if statements catch everything involving a |
2554 | * single or absent peer SID/label */ | 2543 | * single or absent peer SID/label */ |
@@ -2567,40 +2556,37 @@ int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type, | |||
2567 | /* we don't need to check ss_initialized here since the only way both | 2556 | /* we don't need to check ss_initialized here since the only way both |
2568 | * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the | 2557 | * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the |
2569 | * security server was initialized and ss_initialized was true */ | 2558 | * security server was initialized and ss_initialized was true */ |
2570 | if (!policydb.mls_enabled) { | 2559 | if (!policydb.mls_enabled) |
2571 | *peer_sid = SECSID_NULL; | ||
2572 | return 0; | 2560 | return 0; |
2573 | } | ||
2574 | 2561 | ||
2575 | read_lock(&policy_rwlock); | 2562 | read_lock(&policy_rwlock); |
2576 | 2563 | ||
2564 | rc = -EINVAL; | ||
2577 | nlbl_ctx = sidtab_search(&sidtab, nlbl_sid); | 2565 | nlbl_ctx = sidtab_search(&sidtab, nlbl_sid); |
2578 | if (!nlbl_ctx) { | 2566 | if (!nlbl_ctx) { |
2579 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", | 2567 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", |
2580 | __func__, nlbl_sid); | 2568 | __func__, nlbl_sid); |
2581 | rc = -EINVAL; | 2569 | goto out; |
2582 | goto out_slowpath; | ||
2583 | } | 2570 | } |
2571 | rc = -EINVAL; | ||
2584 | xfrm_ctx = sidtab_search(&sidtab, xfrm_sid); | 2572 | xfrm_ctx = sidtab_search(&sidtab, xfrm_sid); |
2585 | if (!xfrm_ctx) { | 2573 | if (!xfrm_ctx) { |
2586 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", | 2574 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", |
2587 | __func__, xfrm_sid); | 2575 | __func__, xfrm_sid); |
2588 | rc = -EINVAL; | 2576 | goto out; |
2589 | goto out_slowpath; | ||
2590 | } | 2577 | } |
2591 | rc = (mls_context_cmp(nlbl_ctx, xfrm_ctx) ? 0 : -EACCES); | 2578 | rc = (mls_context_cmp(nlbl_ctx, xfrm_ctx) ? 0 : -EACCES); |
2579 | if (rc) | ||
2580 | goto out; | ||
2592 | 2581 | ||
2593 | out_slowpath: | 2582 | /* at present NetLabel SIDs/labels really only carry MLS |
2583 | * information so if the MLS portion of the NetLabel SID | ||
2584 | * matches the MLS portion of the labeled XFRM SID/label | ||
2585 | * then pass along the XFRM SID as it is the most | ||
2586 | * expressive */ | ||
2587 | *peer_sid = xfrm_sid; | ||
2588 | out: | ||
2594 | read_unlock(&policy_rwlock); | 2589 | read_unlock(&policy_rwlock); |
2595 | if (rc == 0) | ||
2596 | /* at present NetLabel SIDs/labels really only carry MLS | ||
2597 | * information so if the MLS portion of the NetLabel SID | ||
2598 | * matches the MLS portion of the labeled XFRM SID/label | ||
2599 | * then pass along the XFRM SID as it is the most | ||
2600 | * expressive */ | ||
2601 | *peer_sid = xfrm_sid; | ||
2602 | else | ||
2603 | *peer_sid = SECSID_NULL; | ||
2604 | return rc; | 2590 | return rc; |
2605 | } | 2591 | } |
2606 | 2592 | ||
@@ -2619,10 +2605,11 @@ static int get_classes_callback(void *k, void *d, void *args) | |||
2619 | 2605 | ||
2620 | int security_get_classes(char ***classes, int *nclasses) | 2606 | int security_get_classes(char ***classes, int *nclasses) |
2621 | { | 2607 | { |
2622 | int rc = -ENOMEM; | 2608 | int rc; |
2623 | 2609 | ||
2624 | read_lock(&policy_rwlock); | 2610 | read_lock(&policy_rwlock); |
2625 | 2611 | ||
2612 | rc = -ENOMEM; | ||
2626 | *nclasses = policydb.p_classes.nprim; | 2613 | *nclasses = policydb.p_classes.nprim; |
2627 | *classes = kcalloc(*nclasses, sizeof(**classes), GFP_ATOMIC); | 2614 | *classes = kcalloc(*nclasses, sizeof(**classes), GFP_ATOMIC); |
2628 | if (!*classes) | 2615 | if (!*classes) |
@@ -2630,7 +2617,7 @@ int security_get_classes(char ***classes, int *nclasses) | |||
2630 | 2617 | ||
2631 | rc = hashtab_map(policydb.p_classes.table, get_classes_callback, | 2618 | rc = hashtab_map(policydb.p_classes.table, get_classes_callback, |
2632 | *classes); | 2619 | *classes); |
2633 | if (rc < 0) { | 2620 | if (rc) { |
2634 | int i; | 2621 | int i; |
2635 | for (i = 0; i < *nclasses; i++) | 2622 | for (i = 0; i < *nclasses; i++) |
2636 | kfree((*classes)[i]); | 2623 | kfree((*classes)[i]); |
@@ -2657,19 +2644,20 @@ static int get_permissions_callback(void *k, void *d, void *args) | |||
2657 | 2644 | ||
2658 | int security_get_permissions(char *class, char ***perms, int *nperms) | 2645 | int security_get_permissions(char *class, char ***perms, int *nperms) |
2659 | { | 2646 | { |
2660 | int rc = -ENOMEM, i; | 2647 | int rc, i; |
2661 | struct class_datum *match; | 2648 | struct class_datum *match; |
2662 | 2649 | ||
2663 | read_lock(&policy_rwlock); | 2650 | read_lock(&policy_rwlock); |
2664 | 2651 | ||
2652 | rc = -EINVAL; | ||
2665 | match = hashtab_search(policydb.p_classes.table, class); | 2653 | match = hashtab_search(policydb.p_classes.table, class); |
2666 | if (!match) { | 2654 | if (!match) { |
2667 | printk(KERN_ERR "SELinux: %s: unrecognized class %s\n", | 2655 | printk(KERN_ERR "SELinux: %s: unrecognized class %s\n", |
2668 | __func__, class); | 2656 | __func__, class); |
2669 | rc = -EINVAL; | ||
2670 | goto out; | 2657 | goto out; |
2671 | } | 2658 | } |
2672 | 2659 | ||
2660 | rc = -ENOMEM; | ||
2673 | *nperms = match->permissions.nprim; | 2661 | *nperms = match->permissions.nprim; |
2674 | *perms = kcalloc(*nperms, sizeof(**perms), GFP_ATOMIC); | 2662 | *perms = kcalloc(*nperms, sizeof(**perms), GFP_ATOMIC); |
2675 | if (!*perms) | 2663 | if (!*perms) |
@@ -2678,13 +2666,13 @@ int security_get_permissions(char *class, char ***perms, int *nperms) | |||
2678 | if (match->comdatum) { | 2666 | if (match->comdatum) { |
2679 | rc = hashtab_map(match->comdatum->permissions.table, | 2667 | rc = hashtab_map(match->comdatum->permissions.table, |
2680 | get_permissions_callback, *perms); | 2668 | get_permissions_callback, *perms); |
2681 | if (rc < 0) | 2669 | if (rc) |
2682 | goto err; | 2670 | goto err; |
2683 | } | 2671 | } |
2684 | 2672 | ||
2685 | rc = hashtab_map(match->permissions.table, get_permissions_callback, | 2673 | rc = hashtab_map(match->permissions.table, get_permissions_callback, |
2686 | *perms); | 2674 | *perms); |
2687 | if (rc < 0) | 2675 | if (rc) |
2688 | goto err; | 2676 | goto err; |
2689 | 2677 | ||
2690 | out: | 2678 | out: |
@@ -2796,36 +2784,39 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) | |||
2796 | switch (field) { | 2784 | switch (field) { |
2797 | case AUDIT_SUBJ_USER: | 2785 | case AUDIT_SUBJ_USER: |
2798 | case AUDIT_OBJ_USER: | 2786 | case AUDIT_OBJ_USER: |
2787 | rc = -EINVAL; | ||
2799 | userdatum = hashtab_search(policydb.p_users.table, rulestr); | 2788 | userdatum = hashtab_search(policydb.p_users.table, rulestr); |
2800 | if (!userdatum) | 2789 | if (!userdatum) |
2801 | rc = -EINVAL; | 2790 | goto out; |
2802 | else | 2791 | tmprule->au_ctxt.user = userdatum->value; |
2803 | tmprule->au_ctxt.user = userdatum->value; | ||
2804 | break; | 2792 | break; |
2805 | case AUDIT_SUBJ_ROLE: | 2793 | case AUDIT_SUBJ_ROLE: |
2806 | case AUDIT_OBJ_ROLE: | 2794 | case AUDIT_OBJ_ROLE: |
2795 | rc = -EINVAL; | ||
2807 | roledatum = hashtab_search(policydb.p_roles.table, rulestr); | 2796 | roledatum = hashtab_search(policydb.p_roles.table, rulestr); |
2808 | if (!roledatum) | 2797 | if (!roledatum) |
2809 | rc = -EINVAL; | 2798 | goto out; |
2810 | else | 2799 | tmprule->au_ctxt.role = roledatum->value; |
2811 | tmprule->au_ctxt.role = roledatum->value; | ||
2812 | break; | 2800 | break; |
2813 | case AUDIT_SUBJ_TYPE: | 2801 | case AUDIT_SUBJ_TYPE: |
2814 | case AUDIT_OBJ_TYPE: | 2802 | case AUDIT_OBJ_TYPE: |
2803 | rc = -EINVAL; | ||
2815 | typedatum = hashtab_search(policydb.p_types.table, rulestr); | 2804 | typedatum = hashtab_search(policydb.p_types.table, rulestr); |
2816 | if (!typedatum) | 2805 | if (!typedatum) |
2817 | rc = -EINVAL; | 2806 | goto out; |
2818 | else | 2807 | tmprule->au_ctxt.type = typedatum->value; |
2819 | tmprule->au_ctxt.type = typedatum->value; | ||
2820 | break; | 2808 | break; |
2821 | case AUDIT_SUBJ_SEN: | 2809 | case AUDIT_SUBJ_SEN: |
2822 | case AUDIT_SUBJ_CLR: | 2810 | case AUDIT_SUBJ_CLR: |
2823 | case AUDIT_OBJ_LEV_LOW: | 2811 | case AUDIT_OBJ_LEV_LOW: |
2824 | case AUDIT_OBJ_LEV_HIGH: | 2812 | case AUDIT_OBJ_LEV_HIGH: |
2825 | rc = mls_from_string(rulestr, &tmprule->au_ctxt, GFP_ATOMIC); | 2813 | rc = mls_from_string(rulestr, &tmprule->au_ctxt, GFP_ATOMIC); |
2814 | if (rc) | ||
2815 | goto out; | ||
2826 | break; | 2816 | break; |
2827 | } | 2817 | } |
2828 | 2818 | rc = 0; | |
2819 | out: | ||
2829 | read_unlock(&policy_rwlock); | 2820 | read_unlock(&policy_rwlock); |
2830 | 2821 | ||
2831 | if (rc) { | 2822 | if (rc) { |
@@ -3127,28 +3118,23 @@ int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr) | |||
3127 | return 0; | 3118 | return 0; |
3128 | 3119 | ||
3129 | read_lock(&policy_rwlock); | 3120 | read_lock(&policy_rwlock); |
3121 | |||
3122 | rc = -ENOENT; | ||
3130 | ctx = sidtab_search(&sidtab, sid); | 3123 | ctx = sidtab_search(&sidtab, sid); |
3131 | if (ctx == NULL) { | 3124 | if (ctx == NULL) |
3132 | rc = -ENOENT; | 3125 | goto out; |
3133 | goto netlbl_sid_to_secattr_failure; | 3126 | |
3134 | } | 3127 | rc = -ENOMEM; |
3135 | secattr->domain = kstrdup(policydb.p_type_val_to_name[ctx->type - 1], | 3128 | secattr->domain = kstrdup(policydb.p_type_val_to_name[ctx->type - 1], |
3136 | GFP_ATOMIC); | 3129 | GFP_ATOMIC); |
3137 | if (secattr->domain == NULL) { | 3130 | if (secattr->domain == NULL) |
3138 | rc = -ENOMEM; | 3131 | goto out; |
3139 | goto netlbl_sid_to_secattr_failure; | 3132 | |
3140 | } | ||
3141 | secattr->attr.secid = sid; | 3133 | secattr->attr.secid = sid; |
3142 | secattr->flags |= NETLBL_SECATTR_DOMAIN_CPY | NETLBL_SECATTR_SECID; | 3134 | secattr->flags |= NETLBL_SECATTR_DOMAIN_CPY | NETLBL_SECATTR_SECID; |
3143 | mls_export_netlbl_lvl(ctx, secattr); | 3135 | mls_export_netlbl_lvl(ctx, secattr); |
3144 | rc = mls_export_netlbl_cat(ctx, secattr); | 3136 | rc = mls_export_netlbl_cat(ctx, secattr); |
3145 | if (rc != 0) | 3137 | out: |
3146 | goto netlbl_sid_to_secattr_failure; | ||
3147 | read_unlock(&policy_rwlock); | ||
3148 | |||
3149 | return 0; | ||
3150 | |||
3151 | netlbl_sid_to_secattr_failure: | ||
3152 | read_unlock(&policy_rwlock); | 3138 | read_unlock(&policy_rwlock); |
3153 | return rc; | 3139 | return rc; |
3154 | } | 3140 | } |