aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss
diff options
context:
space:
mode:
authorPaul Moore <pmoore@redhat.com>2013-09-18 13:52:20 -0400
committerPaul Moore <pmoore@redhat.com>2013-09-18 13:52:20 -0400
commit98f700f317967d45cf60c9843b3c42ce3c286f7c (patch)
tree2e68b189ceb954182af56b8f6febe644119b7cd7 /security/selinux/ss
parent6e4664525b1db28f8c4e1130957f70a94c19213e (diff)
parent0b4bdb3573a86a88c829b9e4ad702859eb923e7e (diff)
Merge git://git.infradead.org/users/eparis/selinux
Conflicts: security/selinux/hooks.c Pull Eric's existing SELinux tree as there are a number of patches in there that are not yet upstream. There was some minor fixup needed to resolve a conflict in security/selinux/hooks.c:selinux_set_mnt_opts() between the labeled NFS patches and Eric's security_fs_use() simplification patch.
Diffstat (limited to 'security/selinux/ss')
-rw-r--r--security/selinux/ss/ebitmap.c20
-rw-r--r--security/selinux/ss/ebitmap.h10
-rw-r--r--security/selinux/ss/mls.c22
-rw-r--r--security/selinux/ss/mls_types.h2
-rw-r--r--security/selinux/ss/policydb.c3
-rw-r--r--security/selinux/ss/services.c66
6 files changed, 85 insertions, 38 deletions
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c
index 30f119b1d1ec..820313a04d49 100644
--- a/security/selinux/ss/ebitmap.c
+++ b/security/selinux/ss/ebitmap.c
@@ -213,7 +213,12 @@ netlbl_import_failure:
213} 213}
214#endif /* CONFIG_NETLABEL */ 214#endif /* CONFIG_NETLABEL */
215 215
216int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2) 216/*
217 * Check to see if all the bits set in e2 are also set in e1. Optionally,
218 * if last_e2bit is non-zero, the highest set bit in e2 cannot exceed
219 * last_e2bit.
220 */
221int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2, u32 last_e2bit)
217{ 222{
218 struct ebitmap_node *n1, *n2; 223 struct ebitmap_node *n1, *n2;
219 int i; 224 int i;
@@ -223,14 +228,25 @@ int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2)
223 228
224 n1 = e1->node; 229 n1 = e1->node;
225 n2 = e2->node; 230 n2 = e2->node;
231
226 while (n1 && n2 && (n1->startbit <= n2->startbit)) { 232 while (n1 && n2 && (n1->startbit <= n2->startbit)) {
227 if (n1->startbit < n2->startbit) { 233 if (n1->startbit < n2->startbit) {
228 n1 = n1->next; 234 n1 = n1->next;
229 continue; 235 continue;
230 } 236 }
231 for (i = 0; i < EBITMAP_UNIT_NUMS; i++) { 237 for (i = EBITMAP_UNIT_NUMS - 1; (i >= 0) && !n2->maps[i]; )
238 i--; /* Skip trailing NULL map entries */
239 if (last_e2bit && (i >= 0)) {
240 u32 lastsetbit = n2->startbit + i * EBITMAP_UNIT_SIZE +
241 __fls(n2->maps[i]);
242 if (lastsetbit > last_e2bit)
243 return 0;
244 }
245
246 while (i >= 0) {
232 if ((n1->maps[i] & n2->maps[i]) != n2->maps[i]) 247 if ((n1->maps[i] & n2->maps[i]) != n2->maps[i])
233 return 0; 248 return 0;
249 i--;
234 } 250 }
235 251
236 n1 = n1->next; 252 n1 = n1->next;
diff --git a/security/selinux/ss/ebitmap.h b/security/selinux/ss/ebitmap.h
index 922f8afa89dd..712c8a7b8e8b 100644
--- a/security/selinux/ss/ebitmap.h
+++ b/security/selinux/ss/ebitmap.h
@@ -16,7 +16,13 @@
16 16
17#include <net/netlabel.h> 17#include <net/netlabel.h>
18 18
19#define EBITMAP_UNIT_NUMS ((32 - sizeof(void *) - sizeof(u32)) \ 19#ifdef CONFIG_64BIT
20#define EBITMAP_NODE_SIZE 64
21#else
22#define EBITMAP_NODE_SIZE 32
23#endif
24
25#define EBITMAP_UNIT_NUMS ((EBITMAP_NODE_SIZE-sizeof(void *)-sizeof(u32))\
20 / sizeof(unsigned long)) 26 / sizeof(unsigned long))
21#define EBITMAP_UNIT_SIZE BITS_PER_LONG 27#define EBITMAP_UNIT_SIZE BITS_PER_LONG
22#define EBITMAP_SIZE (EBITMAP_UNIT_NUMS * EBITMAP_UNIT_SIZE) 28#define EBITMAP_SIZE (EBITMAP_UNIT_NUMS * EBITMAP_UNIT_SIZE)
@@ -117,7 +123,7 @@ static inline void ebitmap_node_clr_bit(struct ebitmap_node *n,
117 123
118int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2); 124int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2);
119int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src); 125int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src);
120int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2); 126int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2, u32 last_e2bit);
121int ebitmap_get_bit(struct ebitmap *e, unsigned long bit); 127int ebitmap_get_bit(struct ebitmap *e, unsigned long bit);
122int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value); 128int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value);
123void ebitmap_destroy(struct ebitmap *e); 129void ebitmap_destroy(struct ebitmap *e);
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index 40de8d3f208e..c85bc1ec040c 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -160,8 +160,6 @@ void mls_sid_to_context(struct context *context,
160int mls_level_isvalid(struct policydb *p, struct mls_level *l) 160int mls_level_isvalid(struct policydb *p, struct mls_level *l)
161{ 161{
162 struct level_datum *levdatum; 162 struct level_datum *levdatum;
163 struct ebitmap_node *node;
164 int i;
165 163
166 if (!l->sens || l->sens > p->p_levels.nprim) 164 if (!l->sens || l->sens > p->p_levels.nprim)
167 return 0; 165 return 0;
@@ -170,19 +168,13 @@ int mls_level_isvalid(struct policydb *p, struct mls_level *l)
170 if (!levdatum) 168 if (!levdatum)
171 return 0; 169 return 0;
172 170
173 ebitmap_for_each_positive_bit(&l->cat, node, i) { 171 /*
174 if (i > p->p_cats.nprim) 172 * Return 1 iff all the bits set in l->cat are also be set in
175 return 0; 173 * levdatum->level->cat and no bit in l->cat is larger than
176 if (!ebitmap_get_bit(&levdatum->level->cat, i)) { 174 * p->p_cats.nprim.
177 /* 175 */
178 * Category may not be associated with 176 return ebitmap_contains(&levdatum->level->cat, &l->cat,
179 * sensitivity. 177 p->p_cats.nprim);
180 */
181 return 0;
182 }
183 }
184
185 return 1;
186} 178}
187 179
188int mls_range_isvalid(struct policydb *p, struct mls_range *r) 180int mls_range_isvalid(struct policydb *p, struct mls_range *r)
diff --git a/security/selinux/ss/mls_types.h b/security/selinux/ss/mls_types.h
index 03bed52a8052..e93648774137 100644
--- a/security/selinux/ss/mls_types.h
+++ b/security/selinux/ss/mls_types.h
@@ -35,7 +35,7 @@ static inline int mls_level_eq(struct mls_level *l1, struct mls_level *l2)
35static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2) 35static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2)
36{ 36{
37 return ((l1->sens >= l2->sens) && 37 return ((l1->sens >= l2->sens) &&
38 ebitmap_contains(&l1->cat, &l2->cat)); 38 ebitmap_contains(&l1->cat, &l2->cat, 0));
39} 39}
40 40
41#define mls_level_incomp(l1, l2) \ 41#define mls_level_incomp(l1, l2) \
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index c8adde3aff8f..f6195ebde3c9 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -3203,9 +3203,8 @@ static int range_write_helper(void *key, void *data, void *ptr)
3203 3203
3204static int range_write(struct policydb *p, void *fp) 3204static int range_write(struct policydb *p, void *fp)
3205{ 3205{
3206 size_t nel;
3207 __le32 buf[1]; 3206 __le32 buf[1];
3208 int rc; 3207 int rc, nel;
3209 struct policy_data pd; 3208 struct policy_data pd;
3210 3209
3211 pd.p = p; 3210 pd.p = p;
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index b4feecc3fe01..ee470a0b5c27 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -72,6 +72,7 @@
72 72
73int selinux_policycap_netpeer; 73int selinux_policycap_netpeer;
74int selinux_policycap_openperm; 74int selinux_policycap_openperm;
75int selinux_policycap_alwaysnetwork;
75 76
76static DEFINE_RWLOCK(policy_rwlock); 77static DEFINE_RWLOCK(policy_rwlock);
77 78
@@ -1812,6 +1813,8 @@ static void security_load_policycaps(void)
1812 POLICYDB_CAPABILITY_NETPEER); 1813 POLICYDB_CAPABILITY_NETPEER);
1813 selinux_policycap_openperm = ebitmap_get_bit(&policydb.policycaps, 1814 selinux_policycap_openperm = ebitmap_get_bit(&policydb.policycaps,
1814 POLICYDB_CAPABILITY_OPENPERM); 1815 POLICYDB_CAPABILITY_OPENPERM);
1816 selinux_policycap_alwaysnetwork = ebitmap_get_bit(&policydb.policycaps,
1817 POLICYDB_CAPABILITY_ALWAYSNETWORK);
1815} 1818}
1816 1819
1817static int security_preserve_bools(struct policydb *p); 1820static int security_preserve_bools(struct policydb *p);
@@ -2323,43 +2326,74 @@ out:
2323 2326
2324/** 2327/**
2325 * security_fs_use - Determine how to handle labeling for a filesystem. 2328 * security_fs_use - Determine how to handle labeling for a filesystem.
2326 * @fstype: filesystem type 2329 * @sb: superblock in question
2327 * @behavior: labeling behavior
2328 * @sid: SID for filesystem (superblock)
2329 */ 2330 */
2330int security_fs_use( 2331int security_fs_use(struct super_block *sb)
2331 const char *fstype,
2332 unsigned int *behavior,
2333 u32 *sid)
2334{ 2332{
2335 int rc = 0; 2333 int rc = 0;
2336 struct ocontext *c; 2334 struct ocontext *c;
2335 struct superblock_security_struct *sbsec = sb->s_security;
2336 const char *fstype = sb->s_type->name;
2337 const char *subtype = (sb->s_subtype && sb->s_subtype[0]) ? sb->s_subtype : NULL;
2338 struct ocontext *base = NULL;
2337 2339
2338 read_lock(&policy_rwlock); 2340 read_lock(&policy_rwlock);
2339 2341
2340 c = policydb.ocontexts[OCON_FSUSE]; 2342 for (c = policydb.ocontexts[OCON_FSUSE]; c; c = c->next) {
2341 while (c) { 2343 char *sub;
2342 if (strcmp(fstype, c->u.name) == 0) 2344 int baselen;
2345
2346 baselen = strlen(fstype);
2347
2348 /* if base does not match, this is not the one */
2349 if (strncmp(fstype, c->u.name, baselen))
2350 continue;
2351
2352 /* if there is no subtype, this is the one! */
2353 if (!subtype)
2354 break;
2355
2356 /* skip past the base in this entry */
2357 sub = c->u.name + baselen;
2358
2359 /* entry is only a base. save it. keep looking for subtype */
2360 if (sub[0] == '\0') {
2361 base = c;
2362 continue;
2363 }
2364
2365 /* entry is not followed by a subtype, so it is not a match */
2366 if (sub[0] != '.')
2367 continue;
2368
2369 /* whew, we found a subtype of this fstype */
2370 sub++; /* move past '.' */
2371
2372 /* exact match of fstype AND subtype */
2373 if (!strcmp(subtype, sub))
2343 break; 2374 break;
2344 c = c->next;
2345 } 2375 }
2346 2376
2377 /* in case we had found an fstype match but no subtype match */
2378 if (!c)
2379 c = base;
2380
2347 if (c) { 2381 if (c) {
2348 *behavior = c->v.behavior; 2382 sbsec->behavior = c->v.behavior;
2349 if (!c->sid[0]) { 2383 if (!c->sid[0]) {
2350 rc = sidtab_context_to_sid(&sidtab, &c->context[0], 2384 rc = sidtab_context_to_sid(&sidtab, &c->context[0],
2351 &c->sid[0]); 2385 &c->sid[0]);
2352 if (rc) 2386 if (rc)
2353 goto out; 2387 goto out;
2354 } 2388 }
2355 *sid = c->sid[0]; 2389 sbsec->sid = c->sid[0];
2356 } else { 2390 } else {
2357 rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, sid); 2391 rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, &sbsec->sid);
2358 if (rc) { 2392 if (rc) {
2359 *behavior = SECURITY_FS_USE_NONE; 2393 sbsec->behavior = SECURITY_FS_USE_NONE;
2360 rc = 0; 2394 rc = 0;
2361 } else { 2395 } else {
2362 *behavior = SECURITY_FS_USE_GENFS; 2396 sbsec->behavior = SECURITY_FS_USE_GENFS;
2363 } 2397 }
2364 } 2398 }
2365 2399