aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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}