aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2010-11-23 11:40:08 -0500
committerEric Paris <eparis@redhat.com>2010-11-30 17:28:57 -0500
commit4b02b524487622ce1cf472123899520b583f47dc (patch)
tree58802e2968852cb1eb0f8f6303fbfaf3d85ecc53 /security
parentb77a493b1dc8010245feeac001e5c7ed0988678f (diff)
SELinux: standardize return code handling in selinuxfs.c
selinuxfs.c has lots of different standards on how to handle return paths on error. For the most part transition to rc=errno if (failure) goto out; [...] out: cleanup() return rc; Instead of doing cleanup mid function, or having multiple returns or other options. This doesn't do that for every function, but most of the complex functions which have cleanup routines on error. Signed-off-by: Eric Paris <eparis@redhat.com>
Diffstat (limited to 'security')
-rw-r--r--security/selinux/ss/services.c328
1 files changed, 157 insertions, 171 deletions
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 223c1ff6ef2..84e2a98d7cc 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;
1201out: 1198out:
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);
1257out: 1252out_unlock:
1258 read_unlock(&policy_rwlock); 1253 read_unlock(&policy_rwlock);
1254out:
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
1570static inline int convert_context_handle_invalid_context(struct context *context) 1566static 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
1590struct convert_context_args { 1581struct 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;
1723out: 1716out:
1724 return rc; 1717 return rc;
1725bad: 1718bad:
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;
2072out: 2065out:
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;
2164out_unlock: 2154out_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;
2257out: 2243out:
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
2310int security_get_bools(int *len, char ***names, int **values) 2295int 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
2356int security_set_bools(int len, int *values) 2346int 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;
2395out: 2384out:
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
2406int security_get_bool_value(int bool) 2395int 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;
2420out: 2408out:
@@ -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
2510bad:
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
2517out_unlock: 2504out_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
2593out_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;
2588out:
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
2620int security_get_classes(char ***classes, int *nclasses) 2606int 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
2658int security_get_permissions(char *class, char ***perms, int *nperms) 2645int 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
2690out: 2678out:
@@ -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;
2819out:
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) 3137out:
3146 goto netlbl_sid_to_secattr_failure;
3147 read_unlock(&policy_rwlock);
3148
3149 return 0;
3150
3151netlbl_sid_to_secattr_failure:
3152 read_unlock(&policy_rwlock); 3138 read_unlock(&policy_rwlock);
3153 return rc; 3139 return rc;
3154} 3140}