diff options
Diffstat (limited to 'security/selinux/ss/policydb.c')
| -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) |
