diff options
Diffstat (limited to 'security/selinux/ss')
-rw-r--r-- | security/selinux/ss/policydb.c | 18 | ||||
-rw-r--r-- | security/selinux/ss/policydb.h | 2 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 67 |
3 files changed, 85 insertions, 2 deletions
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index b582aae3c62c..bd7d6a00342d 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c | |||
@@ -13,6 +13,11 @@ | |||
13 | * | 13 | * |
14 | * Added conditional policy language extensions | 14 | * Added conditional policy language extensions |
15 | * | 15 | * |
16 | * Updated: Hewlett-Packard <paul.moore@hp.com> | ||
17 | * | ||
18 | * Added support for the policy capability bitmap | ||
19 | * | ||
20 | * Copyright (C) 2007 Hewlett-Packard Development Company, L.P. | ||
16 | * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. | 21 | * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. |
17 | * Copyright (C) 2003 - 2004 Tresys Technology, LLC | 22 | * Copyright (C) 2003 - 2004 Tresys Technology, LLC |
18 | * This program is free software; you can redistribute it and/or modify | 23 | * This program is free software; you can redistribute it and/or modify |
@@ -102,6 +107,11 @@ static struct policydb_compat_info policydb_compat[] = { | |||
102 | .sym_num = SYM_NUM, | 107 | .sym_num = SYM_NUM, |
103 | .ocon_num = OCON_NUM, | 108 | .ocon_num = OCON_NUM, |
104 | }, | 109 | }, |
110 | { | ||
111 | .version = POLICYDB_VERSION_POLCAP, | ||
112 | .sym_num = SYM_NUM, | ||
113 | .ocon_num = OCON_NUM, | ||
114 | } | ||
105 | }; | 115 | }; |
106 | 116 | ||
107 | static struct policydb_compat_info *policydb_lookup_compat(int version) | 117 | static struct policydb_compat_info *policydb_lookup_compat(int version) |
@@ -183,6 +193,8 @@ static int policydb_init(struct policydb *p) | |||
183 | if (rc) | 193 | if (rc) |
184 | goto out_free_symtab; | 194 | goto out_free_symtab; |
185 | 195 | ||
196 | ebitmap_init(&p->policycaps); | ||
197 | |||
186 | out: | 198 | out: |
187 | return rc; | 199 | return rc; |
188 | 200 | ||
@@ -673,8 +685,8 @@ void policydb_destroy(struct policydb *p) | |||
673 | ebitmap_destroy(&p->type_attr_map[i]); | 685 | ebitmap_destroy(&p->type_attr_map[i]); |
674 | } | 686 | } |
675 | kfree(p->type_attr_map); | 687 | kfree(p->type_attr_map); |
676 | |||
677 | kfree(p->undefined_perms); | 688 | kfree(p->undefined_perms); |
689 | ebitmap_destroy(&p->policycaps); | ||
678 | 690 | ||
679 | return; | 691 | return; |
680 | } | 692 | } |
@@ -1554,6 +1566,10 @@ int policydb_read(struct policydb *p, void *fp) | |||
1554 | p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN); | 1566 | p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN); |
1555 | p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN); | 1567 | p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN); |
1556 | 1568 | ||
1569 | if (p->policyvers >= POLICYDB_VERSION_POLCAP && | ||
1570 | ebitmap_read(&p->policycaps, fp) != 0) | ||
1571 | goto bad; | ||
1572 | |||
1557 | info = policydb_lookup_compat(p->policyvers); | 1573 | info = policydb_lookup_compat(p->policyvers); |
1558 | if (!info) { | 1574 | if (!info) { |
1559 | printk(KERN_ERR "security: unable to find policy compat info " | 1575 | printk(KERN_ERR "security: unable to find policy compat info " |
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h index ed6fc687c66f..c4ce996e202c 100644 --- a/security/selinux/ss/policydb.h +++ b/security/selinux/ss/policydb.h | |||
@@ -241,6 +241,8 @@ struct policydb { | |||
241 | /* type -> attribute reverse mapping */ | 241 | /* type -> attribute reverse mapping */ |
242 | struct ebitmap *type_attr_map; | 242 | struct ebitmap *type_attr_map; |
243 | 243 | ||
244 | struct ebitmap policycaps; | ||
245 | |||
244 | unsigned int policyvers; | 246 | unsigned int policyvers; |
245 | 247 | ||
246 | unsigned int reject_unknown : 1; | 248 | unsigned int reject_unknown : 1; |
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 8dfaa3e7c26d..8ee04a424df7 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -16,12 +16,13 @@ | |||
16 | * Updated: Hewlett-Packard <paul.moore@hp.com> | 16 | * Updated: Hewlett-Packard <paul.moore@hp.com> |
17 | * | 17 | * |
18 | * Added support for NetLabel | 18 | * Added support for NetLabel |
19 | * Added support for the policy capability bitmap | ||
19 | * | 20 | * |
20 | * Updated: Chad Sellers <csellers@tresys.com> | 21 | * Updated: Chad Sellers <csellers@tresys.com> |
21 | * | 22 | * |
22 | * Added validation of kernel classes and permissions | 23 | * Added validation of kernel classes and permissions |
23 | * | 24 | * |
24 | * Copyright (C) 2006 Hewlett-Packard Development Company, L.P. | 25 | * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P. |
25 | * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. | 26 | * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. |
26 | * Copyright (C) 2003 - 2004, 2006 Tresys Technology, LLC | 27 | * Copyright (C) 2003 - 2004, 2006 Tresys Technology, LLC |
27 | * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> | 28 | * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> |
@@ -59,6 +60,8 @@ | |||
59 | extern void selnl_notify_policyload(u32 seqno); | 60 | extern void selnl_notify_policyload(u32 seqno); |
60 | unsigned int policydb_loaded_version; | 61 | unsigned int policydb_loaded_version; |
61 | 62 | ||
63 | int selinux_policycap_netpeer; | ||
64 | |||
62 | /* | 65 | /* |
63 | * This is declared in avc.c | 66 | * This is declared in avc.c |
64 | */ | 67 | */ |
@@ -1299,6 +1302,12 @@ bad: | |||
1299 | goto out; | 1302 | goto out; |
1300 | } | 1303 | } |
1301 | 1304 | ||
1305 | static void security_load_policycaps(void) | ||
1306 | { | ||
1307 | selinux_policycap_netpeer = ebitmap_get_bit(&policydb.policycaps, | ||
1308 | POLICYDB_CAPABILITY_NETPEER); | ||
1309 | } | ||
1310 | |||
1302 | extern void selinux_complete_init(void); | 1311 | extern void selinux_complete_init(void); |
1303 | static int security_preserve_bools(struct policydb *p); | 1312 | static int security_preserve_bools(struct policydb *p); |
1304 | 1313 | ||
@@ -1346,6 +1355,7 @@ int security_load_policy(void *data, size_t len) | |||
1346 | avtab_cache_destroy(); | 1355 | avtab_cache_destroy(); |
1347 | return -EINVAL; | 1356 | return -EINVAL; |
1348 | } | 1357 | } |
1358 | security_load_policycaps(); | ||
1349 | policydb_loaded_version = policydb.policyvers; | 1359 | policydb_loaded_version = policydb.policyvers; |
1350 | ss_initialized = 1; | 1360 | ss_initialized = 1; |
1351 | seqno = ++latest_granting; | 1361 | seqno = ++latest_granting; |
@@ -1404,6 +1414,7 @@ int security_load_policy(void *data, size_t len) | |||
1404 | POLICY_WRLOCK; | 1414 | POLICY_WRLOCK; |
1405 | memcpy(&policydb, &newpolicydb, sizeof policydb); | 1415 | memcpy(&policydb, &newpolicydb, sizeof policydb); |
1406 | sidtab_set(&sidtab, &newsidtab); | 1416 | sidtab_set(&sidtab, &newsidtab); |
1417 | security_load_policycaps(); | ||
1407 | seqno = ++latest_granting; | 1418 | seqno = ++latest_granting; |
1408 | policydb_loaded_version = policydb.policyvers; | 1419 | policydb_loaded_version = policydb.policyvers; |
1409 | POLICY_WRUNLOCK; | 1420 | POLICY_WRUNLOCK; |
@@ -2148,6 +2159,60 @@ int security_get_allow_unknown(void) | |||
2148 | return policydb.allow_unknown; | 2159 | return policydb.allow_unknown; |
2149 | } | 2160 | } |
2150 | 2161 | ||
2162 | /** | ||
2163 | * security_get_policycaps - Query the loaded policy for its capabilities | ||
2164 | * @len: the number of capability bits | ||
2165 | * @values: the capability bit array | ||
2166 | * | ||
2167 | * Description: | ||
2168 | * Get an array of the policy capabilities in @values where each entry in | ||
2169 | * @values is either true (1) or false (0) depending the policy's support of | ||
2170 | * that feature. The policy capabilities are defined by the | ||
2171 | * POLICYDB_CAPABILITY_* enums. The size of the array is stored in @len and it | ||
2172 | * is up to the caller to free the array in @values. Returns zero on success, | ||
2173 | * negative values on failure. | ||
2174 | * | ||
2175 | */ | ||
2176 | int security_get_policycaps(int *len, int **values) | ||
2177 | { | ||
2178 | int rc = -ENOMEM; | ||
2179 | unsigned int iter; | ||
2180 | |||
2181 | POLICY_RDLOCK; | ||
2182 | |||
2183 | *values = kcalloc(POLICYDB_CAPABILITY_MAX, sizeof(int), GFP_ATOMIC); | ||
2184 | if (*values == NULL) | ||
2185 | goto out; | ||
2186 | for (iter = 0; iter < POLICYDB_CAPABILITY_MAX; iter++) | ||
2187 | (*values)[iter] = ebitmap_get_bit(&policydb.policycaps, iter); | ||
2188 | *len = POLICYDB_CAPABILITY_MAX; | ||
2189 | |||
2190 | out: | ||
2191 | POLICY_RDUNLOCK; | ||
2192 | return rc; | ||
2193 | } | ||
2194 | |||
2195 | /** | ||
2196 | * security_policycap_supported - Check for a specific policy capability | ||
2197 | * @req_cap: capability | ||
2198 | * | ||
2199 | * Description: | ||
2200 | * This function queries the currently loaded policy to see if it supports the | ||
2201 | * capability specified by @req_cap. Returns true (1) if the capability is | ||
2202 | * supported, false (0) if it isn't supported. | ||
2203 | * | ||
2204 | */ | ||
2205 | int security_policycap_supported(unsigned int req_cap) | ||
2206 | { | ||
2207 | int rc; | ||
2208 | |||
2209 | POLICY_RDLOCK; | ||
2210 | rc = ebitmap_get_bit(&policydb.policycaps, req_cap); | ||
2211 | POLICY_RDUNLOCK; | ||
2212 | |||
2213 | return rc; | ||
2214 | } | ||
2215 | |||
2151 | struct selinux_audit_rule { | 2216 | struct selinux_audit_rule { |
2152 | u32 au_seqno; | 2217 | u32 au_seqno; |
2153 | struct context au_ctxt; | 2218 | struct context au_ctxt; |