diff options
Diffstat (limited to 'security/selinux/ss/services.c')
| -rw-r--r-- | security/selinux/ss/services.c | 222 |
1 files changed, 97 insertions, 125 deletions
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 12e414394530..dd44126c8d14 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
| @@ -71,7 +71,7 @@ | |||
| 71 | #include "audit.h" | 71 | #include "audit.h" |
| 72 | 72 | ||
| 73 | /* Policy capability names */ | 73 | /* Policy capability names */ |
| 74 | char *selinux_policycap_names[__POLICYDB_CAPABILITY_MAX] = { | 74 | const char *selinux_policycap_names[__POLICYDB_CAPABILITY_MAX] = { |
| 75 | "network_peer_controls", | 75 | "network_peer_controls", |
| 76 | "open_perms", | 76 | "open_perms", |
| 77 | "extended_socket_class", | 77 | "extended_socket_class", |
| @@ -776,7 +776,7 @@ static int security_compute_validatetrans(struct selinux_state *state, | |||
| 776 | read_lock(&state->ss->policy_rwlock); | 776 | read_lock(&state->ss->policy_rwlock); |
| 777 | 777 | ||
| 778 | policydb = &state->ss->policydb; | 778 | policydb = &state->ss->policydb; |
| 779 | sidtab = &state->ss->sidtab; | 779 | sidtab = state->ss->sidtab; |
| 780 | 780 | ||
| 781 | if (!user) | 781 | if (!user) |
| 782 | tclass = unmap_class(&state->ss->map, orig_tclass); | 782 | tclass = unmap_class(&state->ss->map, orig_tclass); |
| @@ -876,7 +876,7 @@ int security_bounded_transition(struct selinux_state *state, | |||
| 876 | read_lock(&state->ss->policy_rwlock); | 876 | read_lock(&state->ss->policy_rwlock); |
| 877 | 877 | ||
| 878 | policydb = &state->ss->policydb; | 878 | policydb = &state->ss->policydb; |
| 879 | sidtab = &state->ss->sidtab; | 879 | sidtab = state->ss->sidtab; |
| 880 | 880 | ||
| 881 | rc = -EINVAL; | 881 | rc = -EINVAL; |
| 882 | old_context = sidtab_search(sidtab, old_sid); | 882 | old_context = sidtab_search(sidtab, old_sid); |
| @@ -1034,7 +1034,7 @@ void security_compute_xperms_decision(struct selinux_state *state, | |||
| 1034 | goto allow; | 1034 | goto allow; |
| 1035 | 1035 | ||
| 1036 | policydb = &state->ss->policydb; | 1036 | policydb = &state->ss->policydb; |
| 1037 | sidtab = &state->ss->sidtab; | 1037 | sidtab = state->ss->sidtab; |
| 1038 | 1038 | ||
| 1039 | scontext = sidtab_search(sidtab, ssid); | 1039 | scontext = sidtab_search(sidtab, ssid); |
| 1040 | if (!scontext) { | 1040 | if (!scontext) { |
| @@ -1123,7 +1123,7 @@ void security_compute_av(struct selinux_state *state, | |||
| 1123 | goto allow; | 1123 | goto allow; |
| 1124 | 1124 | ||
| 1125 | policydb = &state->ss->policydb; | 1125 | policydb = &state->ss->policydb; |
| 1126 | sidtab = &state->ss->sidtab; | 1126 | sidtab = state->ss->sidtab; |
| 1127 | 1127 | ||
| 1128 | scontext = sidtab_search(sidtab, ssid); | 1128 | scontext = sidtab_search(sidtab, ssid); |
| 1129 | if (!scontext) { | 1129 | if (!scontext) { |
| @@ -1177,7 +1177,7 @@ void security_compute_av_user(struct selinux_state *state, | |||
| 1177 | goto allow; | 1177 | goto allow; |
| 1178 | 1178 | ||
| 1179 | policydb = &state->ss->policydb; | 1179 | policydb = &state->ss->policydb; |
| 1180 | sidtab = &state->ss->sidtab; | 1180 | sidtab = state->ss->sidtab; |
| 1181 | 1181 | ||
| 1182 | scontext = sidtab_search(sidtab, ssid); | 1182 | scontext = sidtab_search(sidtab, ssid); |
| 1183 | if (!scontext) { | 1183 | if (!scontext) { |
| @@ -1315,7 +1315,7 @@ static int security_sid_to_context_core(struct selinux_state *state, | |||
| 1315 | } | 1315 | } |
| 1316 | read_lock(&state->ss->policy_rwlock); | 1316 | read_lock(&state->ss->policy_rwlock); |
| 1317 | policydb = &state->ss->policydb; | 1317 | policydb = &state->ss->policydb; |
| 1318 | sidtab = &state->ss->sidtab; | 1318 | sidtab = state->ss->sidtab; |
| 1319 | if (force) | 1319 | if (force) |
| 1320 | context = sidtab_search_force(sidtab, sid); | 1320 | context = sidtab_search_force(sidtab, sid); |
| 1321 | else | 1321 | else |
| @@ -1483,7 +1483,7 @@ static int security_context_to_sid_core(struct selinux_state *state, | |||
| 1483 | } | 1483 | } |
| 1484 | read_lock(&state->ss->policy_rwlock); | 1484 | read_lock(&state->ss->policy_rwlock); |
| 1485 | policydb = &state->ss->policydb; | 1485 | policydb = &state->ss->policydb; |
| 1486 | sidtab = &state->ss->sidtab; | 1486 | sidtab = state->ss->sidtab; |
| 1487 | rc = string_to_context_struct(policydb, sidtab, scontext2, | 1487 | rc = string_to_context_struct(policydb, sidtab, scontext2, |
| 1488 | &context, def_sid); | 1488 | &context, def_sid); |
| 1489 | if (rc == -EINVAL && force) { | 1489 | if (rc == -EINVAL && force) { |
| @@ -1668,7 +1668,7 @@ static int security_compute_sid(struct selinux_state *state, | |||
| 1668 | } | 1668 | } |
| 1669 | 1669 | ||
| 1670 | policydb = &state->ss->policydb; | 1670 | policydb = &state->ss->policydb; |
| 1671 | sidtab = &state->ss->sidtab; | 1671 | sidtab = state->ss->sidtab; |
| 1672 | 1672 | ||
| 1673 | scontext = sidtab_search(sidtab, ssid); | 1673 | scontext = sidtab_search(sidtab, ssid); |
| 1674 | if (!scontext) { | 1674 | if (!scontext) { |
| @@ -1880,19 +1880,6 @@ int security_change_sid(struct selinux_state *state, | |||
| 1880 | out_sid, false); | 1880 | out_sid, false); |
| 1881 | } | 1881 | } |
| 1882 | 1882 | ||
| 1883 | /* Clone the SID into the new SID table. */ | ||
| 1884 | static int clone_sid(u32 sid, | ||
| 1885 | struct context *context, | ||
| 1886 | void *arg) | ||
| 1887 | { | ||
| 1888 | struct sidtab *s = arg; | ||
| 1889 | |||
| 1890 | if (sid > SECINITSID_NUM) | ||
| 1891 | return sidtab_insert(s, sid, context); | ||
| 1892 | else | ||
| 1893 | return 0; | ||
| 1894 | } | ||
| 1895 | |||
| 1896 | static inline int convert_context_handle_invalid_context( | 1883 | static inline int convert_context_handle_invalid_context( |
| 1897 | struct selinux_state *state, | 1884 | struct selinux_state *state, |
| 1898 | struct context *context) | 1885 | struct context *context) |
| @@ -1920,101 +1907,84 @@ struct convert_context_args { | |||
| 1920 | 1907 | ||
| 1921 | /* | 1908 | /* |
| 1922 | * Convert the values in the security context | 1909 | * Convert the values in the security context |
| 1923 | * structure `c' from the values specified | 1910 | * structure `oldc' from the values specified |
| 1924 | * in the policy `p->oldp' to the values specified | 1911 | * in the policy `p->oldp' to the values specified |
| 1925 | * in the policy `p->newp'. Verify that the | 1912 | * in the policy `p->newp', storing the new context |
| 1926 | * context is valid under the new policy. | 1913 | * in `newc'. Verify that the context is valid |
| 1914 | * under the new policy. | ||
| 1927 | */ | 1915 | */ |
| 1928 | static int convert_context(u32 key, | 1916 | static int convert_context(struct context *oldc, struct context *newc, void *p) |
| 1929 | struct context *c, | ||
| 1930 | void *p) | ||
| 1931 | { | 1917 | { |
| 1932 | struct convert_context_args *args; | 1918 | struct convert_context_args *args; |
| 1933 | struct context oldc; | ||
| 1934 | struct ocontext *oc; | 1919 | struct ocontext *oc; |
| 1935 | struct mls_range *range; | ||
| 1936 | struct role_datum *role; | 1920 | struct role_datum *role; |
| 1937 | struct type_datum *typdatum; | 1921 | struct type_datum *typdatum; |
| 1938 | struct user_datum *usrdatum; | 1922 | struct user_datum *usrdatum; |
| 1939 | char *s; | 1923 | char *s; |
| 1940 | u32 len; | 1924 | u32 len; |
| 1941 | int rc = 0; | 1925 | int rc; |
| 1942 | |||
| 1943 | if (key <= SECINITSID_NUM) | ||
| 1944 | goto out; | ||
| 1945 | 1926 | ||
| 1946 | args = p; | 1927 | args = p; |
| 1947 | 1928 | ||
| 1948 | if (c->str) { | 1929 | if (oldc->str) { |
| 1949 | struct context ctx; | 1930 | s = kstrdup(oldc->str, GFP_KERNEL); |
| 1950 | |||
| 1951 | rc = -ENOMEM; | ||
| 1952 | s = kstrdup(c->str, GFP_KERNEL); | ||
| 1953 | if (!s) | 1931 | if (!s) |
| 1954 | goto out; | 1932 | return -ENOMEM; |
| 1955 | 1933 | ||
| 1956 | rc = string_to_context_struct(args->newp, NULL, s, | 1934 | rc = string_to_context_struct(args->newp, NULL, s, |
| 1957 | &ctx, SECSID_NULL); | 1935 | newc, SECSID_NULL); |
| 1958 | kfree(s); | 1936 | if (rc == -EINVAL) { |
| 1959 | if (!rc) { | ||
| 1960 | pr_info("SELinux: Context %s became valid (mapped).\n", | ||
| 1961 | c->str); | ||
| 1962 | /* Replace string with mapped representation. */ | ||
| 1963 | kfree(c->str); | ||
| 1964 | memcpy(c, &ctx, sizeof(*c)); | ||
| 1965 | goto out; | ||
| 1966 | } else if (rc == -EINVAL) { | ||
| 1967 | /* Retain string representation for later mapping. */ | 1937 | /* Retain string representation for later mapping. */ |
| 1968 | rc = 0; | 1938 | context_init(newc); |
| 1969 | goto out; | 1939 | newc->str = s; |
| 1970 | } else { | 1940 | newc->len = oldc->len; |
| 1941 | return 0; | ||
| 1942 | } | ||
| 1943 | kfree(s); | ||
| 1944 | if (rc) { | ||
| 1971 | /* Other error condition, e.g. ENOMEM. */ | 1945 | /* Other error condition, e.g. ENOMEM. */ |
| 1972 | pr_err("SELinux: Unable to map context %s, rc = %d.\n", | 1946 | pr_err("SELinux: Unable to map context %s, rc = %d.\n", |
| 1973 | c->str, -rc); | 1947 | oldc->str, -rc); |
| 1974 | goto out; | 1948 | return rc; |
| 1975 | } | 1949 | } |
| 1950 | pr_info("SELinux: Context %s became valid (mapped).\n", | ||
| 1951 | oldc->str); | ||
| 1952 | return 0; | ||
| 1976 | } | 1953 | } |
| 1977 | 1954 | ||
| 1978 | rc = context_cpy(&oldc, c); | 1955 | context_init(newc); |
| 1979 | if (rc) | ||
| 1980 | goto out; | ||
| 1981 | 1956 | ||
| 1982 | /* Convert the user. */ | 1957 | /* Convert the user. */ |
| 1983 | rc = -EINVAL; | 1958 | rc = -EINVAL; |
| 1984 | usrdatum = hashtab_search(args->newp->p_users.table, | 1959 | usrdatum = hashtab_search(args->newp->p_users.table, |
| 1985 | sym_name(args->oldp, SYM_USERS, c->user - 1)); | 1960 | sym_name(args->oldp, |
| 1961 | SYM_USERS, oldc->user - 1)); | ||
| 1986 | if (!usrdatum) | 1962 | if (!usrdatum) |
| 1987 | goto bad; | 1963 | goto bad; |
| 1988 | c->user = usrdatum->value; | 1964 | newc->user = usrdatum->value; |
| 1989 | 1965 | ||
| 1990 | /* Convert the role. */ | 1966 | /* Convert the role. */ |
| 1991 | rc = -EINVAL; | 1967 | rc = -EINVAL; |
| 1992 | role = hashtab_search(args->newp->p_roles.table, | 1968 | role = hashtab_search(args->newp->p_roles.table, |
| 1993 | sym_name(args->oldp, SYM_ROLES, c->role - 1)); | 1969 | sym_name(args->oldp, SYM_ROLES, oldc->role - 1)); |
| 1994 | if (!role) | 1970 | if (!role) |
| 1995 | goto bad; | 1971 | goto bad; |
| 1996 | c->role = role->value; | 1972 | newc->role = role->value; |
| 1997 | 1973 | ||
| 1998 | /* Convert the type. */ | 1974 | /* Convert the type. */ |
| 1999 | rc = -EINVAL; | 1975 | rc = -EINVAL; |
| 2000 | typdatum = hashtab_search(args->newp->p_types.table, | 1976 | typdatum = hashtab_search(args->newp->p_types.table, |
| 2001 | sym_name(args->oldp, SYM_TYPES, c->type - 1)); | 1977 | sym_name(args->oldp, |
| 1978 | SYM_TYPES, oldc->type - 1)); | ||
| 2002 | if (!typdatum) | 1979 | if (!typdatum) |
| 2003 | goto bad; | 1980 | goto bad; |
| 2004 | c->type = typdatum->value; | 1981 | newc->type = typdatum->value; |
| 2005 | 1982 | ||
| 2006 | /* Convert the MLS fields if dealing with MLS policies */ | 1983 | /* Convert the MLS fields if dealing with MLS policies */ |
| 2007 | if (args->oldp->mls_enabled && args->newp->mls_enabled) { | 1984 | if (args->oldp->mls_enabled && args->newp->mls_enabled) { |
| 2008 | rc = mls_convert_context(args->oldp, args->newp, c); | 1985 | rc = mls_convert_context(args->oldp, args->newp, oldc, newc); |
| 2009 | if (rc) | 1986 | if (rc) |
| 2010 | goto bad; | 1987 | goto bad; |
| 2011 | } else if (args->oldp->mls_enabled && !args->newp->mls_enabled) { | ||
| 2012 | /* | ||
| 2013 | * Switching between MLS and non-MLS policy: | ||
| 2014 | * free any storage used by the MLS fields in the | ||
| 2015 | * context for all existing entries in the sidtab. | ||
| 2016 | */ | ||
| 2017 | mls_context_destroy(c); | ||
| 2018 | } else if (!args->oldp->mls_enabled && args->newp->mls_enabled) { | 1988 | } else if (!args->oldp->mls_enabled && args->newp->mls_enabled) { |
| 2019 | /* | 1989 | /* |
| 2020 | * Switching between non-MLS and MLS policy: | 1990 | * Switching between non-MLS and MLS policy: |
| @@ -2032,38 +2002,30 @@ static int convert_context(u32 key, | |||
| 2032 | " the initial SIDs list\n"); | 2002 | " the initial SIDs list\n"); |
| 2033 | goto bad; | 2003 | goto bad; |
| 2034 | } | 2004 | } |
| 2035 | range = &oc->context[0].range; | 2005 | rc = mls_range_set(newc, &oc->context[0].range); |
| 2036 | rc = mls_range_set(c, range); | ||
| 2037 | if (rc) | 2006 | if (rc) |
| 2038 | goto bad; | 2007 | goto bad; |
| 2039 | } | 2008 | } |
| 2040 | 2009 | ||
| 2041 | /* Check the validity of the new context. */ | 2010 | /* Check the validity of the new context. */ |
| 2042 | if (!policydb_context_isvalid(args->newp, c)) { | 2011 | if (!policydb_context_isvalid(args->newp, newc)) { |
| 2043 | rc = convert_context_handle_invalid_context(args->state, | 2012 | rc = convert_context_handle_invalid_context(args->state, oldc); |
| 2044 | &oldc); | ||
| 2045 | if (rc) | 2013 | if (rc) |
| 2046 | goto bad; | 2014 | goto bad; |
| 2047 | } | 2015 | } |
| 2048 | 2016 | ||
| 2049 | context_destroy(&oldc); | 2017 | return 0; |
| 2050 | |||
| 2051 | rc = 0; | ||
| 2052 | out: | ||
| 2053 | return rc; | ||
| 2054 | bad: | 2018 | bad: |
| 2055 | /* Map old representation to string and save it. */ | 2019 | /* Map old representation to string and save it. */ |
| 2056 | rc = context_struct_to_string(args->oldp, &oldc, &s, &len); | 2020 | rc = context_struct_to_string(args->oldp, oldc, &s, &len); |
| 2057 | if (rc) | 2021 | if (rc) |
| 2058 | return rc; | 2022 | return rc; |
| 2059 | context_destroy(&oldc); | 2023 | context_destroy(newc); |
| 2060 | context_destroy(c); | 2024 | newc->str = s; |
| 2061 | c->str = s; | 2025 | newc->len = len; |
| 2062 | c->len = len; | ||
| 2063 | pr_info("SELinux: Context %s became invalid (unmapped).\n", | 2026 | pr_info("SELinux: Context %s became invalid (unmapped).\n", |
| 2064 | c->str); | 2027 | newc->str); |
| 2065 | rc = 0; | 2028 | return 0; |
| 2066 | goto out; | ||
| 2067 | } | 2029 | } |
| 2068 | 2030 | ||
| 2069 | static void security_load_policycaps(struct selinux_state *state) | 2031 | static void security_load_policycaps(struct selinux_state *state) |
| @@ -2103,11 +2065,11 @@ static int security_preserve_bools(struct selinux_state *state, | |||
| 2103 | int security_load_policy(struct selinux_state *state, void *data, size_t len) | 2065 | int security_load_policy(struct selinux_state *state, void *data, size_t len) |
| 2104 | { | 2066 | { |
| 2105 | struct policydb *policydb; | 2067 | struct policydb *policydb; |
| 2106 | struct sidtab *sidtab; | 2068 | struct sidtab *oldsidtab, *newsidtab; |
| 2107 | struct policydb *oldpolicydb, *newpolicydb; | 2069 | struct policydb *oldpolicydb, *newpolicydb; |
| 2108 | struct sidtab oldsidtab, newsidtab; | ||
| 2109 | struct selinux_mapping *oldmapping; | 2070 | struct selinux_mapping *oldmapping; |
| 2110 | struct selinux_map newmap; | 2071 | struct selinux_map newmap; |
| 2072 | struct sidtab_convert_params convert_params; | ||
| 2111 | struct convert_context_args args; | 2073 | struct convert_context_args args; |
| 2112 | u32 seqno; | 2074 | u32 seqno; |
| 2113 | int rc = 0; | 2075 | int rc = 0; |
| @@ -2121,27 +2083,37 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len) | |||
| 2121 | newpolicydb = oldpolicydb + 1; | 2083 | newpolicydb = oldpolicydb + 1; |
| 2122 | 2084 | ||
| 2123 | policydb = &state->ss->policydb; | 2085 | policydb = &state->ss->policydb; |
| 2124 | sidtab = &state->ss->sidtab; | 2086 | |
| 2087 | newsidtab = kmalloc(sizeof(*newsidtab), GFP_KERNEL); | ||
| 2088 | if (!newsidtab) { | ||
| 2089 | rc = -ENOMEM; | ||
| 2090 | goto out; | ||
| 2091 | } | ||
| 2125 | 2092 | ||
| 2126 | if (!state->initialized) { | 2093 | if (!state->initialized) { |
| 2127 | rc = policydb_read(policydb, fp); | 2094 | rc = policydb_read(policydb, fp); |
| 2128 | if (rc) | 2095 | if (rc) { |
| 2096 | kfree(newsidtab); | ||
| 2129 | goto out; | 2097 | goto out; |
| 2098 | } | ||
| 2130 | 2099 | ||
| 2131 | policydb->len = len; | 2100 | policydb->len = len; |
| 2132 | rc = selinux_set_mapping(policydb, secclass_map, | 2101 | rc = selinux_set_mapping(policydb, secclass_map, |
| 2133 | &state->ss->map); | 2102 | &state->ss->map); |
| 2134 | if (rc) { | 2103 | if (rc) { |
| 2104 | kfree(newsidtab); | ||
| 2135 | policydb_destroy(policydb); | 2105 | policydb_destroy(policydb); |
| 2136 | goto out; | 2106 | goto out; |
| 2137 | } | 2107 | } |
| 2138 | 2108 | ||
| 2139 | rc = policydb_load_isids(policydb, sidtab); | 2109 | rc = policydb_load_isids(policydb, newsidtab); |
| 2140 | if (rc) { | 2110 | if (rc) { |
| 2111 | kfree(newsidtab); | ||
| 2141 | policydb_destroy(policydb); | 2112 | policydb_destroy(policydb); |
| 2142 | goto out; | 2113 | goto out; |
| 2143 | } | 2114 | } |
| 2144 | 2115 | ||
| 2116 | state->ss->sidtab = newsidtab; | ||
| 2145 | security_load_policycaps(state); | 2117 | security_load_policycaps(state); |
| 2146 | state->initialized = 1; | 2118 | state->initialized = 1; |
| 2147 | seqno = ++state->ss->latest_granting; | 2119 | seqno = ++state->ss->latest_granting; |
| @@ -2154,13 +2126,11 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len) | |||
| 2154 | goto out; | 2126 | goto out; |
| 2155 | } | 2127 | } |
| 2156 | 2128 | ||
| 2157 | #if 0 | ||
| 2158 | sidtab_hash_eval(sidtab, "sids"); | ||
| 2159 | #endif | ||
| 2160 | |||
| 2161 | rc = policydb_read(newpolicydb, fp); | 2129 | rc = policydb_read(newpolicydb, fp); |
| 2162 | if (rc) | 2130 | if (rc) { |
| 2131 | kfree(newsidtab); | ||
| 2163 | goto out; | 2132 | goto out; |
| 2133 | } | ||
| 2164 | 2134 | ||
| 2165 | newpolicydb->len = len; | 2135 | newpolicydb->len = len; |
| 2166 | /* If switching between different policy types, log MLS status */ | 2136 | /* If switching between different policy types, log MLS status */ |
| @@ -2169,10 +2139,11 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len) | |||
| 2169 | else if (!policydb->mls_enabled && newpolicydb->mls_enabled) | 2139 | else if (!policydb->mls_enabled && newpolicydb->mls_enabled) |
| 2170 | pr_info("SELinux: Enabling MLS support...\n"); | 2140 | pr_info("SELinux: Enabling MLS support...\n"); |
| 2171 | 2141 | ||
| 2172 | rc = policydb_load_isids(newpolicydb, &newsidtab); | 2142 | rc = policydb_load_isids(newpolicydb, newsidtab); |
| 2173 | if (rc) { | 2143 | if (rc) { |
| 2174 | pr_err("SELinux: unable to load the initial SIDs\n"); | 2144 | pr_err("SELinux: unable to load the initial SIDs\n"); |
| 2175 | policydb_destroy(newpolicydb); | 2145 | policydb_destroy(newpolicydb); |
| 2146 | kfree(newsidtab); | ||
| 2176 | goto out; | 2147 | goto out; |
| 2177 | } | 2148 | } |
| 2178 | 2149 | ||
| @@ -2186,12 +2157,7 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len) | |||
| 2186 | goto err; | 2157 | goto err; |
| 2187 | } | 2158 | } |
| 2188 | 2159 | ||
| 2189 | /* Clone the SID table. */ | 2160 | oldsidtab = state->ss->sidtab; |
| 2190 | sidtab_shutdown(sidtab); | ||
| 2191 | |||
| 2192 | rc = sidtab_map(sidtab, clone_sid, &newsidtab); | ||
| 2193 | if (rc) | ||
| 2194 | goto err; | ||
| 2195 | 2161 | ||
| 2196 | /* | 2162 | /* |
| 2197 | * Convert the internal representations of contexts | 2163 | * Convert the internal representations of contexts |
| @@ -2200,7 +2166,12 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len) | |||
| 2200 | args.state = state; | 2166 | args.state = state; |
| 2201 | args.oldp = policydb; | 2167 | args.oldp = policydb; |
| 2202 | args.newp = newpolicydb; | 2168 | args.newp = newpolicydb; |
| 2203 | rc = sidtab_map(&newsidtab, convert_context, &args); | 2169 | |
| 2170 | convert_params.func = convert_context; | ||
| 2171 | convert_params.args = &args; | ||
| 2172 | convert_params.target = newsidtab; | ||
| 2173 | |||
| 2174 | rc = sidtab_convert(oldsidtab, &convert_params); | ||
| 2204 | if (rc) { | 2175 | if (rc) { |
| 2205 | pr_err("SELinux: unable to convert the internal" | 2176 | pr_err("SELinux: unable to convert the internal" |
| 2206 | " representation of contexts in the new SID" | 2177 | " representation of contexts in the new SID" |
| @@ -2210,12 +2181,11 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len) | |||
| 2210 | 2181 | ||
| 2211 | /* Save the old policydb and SID table to free later. */ | 2182 | /* Save the old policydb and SID table to free later. */ |
| 2212 | memcpy(oldpolicydb, policydb, sizeof(*policydb)); | 2183 | memcpy(oldpolicydb, policydb, sizeof(*policydb)); |
| 2213 | sidtab_set(&oldsidtab, sidtab); | ||
| 2214 | 2184 | ||
| 2215 | /* Install the new policydb and SID table. */ | 2185 | /* Install the new policydb and SID table. */ |
| 2216 | write_lock_irq(&state->ss->policy_rwlock); | 2186 | write_lock_irq(&state->ss->policy_rwlock); |
| 2217 | memcpy(policydb, newpolicydb, sizeof(*policydb)); | 2187 | memcpy(policydb, newpolicydb, sizeof(*policydb)); |
| 2218 | sidtab_set(sidtab, &newsidtab); | 2188 | state->ss->sidtab = newsidtab; |
| 2219 | security_load_policycaps(state); | 2189 | security_load_policycaps(state); |
| 2220 | oldmapping = state->ss->map.mapping; | 2190 | oldmapping = state->ss->map.mapping; |
| 2221 | state->ss->map.mapping = newmap.mapping; | 2191 | state->ss->map.mapping = newmap.mapping; |
| @@ -2225,7 +2195,8 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len) | |||
| 2225 | 2195 | ||
| 2226 | /* Free the old policydb and SID table. */ | 2196 | /* Free the old policydb and SID table. */ |
| 2227 | policydb_destroy(oldpolicydb); | 2197 | policydb_destroy(oldpolicydb); |
| 2228 | sidtab_destroy(&oldsidtab); | 2198 | sidtab_destroy(oldsidtab); |
| 2199 | kfree(oldsidtab); | ||
| 2229 | kfree(oldmapping); | 2200 | kfree(oldmapping); |
| 2230 | 2201 | ||
| 2231 | avc_ss_reset(state->avc, seqno); | 2202 | avc_ss_reset(state->avc, seqno); |
| @@ -2239,7 +2210,8 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len) | |||
| 2239 | 2210 | ||
| 2240 | err: | 2211 | err: |
| 2241 | kfree(newmap.mapping); | 2212 | kfree(newmap.mapping); |
| 2242 | sidtab_destroy(&newsidtab); | 2213 | sidtab_destroy(newsidtab); |
| 2214 | kfree(newsidtab); | ||
| 2243 | policydb_destroy(newpolicydb); | 2215 | policydb_destroy(newpolicydb); |
| 2244 | 2216 | ||
| 2245 | out: | 2217 | out: |
| @@ -2276,7 +2248,7 @@ int security_port_sid(struct selinux_state *state, | |||
| 2276 | read_lock(&state->ss->policy_rwlock); | 2248 | read_lock(&state->ss->policy_rwlock); |
| 2277 | 2249 | ||
| 2278 | policydb = &state->ss->policydb; | 2250 | policydb = &state->ss->policydb; |
| 2279 | sidtab = &state->ss->sidtab; | 2251 | sidtab = state->ss->sidtab; |
| 2280 | 2252 | ||
| 2281 | c = policydb->ocontexts[OCON_PORT]; | 2253 | c = policydb->ocontexts[OCON_PORT]; |
| 2282 | while (c) { | 2254 | while (c) { |
| @@ -2322,7 +2294,7 @@ int security_ib_pkey_sid(struct selinux_state *state, | |||
| 2322 | read_lock(&state->ss->policy_rwlock); | 2294 | read_lock(&state->ss->policy_rwlock); |
| 2323 | 2295 | ||
| 2324 | policydb = &state->ss->policydb; | 2296 | policydb = &state->ss->policydb; |
| 2325 | sidtab = &state->ss->sidtab; | 2297 | sidtab = state->ss->sidtab; |
| 2326 | 2298 | ||
| 2327 | c = policydb->ocontexts[OCON_IBPKEY]; | 2299 | c = policydb->ocontexts[OCON_IBPKEY]; |
| 2328 | while (c) { | 2300 | while (c) { |
| @@ -2368,7 +2340,7 @@ int security_ib_endport_sid(struct selinux_state *state, | |||
| 2368 | read_lock(&state->ss->policy_rwlock); | 2340 | read_lock(&state->ss->policy_rwlock); |
| 2369 | 2341 | ||
| 2370 | policydb = &state->ss->policydb; | 2342 | policydb = &state->ss->policydb; |
| 2371 | sidtab = &state->ss->sidtab; | 2343 | sidtab = state->ss->sidtab; |
| 2372 | 2344 | ||
| 2373 | c = policydb->ocontexts[OCON_IBENDPORT]; | 2345 | c = policydb->ocontexts[OCON_IBENDPORT]; |
| 2374 | while (c) { | 2346 | while (c) { |
| @@ -2414,7 +2386,7 @@ int security_netif_sid(struct selinux_state *state, | |||
| 2414 | read_lock(&state->ss->policy_rwlock); | 2386 | read_lock(&state->ss->policy_rwlock); |
| 2415 | 2387 | ||
| 2416 | policydb = &state->ss->policydb; | 2388 | policydb = &state->ss->policydb; |
| 2417 | sidtab = &state->ss->sidtab; | 2389 | sidtab = state->ss->sidtab; |
| 2418 | 2390 | ||
| 2419 | c = policydb->ocontexts[OCON_NETIF]; | 2391 | c = policydb->ocontexts[OCON_NETIF]; |
| 2420 | while (c) { | 2392 | while (c) { |
| @@ -2479,7 +2451,7 @@ int security_node_sid(struct selinux_state *state, | |||
| 2479 | read_lock(&state->ss->policy_rwlock); | 2451 | read_lock(&state->ss->policy_rwlock); |
| 2480 | 2452 | ||
| 2481 | policydb = &state->ss->policydb; | 2453 | policydb = &state->ss->policydb; |
| 2482 | sidtab = &state->ss->sidtab; | 2454 | sidtab = state->ss->sidtab; |
| 2483 | 2455 | ||
| 2484 | switch (domain) { | 2456 | switch (domain) { |
| 2485 | case AF_INET: { | 2457 | case AF_INET: { |
| @@ -2579,7 +2551,7 @@ int security_get_user_sids(struct selinux_state *state, | |||
| 2579 | read_lock(&state->ss->policy_rwlock); | 2551 | read_lock(&state->ss->policy_rwlock); |
| 2580 | 2552 | ||
| 2581 | policydb = &state->ss->policydb; | 2553 | policydb = &state->ss->policydb; |
| 2582 | sidtab = &state->ss->sidtab; | 2554 | sidtab = state->ss->sidtab; |
| 2583 | 2555 | ||
| 2584 | context_init(&usercon); | 2556 | context_init(&usercon); |
| 2585 | 2557 | ||
| @@ -2681,7 +2653,7 @@ static inline int __security_genfs_sid(struct selinux_state *state, | |||
| 2681 | u32 *sid) | 2653 | u32 *sid) |
| 2682 | { | 2654 | { |
| 2683 | struct policydb *policydb = &state->ss->policydb; | 2655 | struct policydb *policydb = &state->ss->policydb; |
| 2684 | struct sidtab *sidtab = &state->ss->sidtab; | 2656 | struct sidtab *sidtab = state->ss->sidtab; |
| 2685 | int len; | 2657 | int len; |
| 2686 | u16 sclass; | 2658 | u16 sclass; |
| 2687 | struct genfs *genfs; | 2659 | struct genfs *genfs; |
| @@ -2767,7 +2739,7 @@ int security_fs_use(struct selinux_state *state, struct super_block *sb) | |||
| 2767 | read_lock(&state->ss->policy_rwlock); | 2739 | read_lock(&state->ss->policy_rwlock); |
| 2768 | 2740 | ||
| 2769 | policydb = &state->ss->policydb; | 2741 | policydb = &state->ss->policydb; |
| 2770 | sidtab = &state->ss->sidtab; | 2742 | sidtab = state->ss->sidtab; |
| 2771 | 2743 | ||
| 2772 | c = policydb->ocontexts[OCON_FSUSE]; | 2744 | c = policydb->ocontexts[OCON_FSUSE]; |
| 2773 | while (c) { | 2745 | while (c) { |
| @@ -2973,7 +2945,7 @@ int security_sid_mls_copy(struct selinux_state *state, | |||
| 2973 | u32 sid, u32 mls_sid, u32 *new_sid) | 2945 | u32 sid, u32 mls_sid, u32 *new_sid) |
| 2974 | { | 2946 | { |
| 2975 | struct policydb *policydb = &state->ss->policydb; | 2947 | struct policydb *policydb = &state->ss->policydb; |
| 2976 | struct sidtab *sidtab = &state->ss->sidtab; | 2948 | struct sidtab *sidtab = state->ss->sidtab; |
| 2977 | struct context *context1; | 2949 | struct context *context1; |
| 2978 | struct context *context2; | 2950 | struct context *context2; |
| 2979 | struct context newcon; | 2951 | struct context newcon; |
| @@ -3064,7 +3036,7 @@ int security_net_peersid_resolve(struct selinux_state *state, | |||
| 3064 | u32 *peer_sid) | 3036 | u32 *peer_sid) |
| 3065 | { | 3037 | { |
| 3066 | struct policydb *policydb = &state->ss->policydb; | 3038 | struct policydb *policydb = &state->ss->policydb; |
| 3067 | struct sidtab *sidtab = &state->ss->sidtab; | 3039 | struct sidtab *sidtab = state->ss->sidtab; |
| 3068 | int rc; | 3040 | int rc; |
| 3069 | struct context *nlbl_ctx; | 3041 | struct context *nlbl_ctx; |
| 3070 | struct context *xfrm_ctx; | 3042 | struct context *xfrm_ctx; |
| @@ -3425,7 +3397,7 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule, | |||
| 3425 | goto out; | 3397 | goto out; |
| 3426 | } | 3398 | } |
| 3427 | 3399 | ||
| 3428 | ctxt = sidtab_search(&state->ss->sidtab, sid); | 3400 | ctxt = sidtab_search(state->ss->sidtab, sid); |
| 3429 | if (unlikely(!ctxt)) { | 3401 | if (unlikely(!ctxt)) { |
| 3430 | WARN_ONCE(1, "selinux_audit_rule_match: unrecognized SID %d\n", | 3402 | WARN_ONCE(1, "selinux_audit_rule_match: unrecognized SID %d\n", |
| 3431 | sid); | 3403 | sid); |
| @@ -3588,7 +3560,7 @@ int security_netlbl_secattr_to_sid(struct selinux_state *state, | |||
| 3588 | u32 *sid) | 3560 | u32 *sid) |
| 3589 | { | 3561 | { |
| 3590 | struct policydb *policydb = &state->ss->policydb; | 3562 | struct policydb *policydb = &state->ss->policydb; |
| 3591 | struct sidtab *sidtab = &state->ss->sidtab; | 3563 | struct sidtab *sidtab = state->ss->sidtab; |
| 3592 | int rc; | 3564 | int rc; |
| 3593 | struct context *ctx; | 3565 | struct context *ctx; |
| 3594 | struct context ctx_new; | 3566 | struct context ctx_new; |
| @@ -3666,7 +3638,7 @@ int security_netlbl_sid_to_secattr(struct selinux_state *state, | |||
| 3666 | read_lock(&state->ss->policy_rwlock); | 3638 | read_lock(&state->ss->policy_rwlock); |
| 3667 | 3639 | ||
| 3668 | rc = -ENOENT; | 3640 | rc = -ENOENT; |
| 3669 | ctx = sidtab_search(&state->ss->sidtab, sid); | 3641 | ctx = sidtab_search(state->ss->sidtab, sid); |
| 3670 | if (ctx == NULL) | 3642 | if (ctx == NULL) |
| 3671 | goto out; | 3643 | goto out; |
| 3672 | 3644 | ||
