diff options
Diffstat (limited to 'security/selinux')
-rw-r--r-- | security/selinux/ss/policydb.c | 244 |
1 files changed, 133 insertions, 111 deletions
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index 4ea073eaf8bf..674ddfe0ba03 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c | |||
@@ -1901,6 +1901,136 @@ out: | |||
1901 | return rc; | 1901 | return rc; |
1902 | } | 1902 | } |
1903 | 1903 | ||
1904 | static int ocontext_read(struct policydb *p, struct policydb_compat_info *info, | ||
1905 | void *fp) | ||
1906 | { | ||
1907 | int i, j, rc; | ||
1908 | u32 nel, len; | ||
1909 | __le32 buf[3]; | ||
1910 | struct ocontext *l, *c; | ||
1911 | u32 nodebuf[8]; | ||
1912 | |||
1913 | for (i = 0; i < info->ocon_num; i++) { | ||
1914 | rc = next_entry(buf, fp, sizeof(u32)); | ||
1915 | if (rc) | ||
1916 | goto out; | ||
1917 | nel = le32_to_cpu(buf[0]); | ||
1918 | |||
1919 | l = NULL; | ||
1920 | for (j = 0; j < nel; j++) { | ||
1921 | rc = -ENOMEM; | ||
1922 | c = kzalloc(sizeof(*c), GFP_KERNEL); | ||
1923 | if (!c) | ||
1924 | goto out; | ||
1925 | if (l) | ||
1926 | l->next = c; | ||
1927 | else | ||
1928 | p->ocontexts[i] = c; | ||
1929 | l = c; | ||
1930 | |||
1931 | switch (i) { | ||
1932 | case OCON_ISID: | ||
1933 | rc = next_entry(buf, fp, sizeof(u32)); | ||
1934 | if (rc) | ||
1935 | goto out; | ||
1936 | |||
1937 | c->sid[0] = le32_to_cpu(buf[0]); | ||
1938 | rc = context_read_and_validate(&c->context[0], p, fp); | ||
1939 | if (rc) | ||
1940 | goto out; | ||
1941 | break; | ||
1942 | case OCON_FS: | ||
1943 | case OCON_NETIF: | ||
1944 | rc = next_entry(buf, fp, sizeof(u32)); | ||
1945 | if (rc) | ||
1946 | goto out; | ||
1947 | len = le32_to_cpu(buf[0]); | ||
1948 | |||
1949 | rc = -ENOMEM; | ||
1950 | c->u.name = kmalloc(len + 1, GFP_KERNEL); | ||
1951 | if (!c->u.name) | ||
1952 | goto out; | ||
1953 | |||
1954 | rc = next_entry(c->u.name, fp, len); | ||
1955 | if (rc) | ||
1956 | goto out; | ||
1957 | |||
1958 | c->u.name[len] = 0; | ||
1959 | rc = context_read_and_validate(&c->context[0], p, fp); | ||
1960 | if (rc) | ||
1961 | goto out; | ||
1962 | rc = context_read_and_validate(&c->context[1], p, fp); | ||
1963 | if (rc) | ||
1964 | goto out; | ||
1965 | break; | ||
1966 | case OCON_PORT: | ||
1967 | rc = next_entry(buf, fp, sizeof(u32)*3); | ||
1968 | if (rc) | ||
1969 | goto out; | ||
1970 | c->u.port.protocol = le32_to_cpu(buf[0]); | ||
1971 | c->u.port.low_port = le32_to_cpu(buf[1]); | ||
1972 | c->u.port.high_port = le32_to_cpu(buf[2]); | ||
1973 | rc = context_read_and_validate(&c->context[0], p, fp); | ||
1974 | if (rc) | ||
1975 | goto out; | ||
1976 | break; | ||
1977 | case OCON_NODE: | ||
1978 | rc = next_entry(nodebuf, fp, sizeof(u32) * 2); | ||
1979 | if (rc) | ||
1980 | goto out; | ||
1981 | c->u.node.addr = nodebuf[0]; /* network order */ | ||
1982 | c->u.node.mask = nodebuf[1]; /* network order */ | ||
1983 | rc = context_read_and_validate(&c->context[0], p, fp); | ||
1984 | if (rc) | ||
1985 | goto out; | ||
1986 | break; | ||
1987 | case OCON_FSUSE: | ||
1988 | rc = next_entry(buf, fp, sizeof(u32)*2); | ||
1989 | if (rc) | ||
1990 | goto out; | ||
1991 | |||
1992 | rc = -EINVAL; | ||
1993 | c->v.behavior = le32_to_cpu(buf[0]); | ||
1994 | if (c->v.behavior > SECURITY_FS_USE_NONE) | ||
1995 | goto out; | ||
1996 | |||
1997 | rc = -ENOMEM; | ||
1998 | len = le32_to_cpu(buf[1]); | ||
1999 | c->u.name = kmalloc(len + 1, GFP_KERNEL); | ||
2000 | if (!c->u.name) | ||
2001 | goto out; | ||
2002 | |||
2003 | rc = next_entry(c->u.name, fp, len); | ||
2004 | if (rc) | ||
2005 | goto out; | ||
2006 | c->u.name[len] = 0; | ||
2007 | rc = context_read_and_validate(&c->context[0], p, fp); | ||
2008 | if (rc) | ||
2009 | goto out; | ||
2010 | break; | ||
2011 | case OCON_NODE6: { | ||
2012 | int k; | ||
2013 | |||
2014 | rc = next_entry(nodebuf, fp, sizeof(u32) * 8); | ||
2015 | if (rc) | ||
2016 | goto out; | ||
2017 | for (k = 0; k < 4; k++) | ||
2018 | c->u.node6.addr[k] = nodebuf[k]; | ||
2019 | for (k = 0; k < 4; k++) | ||
2020 | c->u.node6.mask[k] = nodebuf[k+4]; | ||
2021 | rc = context_read_and_validate(&c->context[0], p, fp); | ||
2022 | if (rc) | ||
2023 | goto out; | ||
2024 | break; | ||
2025 | } | ||
2026 | } | ||
2027 | } | ||
2028 | } | ||
2029 | rc = 0; | ||
2030 | out: | ||
2031 | return rc; | ||
2032 | } | ||
2033 | |||
1904 | /* | 2034 | /* |
1905 | * Read the configuration data from a policy database binary | 2035 | * Read the configuration data from a policy database binary |
1906 | * representation file into a policy database structure. | 2036 | * representation file into a policy database structure. |
@@ -1909,10 +2039,8 @@ int policydb_read(struct policydb *p, void *fp) | |||
1909 | { | 2039 | { |
1910 | struct role_allow *ra, *lra; | 2040 | struct role_allow *ra, *lra; |
1911 | struct role_trans *tr, *ltr; | 2041 | struct role_trans *tr, *ltr; |
1912 | struct ocontext *l, *c; | ||
1913 | int i, j, rc; | 2042 | int i, j, rc; |
1914 | __le32 buf[4]; | 2043 | __le32 buf[4]; |
1915 | u32 nodebuf[8]; | ||
1916 | u32 len, nprim, nel; | 2044 | u32 len, nprim, nel; |
1917 | 2045 | ||
1918 | char *policydb_str; | 2046 | char *policydb_str; |
@@ -2117,115 +2245,9 @@ int policydb_read(struct policydb *p, void *fp) | |||
2117 | if (!p->process_trans_perms) | 2245 | if (!p->process_trans_perms) |
2118 | goto bad; | 2246 | goto bad; |
2119 | 2247 | ||
2120 | for (i = 0; i < info->ocon_num; i++) { | 2248 | rc = ocontext_read(p, info, fp); |
2121 | rc = next_entry(buf, fp, sizeof(u32)); | 2249 | if (rc) |
2122 | if (rc < 0) | 2250 | goto bad; |
2123 | goto bad; | ||
2124 | nel = le32_to_cpu(buf[0]); | ||
2125 | l = NULL; | ||
2126 | for (j = 0; j < nel; j++) { | ||
2127 | c = kzalloc(sizeof(*c), GFP_KERNEL); | ||
2128 | if (!c) { | ||
2129 | rc = -ENOMEM; | ||
2130 | goto bad; | ||
2131 | } | ||
2132 | if (l) | ||
2133 | l->next = c; | ||
2134 | else | ||
2135 | p->ocontexts[i] = c; | ||
2136 | l = c; | ||
2137 | rc = -EINVAL; | ||
2138 | switch (i) { | ||
2139 | case OCON_ISID: | ||
2140 | rc = next_entry(buf, fp, sizeof(u32)); | ||
2141 | if (rc < 0) | ||
2142 | goto bad; | ||
2143 | c->sid[0] = le32_to_cpu(buf[0]); | ||
2144 | rc = context_read_and_validate(&c->context[0], p, fp); | ||
2145 | if (rc) | ||
2146 | goto bad; | ||
2147 | break; | ||
2148 | case OCON_FS: | ||
2149 | case OCON_NETIF: | ||
2150 | rc = next_entry(buf, fp, sizeof(u32)); | ||
2151 | if (rc < 0) | ||
2152 | goto bad; | ||
2153 | len = le32_to_cpu(buf[0]); | ||
2154 | c->u.name = kmalloc(len + 1, GFP_KERNEL); | ||
2155 | if (!c->u.name) { | ||
2156 | rc = -ENOMEM; | ||
2157 | goto bad; | ||
2158 | } | ||
2159 | rc = next_entry(c->u.name, fp, len); | ||
2160 | if (rc < 0) | ||
2161 | goto bad; | ||
2162 | c->u.name[len] = 0; | ||
2163 | rc = context_read_and_validate(&c->context[0], p, fp); | ||
2164 | if (rc) | ||
2165 | goto bad; | ||
2166 | rc = context_read_and_validate(&c->context[1], p, fp); | ||
2167 | if (rc) | ||
2168 | goto bad; | ||
2169 | break; | ||
2170 | case OCON_PORT: | ||
2171 | rc = next_entry(buf, fp, sizeof(u32)*3); | ||
2172 | if (rc < 0) | ||
2173 | goto bad; | ||
2174 | c->u.port.protocol = le32_to_cpu(buf[0]); | ||
2175 | c->u.port.low_port = le32_to_cpu(buf[1]); | ||
2176 | c->u.port.high_port = le32_to_cpu(buf[2]); | ||
2177 | rc = context_read_and_validate(&c->context[0], p, fp); | ||
2178 | if (rc) | ||
2179 | goto bad; | ||
2180 | break; | ||
2181 | case OCON_NODE: | ||
2182 | rc = next_entry(nodebuf, fp, sizeof(u32) * 2); | ||
2183 | if (rc < 0) | ||
2184 | goto bad; | ||
2185 | c->u.node.addr = nodebuf[0]; /* network order */ | ||
2186 | c->u.node.mask = nodebuf[1]; /* network order */ | ||
2187 | rc = context_read_and_validate(&c->context[0], p, fp); | ||
2188 | if (rc) | ||
2189 | goto bad; | ||
2190 | break; | ||
2191 | case OCON_FSUSE: | ||
2192 | rc = next_entry(buf, fp, sizeof(u32)*2); | ||
2193 | if (rc < 0) | ||
2194 | goto bad; | ||
2195 | c->v.behavior = le32_to_cpu(buf[0]); | ||
2196 | if (c->v.behavior > SECURITY_FS_USE_NONE) | ||
2197 | goto bad; | ||
2198 | len = le32_to_cpu(buf[1]); | ||
2199 | c->u.name = kmalloc(len + 1, GFP_KERNEL); | ||
2200 | if (!c->u.name) { | ||
2201 | rc = -ENOMEM; | ||
2202 | goto bad; | ||
2203 | } | ||
2204 | rc = next_entry(c->u.name, fp, len); | ||
2205 | if (rc < 0) | ||
2206 | goto bad; | ||
2207 | c->u.name[len] = 0; | ||
2208 | rc = context_read_and_validate(&c->context[0], p, fp); | ||
2209 | if (rc) | ||
2210 | goto bad; | ||
2211 | break; | ||
2212 | case OCON_NODE6: { | ||
2213 | int k; | ||
2214 | |||
2215 | rc = next_entry(nodebuf, fp, sizeof(u32) * 8); | ||
2216 | if (rc < 0) | ||
2217 | goto bad; | ||
2218 | for (k = 0; k < 4; k++) | ||
2219 | c->u.node6.addr[k] = nodebuf[k]; | ||
2220 | for (k = 0; k < 4; k++) | ||
2221 | c->u.node6.mask[k] = nodebuf[k+4]; | ||
2222 | if (context_read_and_validate(&c->context[0], p, fp)) | ||
2223 | goto bad; | ||
2224 | break; | ||
2225 | } | ||
2226 | } | ||
2227 | } | ||
2228 | } | ||
2229 | 2251 | ||
2230 | rc = genfs_read(p, fp); | 2252 | rc = genfs_read(p, fp); |
2231 | if (rc) | 2253 | if (rc) |