aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/ss')
-rw-r--r--security/selinux/ss/Makefile2
-rw-r--r--security/selinux/ss/avtab.h2
-rw-r--r--security/selinux/ss/context.h12
-rw-r--r--security/selinux/ss/ebitmap.c2
-rw-r--r--security/selinux/ss/mls.c50
-rw-r--r--security/selinux/ss/mls.h2
-rw-r--r--security/selinux/ss/mls_types.h7
-rw-r--r--security/selinux/ss/policydb.c174
-rw-r--r--security/selinux/ss/policydb.h17
-rw-r--r--security/selinux/ss/services.c665
-rw-r--r--security/selinux/ss/symtab.c1
11 files changed, 527 insertions, 407 deletions
diff --git a/security/selinux/ss/Makefile b/security/selinux/ss/Makefile
index bad78779b9b0..15d4e62917de 100644
--- a/security/selinux/ss/Makefile
+++ b/security/selinux/ss/Makefile
@@ -2,7 +2,7 @@
2# Makefile for building the SELinux security server as part of the kernel tree. 2# Makefile for building the SELinux security server as part of the kernel tree.
3# 3#
4 4
5EXTRA_CFLAGS += -Isecurity/selinux/include 5EXTRA_CFLAGS += -Isecurity/selinux -Isecurity/selinux/include
6obj-y := ss.o 6obj-y := ss.o
7 7
8ss-y := ebitmap.o hashtab.o symtab.o sidtab.o avtab.o policydb.o services.o conditional.o mls.o 8ss-y := ebitmap.o hashtab.o symtab.o sidtab.o avtab.o policydb.o services.o conditional.o mls.o
diff --git a/security/selinux/ss/avtab.h b/security/selinux/ss/avtab.h
index 8da6a8428086..cd4f734e2749 100644
--- a/security/selinux/ss/avtab.h
+++ b/security/selinux/ss/avtab.h
@@ -82,7 +82,7 @@ struct avtab_node *avtab_search_node_next(struct avtab_node *node, int specified
82void avtab_cache_init(void); 82void avtab_cache_init(void);
83void avtab_cache_destroy(void); 83void avtab_cache_destroy(void);
84 84
85#define MAX_AVTAB_HASH_BITS 13 85#define MAX_AVTAB_HASH_BITS 11
86#define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS) 86#define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS)
87#define MAX_AVTAB_HASH_MASK (MAX_AVTAB_HASH_BUCKETS-1) 87#define MAX_AVTAB_HASH_MASK (MAX_AVTAB_HASH_BUCKETS-1)
88#define MAX_AVTAB_SIZE MAX_AVTAB_HASH_BUCKETS 88#define MAX_AVTAB_SIZE MAX_AVTAB_HASH_BUCKETS
diff --git a/security/selinux/ss/context.h b/security/selinux/ss/context.h
index d9dd7a2f6a8a..45e8fb0515f8 100644
--- a/security/selinux/ss/context.h
+++ b/security/selinux/ss/context.h
@@ -41,9 +41,6 @@ static inline int mls_context_cpy(struct context *dst, struct context *src)
41{ 41{
42 int rc; 42 int rc;
43 43
44 if (!selinux_mls_enabled)
45 return 0;
46
47 dst->range.level[0].sens = src->range.level[0].sens; 44 dst->range.level[0].sens = src->range.level[0].sens;
48 rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat); 45 rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
49 if (rc) 46 if (rc)
@@ -64,9 +61,6 @@ static inline int mls_context_cpy_low(struct context *dst, struct context *src)
64{ 61{
65 int rc; 62 int rc;
66 63
67 if (!selinux_mls_enabled)
68 return 0;
69
70 dst->range.level[0].sens = src->range.level[0].sens; 64 dst->range.level[0].sens = src->range.level[0].sens;
71 rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat); 65 rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
72 if (rc) 66 if (rc)
@@ -82,9 +76,6 @@ out:
82 76
83static inline int mls_context_cmp(struct context *c1, struct context *c2) 77static inline int mls_context_cmp(struct context *c1, struct context *c2)
84{ 78{
85 if (!selinux_mls_enabled)
86 return 1;
87
88 return ((c1->range.level[0].sens == c2->range.level[0].sens) && 79 return ((c1->range.level[0].sens == c2->range.level[0].sens) &&
89 ebitmap_cmp(&c1->range.level[0].cat, &c2->range.level[0].cat) && 80 ebitmap_cmp(&c1->range.level[0].cat, &c2->range.level[0].cat) &&
90 (c1->range.level[1].sens == c2->range.level[1].sens) && 81 (c1->range.level[1].sens == c2->range.level[1].sens) &&
@@ -93,9 +84,6 @@ static inline int mls_context_cmp(struct context *c1, struct context *c2)
93 84
94static inline void mls_context_destroy(struct context *c) 85static inline void mls_context_destroy(struct context *c)
95{ 86{
96 if (!selinux_mls_enabled)
97 return;
98
99 ebitmap_destroy(&c->range.level[0].cat); 87 ebitmap_destroy(&c->range.level[0].cat);
100 ebitmap_destroy(&c->range.level[1].cat); 88 ebitmap_destroy(&c->range.level[1].cat);
101 mls_context_init(c); 89 mls_context_init(c);
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c
index 68c7348d1acc..04b6145d767f 100644
--- a/security/selinux/ss/ebitmap.c
+++ b/security/selinux/ss/ebitmap.c
@@ -128,7 +128,7 @@ int ebitmap_netlbl_export(struct ebitmap *ebmap,
128 cmap_idx = delta / NETLBL_CATMAP_MAPSIZE; 128 cmap_idx = delta / NETLBL_CATMAP_MAPSIZE;
129 cmap_sft = delta % NETLBL_CATMAP_MAPSIZE; 129 cmap_sft = delta % NETLBL_CATMAP_MAPSIZE;
130 c_iter->bitmap[cmap_idx] 130 c_iter->bitmap[cmap_idx]
131 |= e_iter->maps[cmap_idx] << cmap_sft; 131 |= e_iter->maps[i] << cmap_sft;
132 } 132 }
133 e_iter = e_iter->next; 133 e_iter = e_iter->next;
134 } 134 }
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index b5407f16c2a4..372b773f8210 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -39,7 +39,7 @@ int mls_compute_context_len(struct context *context)
39 struct ebitmap *e; 39 struct ebitmap *e;
40 struct ebitmap_node *node; 40 struct ebitmap_node *node;
41 41
42 if (!selinux_mls_enabled) 42 if (!policydb.mls_enabled)
43 return 0; 43 return 0;
44 44
45 len = 1; /* for the beginning ":" */ 45 len = 1; /* for the beginning ":" */
@@ -93,7 +93,7 @@ void mls_sid_to_context(struct context *context,
93 struct ebitmap *e; 93 struct ebitmap *e;
94 struct ebitmap_node *node; 94 struct ebitmap_node *node;
95 95
96 if (!selinux_mls_enabled) 96 if (!policydb.mls_enabled)
97 return; 97 return;
98 98
99 scontextp = *scontext; 99 scontextp = *scontext;
@@ -200,7 +200,7 @@ int mls_context_isvalid(struct policydb *p, struct context *c)
200{ 200{
201 struct user_datum *usrdatum; 201 struct user_datum *usrdatum;
202 202
203 if (!selinux_mls_enabled) 203 if (!p->mls_enabled)
204 return 1; 204 return 1;
205 205
206 if (!mls_range_isvalid(p, &c->range)) 206 if (!mls_range_isvalid(p, &c->range))
@@ -253,7 +253,7 @@ int mls_context_to_sid(struct policydb *pol,
253 struct cat_datum *catdatum, *rngdatum; 253 struct cat_datum *catdatum, *rngdatum;
254 int l, rc = -EINVAL; 254 int l, rc = -EINVAL;
255 255
256 if (!selinux_mls_enabled) { 256 if (!pol->mls_enabled) {
257 if (def_sid != SECSID_NULL && oldc) 257 if (def_sid != SECSID_NULL && oldc)
258 *scontext += strlen(*scontext)+1; 258 *scontext += strlen(*scontext)+1;
259 return 0; 259 return 0;
@@ -387,7 +387,7 @@ int mls_from_string(char *str, struct context *context, gfp_t gfp_mask)
387 char *tmpstr, *freestr; 387 char *tmpstr, *freestr;
388 int rc; 388 int rc;
389 389
390 if (!selinux_mls_enabled) 390 if (!policydb.mls_enabled)
391 return -EINVAL; 391 return -EINVAL;
392 392
393 /* we need freestr because mls_context_to_sid will change 393 /* we need freestr because mls_context_to_sid will change
@@ -407,7 +407,7 @@ int mls_from_string(char *str, struct context *context, gfp_t gfp_mask)
407/* 407/*
408 * Copies the MLS range `range' into `context'. 408 * Copies the MLS range `range' into `context'.
409 */ 409 */
410static inline int mls_range_set(struct context *context, 410int mls_range_set(struct context *context,
411 struct mls_range *range) 411 struct mls_range *range)
412{ 412{
413 int l, rc = 0; 413 int l, rc = 0;
@@ -427,7 +427,7 @@ static inline int mls_range_set(struct context *context,
427int mls_setup_user_range(struct context *fromcon, struct user_datum *user, 427int mls_setup_user_range(struct context *fromcon, struct user_datum *user,
428 struct context *usercon) 428 struct context *usercon)
429{ 429{
430 if (selinux_mls_enabled) { 430 if (policydb.mls_enabled) {
431 struct mls_level *fromcon_sen = &(fromcon->range.level[0]); 431 struct mls_level *fromcon_sen = &(fromcon->range.level[0]);
432 struct mls_level *fromcon_clr = &(fromcon->range.level[1]); 432 struct mls_level *fromcon_clr = &(fromcon->range.level[1]);
433 struct mls_level *user_low = &(user->range.level[0]); 433 struct mls_level *user_low = &(user->range.level[0]);
@@ -477,7 +477,7 @@ int mls_convert_context(struct policydb *oldp,
477 struct ebitmap_node *node; 477 struct ebitmap_node *node;
478 int l, i; 478 int l, i;
479 479
480 if (!selinux_mls_enabled) 480 if (!policydb.mls_enabled)
481 return 0; 481 return 0;
482 482
483 for (l = 0; l < 2; l++) { 483 for (l = 0; l < 2; l++) {
@@ -513,26 +513,24 @@ int mls_compute_sid(struct context *scontext,
513 u32 specified, 513 u32 specified,
514 struct context *newcontext) 514 struct context *newcontext)
515{ 515{
516 struct range_trans *rtr; 516 struct range_trans rtr;
517 struct mls_range *r;
517 518
518 if (!selinux_mls_enabled) 519 if (!policydb.mls_enabled)
519 return 0; 520 return 0;
520 521
521 switch (specified) { 522 switch (specified) {
522 case AVTAB_TRANSITION: 523 case AVTAB_TRANSITION:
523 /* Look for a range transition rule. */ 524 /* Look for a range transition rule. */
524 for (rtr = policydb.range_tr; rtr; rtr = rtr->next) { 525 rtr.source_type = scontext->type;
525 if (rtr->source_type == scontext->type && 526 rtr.target_type = tcontext->type;
526 rtr->target_type == tcontext->type && 527 rtr.target_class = tclass;
527 rtr->target_class == tclass) { 528 r = hashtab_search(policydb.range_tr, &rtr);
528 /* Set the range from the rule */ 529 if (r)
529 return mls_range_set(newcontext, 530 return mls_range_set(newcontext, r);
530 &rtr->target_range);
531 }
532 }
533 /* Fallthrough */ 531 /* Fallthrough */
534 case AVTAB_CHANGE: 532 case AVTAB_CHANGE:
535 if (tclass == SECCLASS_PROCESS) 533 if (tclass == policydb.process_class)
536 /* Use the process MLS attributes. */ 534 /* Use the process MLS attributes. */
537 return mls_context_cpy(newcontext, scontext); 535 return mls_context_cpy(newcontext, scontext);
538 else 536 else
@@ -541,8 +539,8 @@ int mls_compute_sid(struct context *scontext,
541 case AVTAB_MEMBER: 539 case AVTAB_MEMBER:
542 /* Use the process effective MLS attributes. */ 540 /* Use the process effective MLS attributes. */
543 return mls_context_cpy_low(newcontext, scontext); 541 return mls_context_cpy_low(newcontext, scontext);
544 default: 542
545 return -EINVAL; 543 /* fall through */
546 } 544 }
547 return -EINVAL; 545 return -EINVAL;
548} 546}
@@ -561,7 +559,7 @@ int mls_compute_sid(struct context *scontext,
561void mls_export_netlbl_lvl(struct context *context, 559void mls_export_netlbl_lvl(struct context *context,
562 struct netlbl_lsm_secattr *secattr) 560 struct netlbl_lsm_secattr *secattr)
563{ 561{
564 if (!selinux_mls_enabled) 562 if (!policydb.mls_enabled)
565 return; 563 return;
566 564
567 secattr->attr.mls.lvl = context->range.level[0].sens - 1; 565 secattr->attr.mls.lvl = context->range.level[0].sens - 1;
@@ -581,7 +579,7 @@ void mls_export_netlbl_lvl(struct context *context,
581void mls_import_netlbl_lvl(struct context *context, 579void mls_import_netlbl_lvl(struct context *context,
582 struct netlbl_lsm_secattr *secattr) 580 struct netlbl_lsm_secattr *secattr)
583{ 581{
584 if (!selinux_mls_enabled) 582 if (!policydb.mls_enabled)
585 return; 583 return;
586 584
587 context->range.level[0].sens = secattr->attr.mls.lvl + 1; 585 context->range.level[0].sens = secattr->attr.mls.lvl + 1;
@@ -603,7 +601,7 @@ int mls_export_netlbl_cat(struct context *context,
603{ 601{
604 int rc; 602 int rc;
605 603
606 if (!selinux_mls_enabled) 604 if (!policydb.mls_enabled)
607 return 0; 605 return 0;
608 606
609 rc = ebitmap_netlbl_export(&context->range.level[0].cat, 607 rc = ebitmap_netlbl_export(&context->range.level[0].cat,
@@ -631,7 +629,7 @@ int mls_import_netlbl_cat(struct context *context,
631{ 629{
632 int rc; 630 int rc;
633 631
634 if (!selinux_mls_enabled) 632 if (!policydb.mls_enabled)
635 return 0; 633 return 0;
636 634
637 rc = ebitmap_netlbl_import(&context->range.level[0].cat, 635 rc = ebitmap_netlbl_import(&context->range.level[0].cat,
diff --git a/security/selinux/ss/mls.h b/security/selinux/ss/mls.h
index 1276715aaa8b..cd9152632e54 100644
--- a/security/selinux/ss/mls.h
+++ b/security/selinux/ss/mls.h
@@ -39,6 +39,8 @@ int mls_context_to_sid(struct policydb *p,
39 39
40int mls_from_string(char *str, struct context *context, gfp_t gfp_mask); 40int mls_from_string(char *str, struct context *context, gfp_t gfp_mask);
41 41
42int mls_range_set(struct context *context, struct mls_range *range);
43
42int mls_convert_context(struct policydb *oldp, 44int mls_convert_context(struct policydb *oldp,
43 struct policydb *newp, 45 struct policydb *newp,
44 struct context *context); 46 struct context *context);
diff --git a/security/selinux/ss/mls_types.h b/security/selinux/ss/mls_types.h
index b6e943a21061..03bed52a8052 100644
--- a/security/selinux/ss/mls_types.h
+++ b/security/selinux/ss/mls_types.h
@@ -15,6 +15,7 @@
15#define _SS_MLS_TYPES_H_ 15#define _SS_MLS_TYPES_H_
16 16
17#include "security.h" 17#include "security.h"
18#include "ebitmap.h"
18 19
19struct mls_level { 20struct mls_level {
20 u32 sens; /* sensitivity */ 21 u32 sens; /* sensitivity */
@@ -27,18 +28,12 @@ struct mls_range {
27 28
28static inline int mls_level_eq(struct mls_level *l1, struct mls_level *l2) 29static inline int mls_level_eq(struct mls_level *l1, struct mls_level *l2)
29{ 30{
30 if (!selinux_mls_enabled)
31 return 1;
32
33 return ((l1->sens == l2->sens) && 31 return ((l1->sens == l2->sens) &&
34 ebitmap_cmp(&l1->cat, &l2->cat)); 32 ebitmap_cmp(&l1->cat, &l2->cat));
35} 33}
36 34
37static 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)
38{ 36{
39 if (!selinux_mls_enabled)
40 return 1;
41
42 return ((l1->sens >= l2->sens) && 37 return ((l1->sens >= l2->sens) &&
43 ebitmap_contains(&l1->cat, &l2->cat)); 38 ebitmap_contains(&l1->cat, &l2->cat));
44} 39}
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 72e4a54973aa..23c6e53c102c 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -52,8 +52,6 @@ static char *symtab_name[SYM_NUM] = {
52}; 52};
53#endif 53#endif
54 54
55int selinux_mls_enabled;
56
57static unsigned int symtab_sizes[SYM_NUM] = { 55static unsigned int symtab_sizes[SYM_NUM] = {
58 2, 56 2,
59 32, 57 32,
@@ -177,6 +175,21 @@ out_free_role:
177 goto out; 175 goto out;
178} 176}
179 177
178static u32 rangetr_hash(struct hashtab *h, const void *k)
179{
180 const struct range_trans *key = k;
181 return (key->source_type + (key->target_type << 3) +
182 (key->target_class << 5)) & (h->size - 1);
183}
184
185static int rangetr_cmp(struct hashtab *h, const void *k1, const void *k2)
186{
187 const struct range_trans *key1 = k1, *key2 = k2;
188 return (key1->source_type != key2->source_type ||
189 key1->target_type != key2->target_type ||
190 key1->target_class != key2->target_class);
191}
192
180/* 193/*
181 * Initialize a policy database structure. 194 * Initialize a policy database structure.
182 */ 195 */
@@ -204,6 +217,10 @@ static int policydb_init(struct policydb *p)
204 if (rc) 217 if (rc)
205 goto out_free_symtab; 218 goto out_free_symtab;
206 219
220 p->range_tr = hashtab_create(rangetr_hash, rangetr_cmp, 256);
221 if (!p->range_tr)
222 goto out_free_symtab;
223
207 ebitmap_init(&p->policycaps); 224 ebitmap_init(&p->policycaps);
208 ebitmap_init(&p->permissive_map); 225 ebitmap_init(&p->permissive_map);
209 226
@@ -408,6 +425,20 @@ static void symtab_hash_eval(struct symtab *s)
408 info.slots_used, h->size, info.max_chain_len); 425 info.slots_used, h->size, info.max_chain_len);
409 } 426 }
410} 427}
428
429static void rangetr_hash_eval(struct hashtab *h)
430{
431 struct hashtab_info info;
432
433 hashtab_stat(h, &info);
434 printk(KERN_DEBUG "SELinux: rangetr: %d entries and %d/%d buckets used, "
435 "longest chain length %d\n", h->nel,
436 info.slots_used, h->size, info.max_chain_len);
437}
438#else
439static inline void rangetr_hash_eval(struct hashtab *h)
440{
441}
411#endif 442#endif
412 443
413/* 444/*
@@ -422,7 +453,7 @@ static int policydb_index_others(struct policydb *p)
422 453
423 printk(KERN_DEBUG "SELinux: %d users, %d roles, %d types, %d bools", 454 printk(KERN_DEBUG "SELinux: %d users, %d roles, %d types, %d bools",
424 p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim); 455 p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim);
425 if (selinux_mls_enabled) 456 if (p->mls_enabled)
426 printk(", %d sens, %d cats", p->p_levels.nprim, 457 printk(", %d sens, %d cats", p->p_levels.nprim,
427 p->p_cats.nprim); 458 p->p_cats.nprim);
428 printk("\n"); 459 printk("\n");
@@ -612,6 +643,17 @@ static int (*destroy_f[SYM_NUM]) (void *key, void *datum, void *datap) =
612 cat_destroy, 643 cat_destroy,
613}; 644};
614 645
646static int range_tr_destroy(void *key, void *datum, void *p)
647{
648 struct mls_range *rt = datum;
649 kfree(key);
650 ebitmap_destroy(&rt->level[0].cat);
651 ebitmap_destroy(&rt->level[1].cat);
652 kfree(datum);
653 cond_resched();
654 return 0;
655}
656
615static void ocontext_destroy(struct ocontext *c, int i) 657static void ocontext_destroy(struct ocontext *c, int i)
616{ 658{
617 context_destroy(&c->context[0]); 659 context_destroy(&c->context[0]);
@@ -632,7 +674,6 @@ void policydb_destroy(struct policydb *p)
632 int i; 674 int i;
633 struct role_allow *ra, *lra = NULL; 675 struct role_allow *ra, *lra = NULL;
634 struct role_trans *tr, *ltr = NULL; 676 struct role_trans *tr, *ltr = NULL;
635 struct range_trans *rt, *lrt = NULL;
636 677
637 for (i = 0; i < SYM_NUM; i++) { 678 for (i = 0; i < SYM_NUM; i++) {
638 cond_resched(); 679 cond_resched();
@@ -693,27 +734,14 @@ void policydb_destroy(struct policydb *p)
693 } 734 }
694 kfree(lra); 735 kfree(lra);
695 736
696 for (rt = p->range_tr; rt; rt = rt->next) { 737 hashtab_map(p->range_tr, range_tr_destroy, NULL);
697 cond_resched(); 738 hashtab_destroy(p->range_tr);
698 if (lrt) {
699 ebitmap_destroy(&lrt->target_range.level[0].cat);
700 ebitmap_destroy(&lrt->target_range.level[1].cat);
701 kfree(lrt);
702 }
703 lrt = rt;
704 }
705 if (lrt) {
706 ebitmap_destroy(&lrt->target_range.level[0].cat);
707 ebitmap_destroy(&lrt->target_range.level[1].cat);
708 kfree(lrt);
709 }
710 739
711 if (p->type_attr_map) { 740 if (p->type_attr_map) {
712 for (i = 0; i < p->p_types.nprim; i++) 741 for (i = 0; i < p->p_types.nprim; i++)
713 ebitmap_destroy(&p->type_attr_map[i]); 742 ebitmap_destroy(&p->type_attr_map[i]);
714 } 743 }
715 kfree(p->type_attr_map); 744 kfree(p->type_attr_map);
716 kfree(p->undefined_perms);
717 ebitmap_destroy(&p->policycaps); 745 ebitmap_destroy(&p->policycaps);
718 ebitmap_destroy(&p->permissive_map); 746 ebitmap_destroy(&p->permissive_map);
719 747
@@ -1640,6 +1668,40 @@ static int policydb_bounds_sanity_check(struct policydb *p)
1640 1668
1641extern int ss_initialized; 1669extern int ss_initialized;
1642 1670
1671u16 string_to_security_class(struct policydb *p, const char *name)
1672{
1673 struct class_datum *cladatum;
1674
1675 cladatum = hashtab_search(p->p_classes.table, name);
1676 if (!cladatum)
1677 return 0;
1678
1679 return cladatum->value;
1680}
1681
1682u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name)
1683{
1684 struct class_datum *cladatum;
1685 struct perm_datum *perdatum = NULL;
1686 struct common_datum *comdatum;
1687
1688 if (!tclass || tclass > p->p_classes.nprim)
1689 return 0;
1690
1691 cladatum = p->class_val_to_struct[tclass-1];
1692 comdatum = cladatum->comdatum;
1693 if (comdatum)
1694 perdatum = hashtab_search(comdatum->permissions.table,
1695 name);
1696 if (!perdatum)
1697 perdatum = hashtab_search(cladatum->permissions.table,
1698 name);
1699 if (!perdatum)
1700 return 0;
1701
1702 return 1U << (perdatum->value-1);
1703}
1704
1643/* 1705/*
1644 * Read the configuration data from a policy database binary 1706 * Read the configuration data from a policy database binary
1645 * representation file into a policy database structure. 1707 * representation file into a policy database structure.
@@ -1653,12 +1715,11 @@ int policydb_read(struct policydb *p, void *fp)
1653 int i, j, rc; 1715 int i, j, rc;
1654 __le32 buf[4]; 1716 __le32 buf[4];
1655 u32 nodebuf[8]; 1717 u32 nodebuf[8];
1656 u32 len, len2, config, nprim, nel, nel2; 1718 u32 len, len2, nprim, nel, nel2;
1657 char *policydb_str; 1719 char *policydb_str;
1658 struct policydb_compat_info *info; 1720 struct policydb_compat_info *info;
1659 struct range_trans *rt, *lrt; 1721 struct range_trans *rt;
1660 1722 struct mls_range *r;
1661 config = 0;
1662 1723
1663 rc = policydb_init(p); 1724 rc = policydb_init(p);
1664 if (rc) 1725 if (rc)
@@ -1707,7 +1768,7 @@ int policydb_read(struct policydb *p, void *fp)
1707 kfree(policydb_str); 1768 kfree(policydb_str);
1708 policydb_str = NULL; 1769 policydb_str = NULL;
1709 1770
1710 /* Read the version, config, and table sizes. */ 1771 /* Read the version and table sizes. */
1711 rc = next_entry(buf, fp, sizeof(u32)*4); 1772 rc = next_entry(buf, fp, sizeof(u32)*4);
1712 if (rc < 0) 1773 if (rc < 0)
1713 goto bad; 1774 goto bad;
@@ -1722,13 +1783,7 @@ int policydb_read(struct policydb *p, void *fp)
1722 } 1783 }
1723 1784
1724 if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) { 1785 if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) {
1725 if (ss_initialized && !selinux_mls_enabled) { 1786 p->mls_enabled = 1;
1726 printk(KERN_ERR "SELinux: Cannot switch between non-MLS"
1727 " and MLS policies\n");
1728 goto bad;
1729 }
1730 selinux_mls_enabled = 1;
1731 config |= POLICYDB_CONFIG_MLS;
1732 1787
1733 if (p->policyvers < POLICYDB_VERSION_MLS) { 1788 if (p->policyvers < POLICYDB_VERSION_MLS) {
1734 printk(KERN_ERR "SELinux: security policydb version %d " 1789 printk(KERN_ERR "SELinux: security policydb version %d "
@@ -1736,12 +1791,6 @@ int policydb_read(struct policydb *p, void *fp)
1736 p->policyvers); 1791 p->policyvers);
1737 goto bad; 1792 goto bad;
1738 } 1793 }
1739 } else {
1740 if (ss_initialized && selinux_mls_enabled) {
1741 printk(KERN_ERR "SELinux: Cannot switch between MLS and"
1742 " non-MLS policies\n");
1743 goto bad;
1744 }
1745 } 1794 }
1746 p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN); 1795 p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN);
1747 p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN); 1796 p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN);
@@ -1861,6 +1910,16 @@ int policydb_read(struct policydb *p, void *fp)
1861 if (rc) 1910 if (rc)
1862 goto bad; 1911 goto bad;
1863 1912
1913 p->process_class = string_to_security_class(p, "process");
1914 if (!p->process_class)
1915 goto bad;
1916 p->process_trans_perms = string_to_av_perm(p, p->process_class,
1917 "transition");
1918 p->process_trans_perms |= string_to_av_perm(p, p->process_class,
1919 "dyntransition");
1920 if (!p->process_trans_perms)
1921 goto bad;
1922
1864 for (i = 0; i < info->ocon_num; i++) { 1923 for (i = 0; i < info->ocon_num; i++) {
1865 rc = next_entry(buf, fp, sizeof(u32)); 1924 rc = next_entry(buf, fp, sizeof(u32));
1866 if (rc < 0) 1925 if (rc < 0)
@@ -2079,44 +2138,61 @@ int policydb_read(struct policydb *p, void *fp)
2079 if (rc < 0) 2138 if (rc < 0)
2080 goto bad; 2139 goto bad;
2081 nel = le32_to_cpu(buf[0]); 2140 nel = le32_to_cpu(buf[0]);
2082 lrt = NULL;
2083 for (i = 0; i < nel; i++) { 2141 for (i = 0; i < nel; i++) {
2084 rt = kzalloc(sizeof(*rt), GFP_KERNEL); 2142 rt = kzalloc(sizeof(*rt), GFP_KERNEL);
2085 if (!rt) { 2143 if (!rt) {
2086 rc = -ENOMEM; 2144 rc = -ENOMEM;
2087 goto bad; 2145 goto bad;
2088 } 2146 }
2089 if (lrt)
2090 lrt->next = rt;
2091 else
2092 p->range_tr = rt;
2093 rc = next_entry(buf, fp, (sizeof(u32) * 2)); 2147 rc = next_entry(buf, fp, (sizeof(u32) * 2));
2094 if (rc < 0) 2148 if (rc < 0) {
2149 kfree(rt);
2095 goto bad; 2150 goto bad;
2151 }
2096 rt->source_type = le32_to_cpu(buf[0]); 2152 rt->source_type = le32_to_cpu(buf[0]);
2097 rt->target_type = le32_to_cpu(buf[1]); 2153 rt->target_type = le32_to_cpu(buf[1]);
2098 if (new_rangetr) { 2154 if (new_rangetr) {
2099 rc = next_entry(buf, fp, sizeof(u32)); 2155 rc = next_entry(buf, fp, sizeof(u32));
2100 if (rc < 0) 2156 if (rc < 0) {
2157 kfree(rt);
2101 goto bad; 2158 goto bad;
2159 }
2102 rt->target_class = le32_to_cpu(buf[0]); 2160 rt->target_class = le32_to_cpu(buf[0]);
2103 } else 2161 } else
2104 rt->target_class = SECCLASS_PROCESS; 2162 rt->target_class = p->process_class;
2105 if (!policydb_type_isvalid(p, rt->source_type) || 2163 if (!policydb_type_isvalid(p, rt->source_type) ||
2106 !policydb_type_isvalid(p, rt->target_type) || 2164 !policydb_type_isvalid(p, rt->target_type) ||
2107 !policydb_class_isvalid(p, rt->target_class)) { 2165 !policydb_class_isvalid(p, rt->target_class)) {
2166 kfree(rt);
2108 rc = -EINVAL; 2167 rc = -EINVAL;
2109 goto bad; 2168 goto bad;
2110 } 2169 }
2111 rc = mls_read_range_helper(&rt->target_range, fp); 2170 r = kzalloc(sizeof(*r), GFP_KERNEL);
2112 if (rc) 2171 if (!r) {
2172 kfree(rt);
2173 rc = -ENOMEM;
2174 goto bad;
2175 }
2176 rc = mls_read_range_helper(r, fp);
2177 if (rc) {
2178 kfree(rt);
2179 kfree(r);
2113 goto bad; 2180 goto bad;
2114 if (!mls_range_isvalid(p, &rt->target_range)) { 2181 }
2182 if (!mls_range_isvalid(p, r)) {
2115 printk(KERN_WARNING "SELinux: rangetrans: invalid range\n"); 2183 printk(KERN_WARNING "SELinux: rangetrans: invalid range\n");
2184 kfree(rt);
2185 kfree(r);
2186 goto bad;
2187 }
2188 rc = hashtab_insert(p->range_tr, rt, r);
2189 if (rc) {
2190 kfree(rt);
2191 kfree(r);
2116 goto bad; 2192 goto bad;
2117 } 2193 }
2118 lrt = rt;
2119 } 2194 }
2195 rangetr_hash_eval(p->range_tr);
2120 } 2196 }
2121 2197
2122 p->type_attr_map = kmalloc(p->p_types.nprim*sizeof(struct ebitmap), GFP_KERNEL); 2198 p->type_attr_map = kmalloc(p->p_types.nprim*sizeof(struct ebitmap), GFP_KERNEL);
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index 55152d498b53..26d9adf8542b 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -27,6 +27,8 @@
27#include "symtab.h" 27#include "symtab.h"
28#include "avtab.h" 28#include "avtab.h"
29#include "sidtab.h" 29#include "sidtab.h"
30#include "ebitmap.h"
31#include "mls_types.h"
30#include "context.h" 32#include "context.h"
31#include "constraint.h" 33#include "constraint.h"
32 34
@@ -113,8 +115,6 @@ struct range_trans {
113 u32 source_type; 115 u32 source_type;
114 u32 target_type; 116 u32 target_type;
115 u32 target_class; 117 u32 target_class;
116 struct mls_range target_range;
117 struct range_trans *next;
118}; 118};
119 119
120/* Boolean data type */ 120/* Boolean data type */
@@ -187,6 +187,8 @@ struct genfs {
187 187
188/* The policy database */ 188/* The policy database */
189struct policydb { 189struct policydb {
190 int mls_enabled;
191
190 /* symbol tables */ 192 /* symbol tables */
191 struct symtab symtab[SYM_NUM]; 193 struct symtab symtab[SYM_NUM];
192#define p_commons symtab[SYM_COMMONS] 194#define p_commons symtab[SYM_COMMONS]
@@ -240,8 +242,8 @@ struct policydb {
240 fixed labeling behavior. */ 242 fixed labeling behavior. */
241 struct genfs *genfs; 243 struct genfs *genfs;
242 244
243 /* range transitions */ 245 /* range transitions table (range_trans_key -> mls_range) */
244 struct range_trans *range_tr; 246 struct hashtab *range_tr;
245 247
246 /* type -> attribute reverse mapping */ 248 /* type -> attribute reverse mapping */
247 struct ebitmap *type_attr_map; 249 struct ebitmap *type_attr_map;
@@ -254,7 +256,9 @@ struct policydb {
254 256
255 unsigned int reject_unknown : 1; 257 unsigned int reject_unknown : 1;
256 unsigned int allow_unknown : 1; 258 unsigned int allow_unknown : 1;
257 u32 *undefined_perms; 259
260 u16 process_class;
261 u32 process_trans_perms;
258}; 262};
259 263
260extern void policydb_destroy(struct policydb *p); 264extern void policydb_destroy(struct policydb *p);
@@ -295,5 +299,8 @@ static inline int next_entry(void *buf, struct policy_file *fp, size_t bytes)
295 return 0; 299 return 0;
296} 300}
297 301
302extern u16 string_to_security_class(struct policydb *p, const char *name);
303extern u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name);
304
298#endif /* _SS_POLICYDB_H_ */ 305#endif /* _SS_POLICYDB_H_ */
299 306
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index ff17820d35ec..cf27b3ee1a95 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -26,6 +26,10 @@
26 * 26 *
27 * Added support for bounds domain and audit messaged on masked permissions 27 * Added support for bounds domain and audit messaged on masked permissions
28 * 28 *
29 * Updated: Guido Trentalancia <guido@trentalancia.com>
30 *
31 * Added support for runtime switching of the policy type
32 *
29 * Copyright (C) 2008, 2009 NEC Corporation 33 * Copyright (C) 2008, 2009 NEC Corporation
30 * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P. 34 * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P.
31 * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. 35 * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
@@ -65,16 +69,10 @@
65#include "audit.h" 69#include "audit.h"
66 70
67extern void selnl_notify_policyload(u32 seqno); 71extern void selnl_notify_policyload(u32 seqno);
68unsigned int policydb_loaded_version;
69 72
70int selinux_policycap_netpeer; 73int selinux_policycap_netpeer;
71int selinux_policycap_openperm; 74int selinux_policycap_openperm;
72 75
73/*
74 * This is declared in avc.c
75 */
76extern const struct selinux_class_perm selinux_class_perm;
77
78static DEFINE_RWLOCK(policy_rwlock); 76static DEFINE_RWLOCK(policy_rwlock);
79 77
80static struct sidtab sidtab; 78static struct sidtab sidtab;
@@ -93,11 +91,156 @@ static u32 latest_granting;
93static int context_struct_to_string(struct context *context, char **scontext, 91static int context_struct_to_string(struct context *context, char **scontext,
94 u32 *scontext_len); 92 u32 *scontext_len);
95 93
96static int context_struct_compute_av(struct context *scontext, 94static void context_struct_compute_av(struct context *scontext,
97 struct context *tcontext, 95 struct context *tcontext,
98 u16 tclass, 96 u16 tclass,
99 u32 requested, 97 struct av_decision *avd);
100 struct av_decision *avd); 98
99struct selinux_mapping {
100 u16 value; /* policy value */
101 unsigned num_perms;
102 u32 perms[sizeof(u32) * 8];
103};
104
105static struct selinux_mapping *current_mapping;
106static u16 current_mapping_size;
107
108static int selinux_set_mapping(struct policydb *pol,
109 struct security_class_mapping *map,
110 struct selinux_mapping **out_map_p,
111 u16 *out_map_size)
112{
113 struct selinux_mapping *out_map = NULL;
114 size_t size = sizeof(struct selinux_mapping);
115 u16 i, j;
116 unsigned k;
117 bool print_unknown_handle = false;
118
119 /* Find number of classes in the input mapping */
120 if (!map)
121 return -EINVAL;
122 i = 0;
123 while (map[i].name)
124 i++;
125
126 /* Allocate space for the class records, plus one for class zero */
127 out_map = kcalloc(++i, size, GFP_ATOMIC);
128 if (!out_map)
129 return -ENOMEM;
130
131 /* Store the raw class and permission values */
132 j = 0;
133 while (map[j].name) {
134 struct security_class_mapping *p_in = map + (j++);
135 struct selinux_mapping *p_out = out_map + j;
136
137 /* An empty class string skips ahead */
138 if (!strcmp(p_in->name, "")) {
139 p_out->num_perms = 0;
140 continue;
141 }
142
143 p_out->value = string_to_security_class(pol, p_in->name);
144 if (!p_out->value) {
145 printk(KERN_INFO
146 "SELinux: Class %s not defined in policy.\n",
147 p_in->name);
148 if (pol->reject_unknown)
149 goto err;
150 p_out->num_perms = 0;
151 print_unknown_handle = true;
152 continue;
153 }
154
155 k = 0;
156 while (p_in->perms && p_in->perms[k]) {
157 /* An empty permission string skips ahead */
158 if (!*p_in->perms[k]) {
159 k++;
160 continue;
161 }
162 p_out->perms[k] = string_to_av_perm(pol, p_out->value,
163 p_in->perms[k]);
164 if (!p_out->perms[k]) {
165 printk(KERN_INFO
166 "SELinux: Permission %s in class %s not defined in policy.\n",
167 p_in->perms[k], p_in->name);
168 if (pol->reject_unknown)
169 goto err;
170 print_unknown_handle = true;
171 }
172
173 k++;
174 }
175 p_out->num_perms = k;
176 }
177
178 if (print_unknown_handle)
179 printk(KERN_INFO "SELinux: the above unknown classes and permissions will be %s\n",
180 pol->allow_unknown ? "allowed" : "denied");
181
182 *out_map_p = out_map;
183 *out_map_size = i;
184 return 0;
185err:
186 kfree(out_map);
187 return -EINVAL;
188}
189
190/*
191 * Get real, policy values from mapped values
192 */
193
194static u16 unmap_class(u16 tclass)
195{
196 if (tclass < current_mapping_size)
197 return current_mapping[tclass].value;
198
199 return tclass;
200}
201
202static void map_decision(u16 tclass, struct av_decision *avd,
203 int allow_unknown)
204{
205 if (tclass < current_mapping_size) {
206 unsigned i, n = current_mapping[tclass].num_perms;
207 u32 result;
208
209 for (i = 0, result = 0; i < n; i++) {
210 if (avd->allowed & current_mapping[tclass].perms[i])
211 result |= 1<<i;
212 if (allow_unknown && !current_mapping[tclass].perms[i])
213 result |= 1<<i;
214 }
215 avd->allowed = result;
216
217 for (i = 0, result = 0; i < n; i++)
218 if (avd->auditallow & current_mapping[tclass].perms[i])
219 result |= 1<<i;
220 avd->auditallow = result;
221
222 for (i = 0, result = 0; i < n; i++) {
223 if (avd->auditdeny & current_mapping[tclass].perms[i])
224 result |= 1<<i;
225 if (!allow_unknown && !current_mapping[tclass].perms[i])
226 result |= 1<<i;
227 }
228 /*
229 * In case the kernel has a bug and requests a permission
230 * between num_perms and the maximum permission number, we
231 * should audit that denial
232 */
233 for (; i < (sizeof(u32)*8); i++)
234 result |= 1<<i;
235 avd->auditdeny = result;
236 }
237}
238
239int security_mls_enabled(void)
240{
241 return policydb.mls_enabled;
242}
243
101/* 244/*
102 * Return the boolean value of a constraint expression 245 * Return the boolean value of a constraint expression
103 * when it is applied to the specified source and target 246 * when it is applied to the specified source and target
@@ -312,7 +455,8 @@ static void security_dump_masked_av(struct context *scontext,
312 char *scontext_name = NULL; 455 char *scontext_name = NULL;
313 char *tcontext_name = NULL; 456 char *tcontext_name = NULL;
314 char *permission_names[32]; 457 char *permission_names[32];
315 int index, length; 458 int index;
459 u32 length;
316 bool need_comma = false; 460 bool need_comma = false;
317 461
318 if (!permissions) 462 if (!permissions)
@@ -379,7 +523,6 @@ out:
379static void type_attribute_bounds_av(struct context *scontext, 523static void type_attribute_bounds_av(struct context *scontext,
380 struct context *tcontext, 524 struct context *tcontext,
381 u16 tclass, 525 u16 tclass,
382 u32 requested,
383 struct av_decision *avd) 526 struct av_decision *avd)
384{ 527{
385 struct context lo_scontext; 528 struct context lo_scontext;
@@ -400,7 +543,6 @@ static void type_attribute_bounds_av(struct context *scontext,
400 context_struct_compute_av(&lo_scontext, 543 context_struct_compute_av(&lo_scontext,
401 tcontext, 544 tcontext,
402 tclass, 545 tclass,
403 requested,
404 &lo_avd); 546 &lo_avd);
405 if ((lo_avd.allowed & avd->allowed) == avd->allowed) 547 if ((lo_avd.allowed & avd->allowed) == avd->allowed)
406 return; /* no masked permission */ 548 return; /* no masked permission */
@@ -416,7 +558,6 @@ static void type_attribute_bounds_av(struct context *scontext,
416 context_struct_compute_av(scontext, 558 context_struct_compute_av(scontext,
417 &lo_tcontext, 559 &lo_tcontext,
418 tclass, 560 tclass,
419 requested,
420 &lo_avd); 561 &lo_avd);
421 if ((lo_avd.allowed & avd->allowed) == avd->allowed) 562 if ((lo_avd.allowed & avd->allowed) == avd->allowed)
422 return; /* no masked permission */ 563 return; /* no masked permission */
@@ -433,7 +574,6 @@ static void type_attribute_bounds_av(struct context *scontext,
433 context_struct_compute_av(&lo_scontext, 574 context_struct_compute_av(&lo_scontext,
434 &lo_tcontext, 575 &lo_tcontext,
435 tclass, 576 tclass,
436 requested,
437 &lo_avd); 577 &lo_avd);
438 if ((lo_avd.allowed & avd->allowed) == avd->allowed) 578 if ((lo_avd.allowed & avd->allowed) == avd->allowed)
439 return; /* no masked permission */ 579 return; /* no masked permission */
@@ -454,11 +594,10 @@ static void type_attribute_bounds_av(struct context *scontext,
454 * Compute access vectors based on a context structure pair for 594 * Compute access vectors based on a context structure pair for
455 * the permissions in a particular class. 595 * the permissions in a particular class.
456 */ 596 */
457static int context_struct_compute_av(struct context *scontext, 597static void context_struct_compute_av(struct context *scontext,
458 struct context *tcontext, 598 struct context *tcontext,
459 u16 tclass, 599 u16 tclass,
460 u32 requested, 600 struct av_decision *avd)
461 struct av_decision *avd)
462{ 601{
463 struct constraint_node *constraint; 602 struct constraint_node *constraint;
464 struct role_allow *ra; 603 struct role_allow *ra;
@@ -467,56 +606,17 @@ static int context_struct_compute_av(struct context *scontext,
467 struct class_datum *tclass_datum; 606 struct class_datum *tclass_datum;
468 struct ebitmap *sattr, *tattr; 607 struct ebitmap *sattr, *tattr;
469 struct ebitmap_node *snode, *tnode; 608 struct ebitmap_node *snode, *tnode;
470 const struct selinux_class_perm *kdefs = &selinux_class_perm;
471 unsigned int i, j; 609 unsigned int i, j;
472 610
473 /*
474 * Remap extended Netlink classes for old policy versions.
475 * Do this here rather than socket_type_to_security_class()
476 * in case a newer policy version is loaded, allowing sockets
477 * to remain in the correct class.
478 */
479 if (policydb_loaded_version < POLICYDB_VERSION_NLCLASS)
480 if (tclass >= SECCLASS_NETLINK_ROUTE_SOCKET &&
481 tclass <= SECCLASS_NETLINK_DNRT_SOCKET)
482 tclass = SECCLASS_NETLINK_SOCKET;
483
484 /*
485 * Initialize the access vectors to the default values.
486 */
487 avd->allowed = 0; 611 avd->allowed = 0;
488 avd->auditallow = 0; 612 avd->auditallow = 0;
489 avd->auditdeny = 0xffffffff; 613 avd->auditdeny = 0xffffffff;
490 avd->seqno = latest_granting;
491 avd->flags = 0;
492 614
493 /* 615 if (unlikely(!tclass || tclass > policydb.p_classes.nprim)) {
494 * Check for all the invalid cases. 616 if (printk_ratelimit())
495 * - tclass 0 617 printk(KERN_WARNING "SELinux: Invalid class %hu\n", tclass);
496 * - tclass > policy and > kernel 618 return;
497 * - tclass > policy but is a userspace class 619 }
498 * - tclass > policy but we do not allow unknowns
499 */
500 if (unlikely(!tclass))
501 goto inval_class;
502 if (unlikely(tclass > policydb.p_classes.nprim))
503 if (tclass > kdefs->cts_len ||
504 !kdefs->class_to_string[tclass] ||
505 !policydb.allow_unknown)
506 goto inval_class;
507
508 /*
509 * Kernel class and we allow unknown so pad the allow decision
510 * the pad will be all 1 for unknown classes.
511 */
512 if (tclass <= kdefs->cts_len && policydb.allow_unknown)
513 avd->allowed = policydb.undefined_perms[tclass - 1];
514
515 /*
516 * Not in policy. Since decision is completed (all 1 or all 0) return.
517 */
518 if (unlikely(tclass > policydb.p_classes.nprim))
519 return 0;
520 620
521 tclass_datum = policydb.class_val_to_struct[tclass - 1]; 621 tclass_datum = policydb.class_val_to_struct[tclass - 1];
522 622
@@ -568,8 +668,8 @@ static int context_struct_compute_av(struct context *scontext,
568 * role is changing, then check the (current_role, new_role) 668 * role is changing, then check the (current_role, new_role)
569 * pair. 669 * pair.
570 */ 670 */
571 if (tclass == SECCLASS_PROCESS && 671 if (tclass == policydb.process_class &&
572 (avd->allowed & (PROCESS__TRANSITION | PROCESS__DYNTRANSITION)) && 672 (avd->allowed & policydb.process_trans_perms) &&
573 scontext->role != tcontext->role) { 673 scontext->role != tcontext->role) {
574 for (ra = policydb.role_allow; ra; ra = ra->next) { 674 for (ra = policydb.role_allow; ra; ra = ra->next) {
575 if (scontext->role == ra->role && 675 if (scontext->role == ra->role &&
@@ -577,8 +677,7 @@ static int context_struct_compute_av(struct context *scontext,
577 break; 677 break;
578 } 678 }
579 if (!ra) 679 if (!ra)
580 avd->allowed &= ~(PROCESS__TRANSITION | 680 avd->allowed &= ~policydb.process_trans_perms;
581 PROCESS__DYNTRANSITION);
582 } 681 }
583 682
584 /* 683 /*
@@ -587,24 +686,7 @@ static int context_struct_compute_av(struct context *scontext,
587 * permission and notice it to userspace via audit. 686 * permission and notice it to userspace via audit.
588 */ 687 */
589 type_attribute_bounds_av(scontext, tcontext, 688 type_attribute_bounds_av(scontext, tcontext,
590 tclass, requested, avd); 689 tclass, avd);
591
592 return 0;
593
594inval_class:
595 if (!tclass || tclass > kdefs->cts_len ||
596 !kdefs->class_to_string[tclass]) {
597 if (printk_ratelimit())
598 printk(KERN_ERR "SELinux: %s: unrecognized class %d\n",
599 __func__, tclass);
600 return -EINVAL;
601 }
602
603 /*
604 * Known to the kernel, but not to the policy.
605 * Handle as a denial (allowed is 0).
606 */
607 return 0;
608} 690}
609 691
610static int security_validtrans_handle_fail(struct context *ocontext, 692static int security_validtrans_handle_fail(struct context *ocontext,
@@ -636,13 +718,14 @@ out:
636} 718}
637 719
638int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, 720int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
639 u16 tclass) 721 u16 orig_tclass)
640{ 722{
641 struct context *ocontext; 723 struct context *ocontext;
642 struct context *ncontext; 724 struct context *ncontext;
643 struct context *tcontext; 725 struct context *tcontext;
644 struct class_datum *tclass_datum; 726 struct class_datum *tclass_datum;
645 struct constraint_node *constraint; 727 struct constraint_node *constraint;
728 u16 tclass;
646 int rc = 0; 729 int rc = 0;
647 730
648 if (!ss_initialized) 731 if (!ss_initialized)
@@ -650,16 +733,7 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
650 733
651 read_lock(&policy_rwlock); 734 read_lock(&policy_rwlock);
652 735
653 /* 736 tclass = unmap_class(orig_tclass);
654 * Remap extended Netlink classes for old policy versions.
655 * Do this here rather than socket_type_to_security_class()
656 * in case a newer policy version is loaded, allowing sockets
657 * to remain in the correct class.
658 */
659 if (policydb_loaded_version < POLICYDB_VERSION_NLCLASS)
660 if (tclass >= SECCLASS_NETLINK_ROUTE_SOCKET &&
661 tclass <= SECCLASS_NETLINK_DNRT_SOCKET)
662 tclass = SECCLASS_NETLINK_SOCKET;
663 737
664 if (!tclass || tclass > policydb.p_classes.nprim) { 738 if (!tclass || tclass > policydb.p_classes.nprim) {
665 printk(KERN_ERR "SELinux: %s: unrecognized class %d\n", 739 printk(KERN_ERR "SELinux: %s: unrecognized class %d\n",
@@ -741,7 +815,7 @@ int security_bounded_transition(u32 old_sid, u32 new_sid)
741 goto out; 815 goto out;
742 } 816 }
743 817
744 /* type/domain unchaned */ 818 /* type/domain unchanged */
745 if (old_context->type == new_context->type) { 819 if (old_context->type == new_context->type) {
746 rc = 0; 820 rc = 0;
747 goto out; 821 goto out;
@@ -769,7 +843,7 @@ int security_bounded_transition(u32 old_sid, u32 new_sid)
769 if (rc) { 843 if (rc) {
770 char *old_name = NULL; 844 char *old_name = NULL;
771 char *new_name = NULL; 845 char *new_name = NULL;
772 int length; 846 u32 length;
773 847
774 if (!context_struct_to_string(old_context, 848 if (!context_struct_to_string(old_context,
775 &old_name, &length) && 849 &old_name, &length) &&
@@ -791,63 +865,116 @@ out:
791 return rc; 865 return rc;
792} 866}
793 867
868static void avd_init(struct av_decision *avd)
869{
870 avd->allowed = 0;
871 avd->auditallow = 0;
872 avd->auditdeny = 0xffffffff;
873 avd->seqno = latest_granting;
874 avd->flags = 0;
875}
876
794 877
795/** 878/**
796 * security_compute_av - Compute access vector decisions. 879 * security_compute_av - Compute access vector decisions.
797 * @ssid: source security identifier 880 * @ssid: source security identifier
798 * @tsid: target security identifier 881 * @tsid: target security identifier
799 * @tclass: target security class 882 * @tclass: target security class
800 * @requested: requested permissions
801 * @avd: access vector decisions 883 * @avd: access vector decisions
802 * 884 *
803 * Compute a set of access vector decisions based on the 885 * Compute a set of access vector decisions based on the
804 * SID pair (@ssid, @tsid) for the permissions in @tclass. 886 * SID pair (@ssid, @tsid) for the permissions in @tclass.
805 * Return -%EINVAL if any of the parameters are invalid or %0
806 * if the access vector decisions were computed successfully.
807 */ 887 */
808int security_compute_av(u32 ssid, 888void security_compute_av(u32 ssid,
809 u32 tsid, 889 u32 tsid,
810 u16 tclass, 890 u16 orig_tclass,
811 u32 requested, 891 struct av_decision *avd)
812 struct av_decision *avd)
813{ 892{
893 u16 tclass;
814 struct context *scontext = NULL, *tcontext = NULL; 894 struct context *scontext = NULL, *tcontext = NULL;
815 int rc = 0;
816
817 if (!ss_initialized) {
818 avd->allowed = 0xffffffff;
819 avd->auditallow = 0;
820 avd->auditdeny = 0xffffffff;
821 avd->seqno = latest_granting;
822 return 0;
823 }
824 895
825 read_lock(&policy_rwlock); 896 read_lock(&policy_rwlock);
897 avd_init(avd);
898 if (!ss_initialized)
899 goto allow;
826 900
827 scontext = sidtab_search(&sidtab, ssid); 901 scontext = sidtab_search(&sidtab, ssid);
828 if (!scontext) { 902 if (!scontext) {
829 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", 903 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
830 __func__, ssid); 904 __func__, ssid);
831 rc = -EINVAL;
832 goto out; 905 goto out;
833 } 906 }
907
908 /* permissive domain? */
909 if (ebitmap_get_bit(&policydb.permissive_map, scontext->type))
910 avd->flags |= AVD_FLAGS_PERMISSIVE;
911
834 tcontext = sidtab_search(&sidtab, tsid); 912 tcontext = sidtab_search(&sidtab, tsid);
835 if (!tcontext) { 913 if (!tcontext) {
836 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", 914 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
837 __func__, tsid); 915 __func__, tsid);
838 rc = -EINVAL;
839 goto out; 916 goto out;
840 } 917 }
841 918
842 rc = context_struct_compute_av(scontext, tcontext, tclass, 919 tclass = unmap_class(orig_tclass);
843 requested, avd); 920 if (unlikely(orig_tclass && !tclass)) {
921 if (policydb.allow_unknown)
922 goto allow;
923 goto out;
924 }
925 context_struct_compute_av(scontext, tcontext, tclass, avd);
926 map_decision(orig_tclass, avd, policydb.allow_unknown);
927out:
928 read_unlock(&policy_rwlock);
929 return;
930allow:
931 avd->allowed = 0xffffffff;
932 goto out;
933}
934
935void security_compute_av_user(u32 ssid,
936 u32 tsid,
937 u16 tclass,
938 struct av_decision *avd)
939{
940 struct context *scontext = NULL, *tcontext = NULL;
941
942 read_lock(&policy_rwlock);
943 avd_init(avd);
944 if (!ss_initialized)
945 goto allow;
946
947 scontext = sidtab_search(&sidtab, ssid);
948 if (!scontext) {
949 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
950 __func__, ssid);
951 goto out;
952 }
844 953
845 /* permissive domain? */ 954 /* permissive domain? */
846 if (ebitmap_get_bit(&policydb.permissive_map, scontext->type)) 955 if (ebitmap_get_bit(&policydb.permissive_map, scontext->type))
847 avd->flags |= AVD_FLAGS_PERMISSIVE; 956 avd->flags |= AVD_FLAGS_PERMISSIVE;
848out: 957
958 tcontext = sidtab_search(&sidtab, tsid);
959 if (!tcontext) {
960 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
961 __func__, tsid);
962 goto out;
963 }
964
965 if (unlikely(!tclass)) {
966 if (policydb.allow_unknown)
967 goto allow;
968 goto out;
969 }
970
971 context_struct_compute_av(scontext, tcontext, tclass, avd);
972 out:
849 read_unlock(&policy_rwlock); 973 read_unlock(&policy_rwlock);
850 return rc; 974 return;
975allow:
976 avd->allowed = 0xffffffff;
977 goto out;
851} 978}
852 979
853/* 980/*
@@ -1204,20 +1331,22 @@ out:
1204 1331
1205static int security_compute_sid(u32 ssid, 1332static int security_compute_sid(u32 ssid,
1206 u32 tsid, 1333 u32 tsid,
1207 u16 tclass, 1334 u16 orig_tclass,
1208 u32 specified, 1335 u32 specified,
1209 u32 *out_sid) 1336 u32 *out_sid,
1337 bool kern)
1210{ 1338{
1211 struct context *scontext = NULL, *tcontext = NULL, newcontext; 1339 struct context *scontext = NULL, *tcontext = NULL, newcontext;
1212 struct role_trans *roletr = NULL; 1340 struct role_trans *roletr = NULL;
1213 struct avtab_key avkey; 1341 struct avtab_key avkey;
1214 struct avtab_datum *avdatum; 1342 struct avtab_datum *avdatum;
1215 struct avtab_node *node; 1343 struct avtab_node *node;
1344 u16 tclass;
1216 int rc = 0; 1345 int rc = 0;
1217 1346
1218 if (!ss_initialized) { 1347 if (!ss_initialized) {
1219 switch (tclass) { 1348 switch (orig_tclass) {
1220 case SECCLASS_PROCESS: 1349 case SECCLASS_PROCESS: /* kernel value */
1221 *out_sid = ssid; 1350 *out_sid = ssid;
1222 break; 1351 break;
1223 default: 1352 default:
@@ -1231,6 +1360,11 @@ static int security_compute_sid(u32 ssid,
1231 1360
1232 read_lock(&policy_rwlock); 1361 read_lock(&policy_rwlock);
1233 1362
1363 if (kern)
1364 tclass = unmap_class(orig_tclass);
1365 else
1366 tclass = orig_tclass;
1367
1234 scontext = sidtab_search(&sidtab, ssid); 1368 scontext = sidtab_search(&sidtab, ssid);
1235 if (!scontext) { 1369 if (!scontext) {
1236 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", 1370 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
@@ -1260,13 +1394,11 @@ static int security_compute_sid(u32 ssid,
1260 } 1394 }
1261 1395
1262 /* Set the role and type to default values. */ 1396 /* Set the role and type to default values. */
1263 switch (tclass) { 1397 if (tclass == policydb.process_class) {
1264 case SECCLASS_PROCESS:
1265 /* Use the current role and type of process. */ 1398 /* Use the current role and type of process. */
1266 newcontext.role = scontext->role; 1399 newcontext.role = scontext->role;
1267 newcontext.type = scontext->type; 1400 newcontext.type = scontext->type;
1268 break; 1401 } else {
1269 default:
1270 /* Use the well-defined object role. */ 1402 /* Use the well-defined object role. */
1271 newcontext.role = OBJECT_R_VAL; 1403 newcontext.role = OBJECT_R_VAL;
1272 /* Use the type of the related object. */ 1404 /* Use the type of the related object. */
@@ -1297,8 +1429,7 @@ static int security_compute_sid(u32 ssid,
1297 } 1429 }
1298 1430
1299 /* Check for class-specific changes. */ 1431 /* Check for class-specific changes. */
1300 switch (tclass) { 1432 if (tclass == policydb.process_class) {
1301 case SECCLASS_PROCESS:
1302 if (specified & AVTAB_TRANSITION) { 1433 if (specified & AVTAB_TRANSITION) {
1303 /* Look for a role transition rule. */ 1434 /* Look for a role transition rule. */
1304 for (roletr = policydb.role_tr; roletr; 1435 for (roletr = policydb.role_tr; roletr;
@@ -1311,9 +1442,6 @@ static int security_compute_sid(u32 ssid,
1311 } 1442 }
1312 } 1443 }
1313 } 1444 }
1314 break;
1315 default:
1316 break;
1317 } 1445 }
1318 1446
1319 /* Set the MLS attributes. 1447 /* Set the MLS attributes.
@@ -1358,7 +1486,17 @@ int security_transition_sid(u32 ssid,
1358 u16 tclass, 1486 u16 tclass,
1359 u32 *out_sid) 1487 u32 *out_sid)
1360{ 1488{
1361 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, out_sid); 1489 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,
1490 out_sid, true);
1491}
1492
1493int security_transition_sid_user(u32 ssid,
1494 u32 tsid,
1495 u16 tclass,
1496 u32 *out_sid)
1497{
1498 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,
1499 out_sid, false);
1362} 1500}
1363 1501
1364/** 1502/**
@@ -1379,7 +1517,8 @@ int security_member_sid(u32 ssid,
1379 u16 tclass, 1517 u16 tclass,
1380 u32 *out_sid) 1518 u32 *out_sid)
1381{ 1519{
1382 return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, out_sid); 1520 return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, out_sid,
1521 false);
1383} 1522}
1384 1523
1385/** 1524/**
@@ -1400,144 +1539,8 @@ int security_change_sid(u32 ssid,
1400 u16 tclass, 1539 u16 tclass,
1401 u32 *out_sid) 1540 u32 *out_sid)
1402{ 1541{
1403 return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, out_sid); 1542 return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, out_sid,
1404} 1543 false);
1405
1406/*
1407 * Verify that each kernel class that is defined in the
1408 * policy is correct
1409 */
1410static int validate_classes(struct policydb *p)
1411{
1412 int i, j;
1413 struct class_datum *cladatum;
1414 struct perm_datum *perdatum;
1415 u32 nprim, tmp, common_pts_len, perm_val, pol_val;
1416 u16 class_val;
1417 const struct selinux_class_perm *kdefs = &selinux_class_perm;
1418 const char *def_class, *def_perm, *pol_class;
1419 struct symtab *perms;
1420 bool print_unknown_handle = 0;
1421
1422 if (p->allow_unknown) {
1423 u32 num_classes = kdefs->cts_len;
1424 p->undefined_perms = kcalloc(num_classes, sizeof(u32), GFP_KERNEL);
1425 if (!p->undefined_perms)
1426 return -ENOMEM;
1427 }
1428
1429 for (i = 1; i < kdefs->cts_len; i++) {
1430 def_class = kdefs->class_to_string[i];
1431 if (!def_class)
1432 continue;
1433 if (i > p->p_classes.nprim) {
1434 printk(KERN_INFO
1435 "SELinux: class %s not defined in policy\n",
1436 def_class);
1437 if (p->reject_unknown)
1438 return -EINVAL;
1439 if (p->allow_unknown)
1440 p->undefined_perms[i-1] = ~0U;
1441 print_unknown_handle = 1;
1442 continue;
1443 }
1444 pol_class = p->p_class_val_to_name[i-1];
1445 if (strcmp(pol_class, def_class)) {
1446 printk(KERN_ERR
1447 "SELinux: class %d is incorrect, found %s but should be %s\n",
1448 i, pol_class, def_class);
1449 return -EINVAL;
1450 }
1451 }
1452 for (i = 0; i < kdefs->av_pts_len; i++) {
1453 class_val = kdefs->av_perm_to_string[i].tclass;
1454 perm_val = kdefs->av_perm_to_string[i].value;
1455 def_perm = kdefs->av_perm_to_string[i].name;
1456 if (class_val > p->p_classes.nprim)
1457 continue;
1458 pol_class = p->p_class_val_to_name[class_val-1];
1459 cladatum = hashtab_search(p->p_classes.table, pol_class);
1460 BUG_ON(!cladatum);
1461 perms = &cladatum->permissions;
1462 nprim = 1 << (perms->nprim - 1);
1463 if (perm_val > nprim) {
1464 printk(KERN_INFO
1465 "SELinux: permission %s in class %s not defined in policy\n",
1466 def_perm, pol_class);
1467 if (p->reject_unknown)
1468 return -EINVAL;
1469 if (p->allow_unknown)
1470 p->undefined_perms[class_val-1] |= perm_val;
1471 print_unknown_handle = 1;
1472 continue;
1473 }
1474 perdatum = hashtab_search(perms->table, def_perm);
1475 if (perdatum == NULL) {
1476 printk(KERN_ERR
1477 "SELinux: permission %s in class %s not found in policy, bad policy\n",
1478 def_perm, pol_class);
1479 return -EINVAL;
1480 }
1481 pol_val = 1 << (perdatum->value - 1);
1482 if (pol_val != perm_val) {
1483 printk(KERN_ERR
1484 "SELinux: permission %s in class %s has incorrect value\n",
1485 def_perm, pol_class);
1486 return -EINVAL;
1487 }
1488 }
1489 for (i = 0; i < kdefs->av_inherit_len; i++) {
1490 class_val = kdefs->av_inherit[i].tclass;
1491 if (class_val > p->p_classes.nprim)
1492 continue;
1493 pol_class = p->p_class_val_to_name[class_val-1];
1494 cladatum = hashtab_search(p->p_classes.table, pol_class);
1495 BUG_ON(!cladatum);
1496 if (!cladatum->comdatum) {
1497 printk(KERN_ERR
1498 "SELinux: class %s should have an inherits clause but does not\n",
1499 pol_class);
1500 return -EINVAL;
1501 }
1502 tmp = kdefs->av_inherit[i].common_base;
1503 common_pts_len = 0;
1504 while (!(tmp & 0x01)) {
1505 common_pts_len++;
1506 tmp >>= 1;
1507 }
1508 perms = &cladatum->comdatum->permissions;
1509 for (j = 0; j < common_pts_len; j++) {
1510 def_perm = kdefs->av_inherit[i].common_pts[j];
1511 if (j >= perms->nprim) {
1512 printk(KERN_INFO
1513 "SELinux: permission %s in class %s not defined in policy\n",
1514 def_perm, pol_class);
1515 if (p->reject_unknown)
1516 return -EINVAL;
1517 if (p->allow_unknown)
1518 p->undefined_perms[class_val-1] |= (1 << j);
1519 print_unknown_handle = 1;
1520 continue;
1521 }
1522 perdatum = hashtab_search(perms->table, def_perm);
1523 if (perdatum == NULL) {
1524 printk(KERN_ERR
1525 "SELinux: permission %s in class %s not found in policy, bad policy\n",
1526 def_perm, pol_class);
1527 return -EINVAL;
1528 }
1529 if (perdatum->value != j + 1) {
1530 printk(KERN_ERR
1531 "SELinux: permission %s in class %s has incorrect value\n",
1532 def_perm, pol_class);
1533 return -EINVAL;
1534 }
1535 }
1536 }
1537 if (print_unknown_handle)
1538 printk(KERN_INFO "SELinux: the above unknown classes and permissions will be %s\n",
1539 (security_get_allow_unknown() ? "allowed" : "denied"));
1540 return 0;
1541} 1544}
1542 1545
1543/* Clone the SID into the new SID table. */ 1546/* Clone the SID into the new SID table. */
@@ -1547,7 +1550,10 @@ static int clone_sid(u32 sid,
1547{ 1550{
1548 struct sidtab *s = arg; 1551 struct sidtab *s = arg;
1549 1552
1550 return sidtab_insert(s, sid, context); 1553 if (sid > SECINITSID_NUM)
1554 return sidtab_insert(s, sid, context);
1555 else
1556 return 0;
1551} 1557}
1552 1558
1553static inline int convert_context_handle_invalid_context(struct context *context) 1559static inline int convert_context_handle_invalid_context(struct context *context)
@@ -1588,12 +1594,17 @@ static int convert_context(u32 key,
1588{ 1594{
1589 struct convert_context_args *args; 1595 struct convert_context_args *args;
1590 struct context oldc; 1596 struct context oldc;
1597 struct ocontext *oc;
1598 struct mls_range *range;
1591 struct role_datum *role; 1599 struct role_datum *role;
1592 struct type_datum *typdatum; 1600 struct type_datum *typdatum;
1593 struct user_datum *usrdatum; 1601 struct user_datum *usrdatum;
1594 char *s; 1602 char *s;
1595 u32 len; 1603 u32 len;
1596 int rc; 1604 int rc = 0;
1605
1606 if (key <= SECINITSID_NUM)
1607 goto out;
1597 1608
1598 args = p; 1609 args = p;
1599 1610
@@ -1655,9 +1666,39 @@ static int convert_context(u32 key,
1655 goto bad; 1666 goto bad;
1656 c->type = typdatum->value; 1667 c->type = typdatum->value;
1657 1668
1658 rc = mls_convert_context(args->oldp, args->newp, c); 1669 /* Convert the MLS fields if dealing with MLS policies */
1659 if (rc) 1670 if (args->oldp->mls_enabled && args->newp->mls_enabled) {
1660 goto bad; 1671 rc = mls_convert_context(args->oldp, args->newp, c);
1672 if (rc)
1673 goto bad;
1674 } else if (args->oldp->mls_enabled && !args->newp->mls_enabled) {
1675 /*
1676 * Switching between MLS and non-MLS policy:
1677 * free any storage used by the MLS fields in the
1678 * context for all existing entries in the sidtab.
1679 */
1680 mls_context_destroy(c);
1681 } else if (!args->oldp->mls_enabled && args->newp->mls_enabled) {
1682 /*
1683 * Switching between non-MLS and MLS policy:
1684 * ensure that the MLS fields of the context for all
1685 * existing entries in the sidtab are filled in with a
1686 * suitable default value, likely taken from one of the
1687 * initial SIDs.
1688 */
1689 oc = args->newp->ocontexts[OCON_ISID];
1690 while (oc && oc->sid[0] != SECINITSID_UNLABELED)
1691 oc = oc->next;
1692 if (!oc) {
1693 printk(KERN_ERR "SELinux: unable to look up"
1694 " the initial SIDs list\n");
1695 goto bad;
1696 }
1697 range = &oc->context[0].range;
1698 rc = mls_range_set(c, range);
1699 if (rc)
1700 goto bad;
1701 }
1661 1702
1662 /* Check the validity of the new context. */ 1703 /* Check the validity of the new context. */
1663 if (!policydb_context_isvalid(args->newp, c)) { 1704 if (!policydb_context_isvalid(args->newp, c)) {
@@ -1710,8 +1751,10 @@ int security_load_policy(void *data, size_t len)
1710{ 1751{
1711 struct policydb oldpolicydb, newpolicydb; 1752 struct policydb oldpolicydb, newpolicydb;
1712 struct sidtab oldsidtab, newsidtab; 1753 struct sidtab oldsidtab, newsidtab;
1754 struct selinux_mapping *oldmap, *map = NULL;
1713 struct convert_context_args args; 1755 struct convert_context_args args;
1714 u32 seqno; 1756 u32 seqno;
1757 u16 map_size;
1715 int rc = 0; 1758 int rc = 0;
1716 struct policy_file file = { data, len }, *fp = &file; 1759 struct policy_file file = { data, len }, *fp = &file;
1717 1760
@@ -1721,22 +1764,19 @@ int security_load_policy(void *data, size_t len)
1721 avtab_cache_destroy(); 1764 avtab_cache_destroy();
1722 return -EINVAL; 1765 return -EINVAL;
1723 } 1766 }
1724 if (policydb_load_isids(&policydb, &sidtab)) { 1767 if (selinux_set_mapping(&policydb, secclass_map,
1768 &current_mapping,
1769 &current_mapping_size)) {
1725 policydb_destroy(&policydb); 1770 policydb_destroy(&policydb);
1726 avtab_cache_destroy(); 1771 avtab_cache_destroy();
1727 return -EINVAL; 1772 return -EINVAL;
1728 } 1773 }
1729 /* Verify that the kernel defined classes are correct. */ 1774 if (policydb_load_isids(&policydb, &sidtab)) {
1730 if (validate_classes(&policydb)) {
1731 printk(KERN_ERR
1732 "SELinux: the definition of a class is incorrect\n");
1733 sidtab_destroy(&sidtab);
1734 policydb_destroy(&policydb); 1775 policydb_destroy(&policydb);
1735 avtab_cache_destroy(); 1776 avtab_cache_destroy();
1736 return -EINVAL; 1777 return -EINVAL;
1737 } 1778 }
1738 security_load_policycaps(); 1779 security_load_policycaps();
1739 policydb_loaded_version = policydb.policyvers;
1740 ss_initialized = 1; 1780 ss_initialized = 1;
1741 seqno = ++latest_granting; 1781 seqno = ++latest_granting;
1742 selinux_complete_init(); 1782 selinux_complete_init();
@@ -1754,18 +1794,22 @@ int security_load_policy(void *data, size_t len)
1754 if (policydb_read(&newpolicydb, fp)) 1794 if (policydb_read(&newpolicydb, fp))
1755 return -EINVAL; 1795 return -EINVAL;
1756 1796
1757 if (sidtab_init(&newsidtab)) { 1797 /* If switching between different policy types, log MLS status */
1798 if (policydb.mls_enabled && !newpolicydb.mls_enabled)
1799 printk(KERN_INFO "SELinux: Disabling MLS support...\n");
1800 else if (!policydb.mls_enabled && newpolicydb.mls_enabled)
1801 printk(KERN_INFO "SELinux: Enabling MLS support...\n");
1802
1803 rc = policydb_load_isids(&newpolicydb, &newsidtab);
1804 if (rc) {
1805 printk(KERN_ERR "SELinux: unable to load the initial SIDs\n");
1758 policydb_destroy(&newpolicydb); 1806 policydb_destroy(&newpolicydb);
1759 return -ENOMEM; 1807 return rc;
1760 } 1808 }
1761 1809
1762 /* Verify that the kernel defined classes are correct. */ 1810 if (selinux_set_mapping(&newpolicydb, secclass_map,
1763 if (validate_classes(&newpolicydb)) { 1811 &map, &map_size))
1764 printk(KERN_ERR
1765 "SELinux: the definition of a class is incorrect\n");
1766 rc = -EINVAL;
1767 goto err; 1812 goto err;
1768 }
1769 1813
1770 rc = security_preserve_bools(&newpolicydb); 1814 rc = security_preserve_bools(&newpolicydb);
1771 if (rc) { 1815 if (rc) {
@@ -1787,8 +1831,12 @@ int security_load_policy(void *data, size_t len)
1787 args.oldp = &policydb; 1831 args.oldp = &policydb;
1788 args.newp = &newpolicydb; 1832 args.newp = &newpolicydb;
1789 rc = sidtab_map(&newsidtab, convert_context, &args); 1833 rc = sidtab_map(&newsidtab, convert_context, &args);
1790 if (rc) 1834 if (rc) {
1835 printk(KERN_ERR "SELinux: unable to convert the internal"
1836 " representation of contexts in the new SID"
1837 " table\n");
1791 goto err; 1838 goto err;
1839 }
1792 1840
1793 /* Save the old policydb and SID table to free later. */ 1841 /* Save the old policydb and SID table to free later. */
1794 memcpy(&oldpolicydb, &policydb, sizeof policydb); 1842 memcpy(&oldpolicydb, &policydb, sizeof policydb);
@@ -1799,13 +1847,16 @@ int security_load_policy(void *data, size_t len)
1799 memcpy(&policydb, &newpolicydb, sizeof policydb); 1847 memcpy(&policydb, &newpolicydb, sizeof policydb);
1800 sidtab_set(&sidtab, &newsidtab); 1848 sidtab_set(&sidtab, &newsidtab);
1801 security_load_policycaps(); 1849 security_load_policycaps();
1850 oldmap = current_mapping;
1851 current_mapping = map;
1852 current_mapping_size = map_size;
1802 seqno = ++latest_granting; 1853 seqno = ++latest_granting;
1803 policydb_loaded_version = policydb.policyvers;
1804 write_unlock_irq(&policy_rwlock); 1854 write_unlock_irq(&policy_rwlock);
1805 1855
1806 /* Free the old policydb and SID table. */ 1856 /* Free the old policydb and SID table. */
1807 policydb_destroy(&oldpolicydb); 1857 policydb_destroy(&oldpolicydb);
1808 sidtab_destroy(&oldsidtab); 1858 sidtab_destroy(&oldsidtab);
1859 kfree(oldmap);
1809 1860
1810 avc_ss_reset(seqno); 1861 avc_ss_reset(seqno);
1811 selnl_notify_policyload(seqno); 1862 selnl_notify_policyload(seqno);
@@ -1815,6 +1866,7 @@ int security_load_policy(void *data, size_t len)
1815 return 0; 1866 return 0;
1816 1867
1817err: 1868err:
1869 kfree(map);
1818 sidtab_destroy(&newsidtab); 1870 sidtab_destroy(&newsidtab);
1819 policydb_destroy(&newpolicydb); 1871 policydb_destroy(&newpolicydb);
1820 return rc; 1872 return rc;
@@ -2091,7 +2143,7 @@ out_unlock:
2091 } 2143 }
2092 for (i = 0, j = 0; i < mynel; i++) { 2144 for (i = 0, j = 0; i < mynel; i++) {
2093 rc = avc_has_perm_noaudit(fromsid, mysids[i], 2145 rc = avc_has_perm_noaudit(fromsid, mysids[i],
2094 SECCLASS_PROCESS, 2146 SECCLASS_PROCESS, /* kernel value */
2095 PROCESS__TRANSITION, AVC_STRICT, 2147 PROCESS__TRANSITION, AVC_STRICT,
2096 NULL); 2148 NULL);
2097 if (!rc) 2149 if (!rc)
@@ -2119,10 +2171,11 @@ out:
2119 */ 2171 */
2120int security_genfs_sid(const char *fstype, 2172int security_genfs_sid(const char *fstype,
2121 char *path, 2173 char *path,
2122 u16 sclass, 2174 u16 orig_sclass,
2123 u32 *sid) 2175 u32 *sid)
2124{ 2176{
2125 int len; 2177 int len;
2178 u16 sclass;
2126 struct genfs *genfs; 2179 struct genfs *genfs;
2127 struct ocontext *c; 2180 struct ocontext *c;
2128 int rc = 0, cmp = 0; 2181 int rc = 0, cmp = 0;
@@ -2132,6 +2185,8 @@ int security_genfs_sid(const char *fstype,
2132 2185
2133 read_lock(&policy_rwlock); 2186 read_lock(&policy_rwlock);
2134 2187
2188 sclass = unmap_class(orig_sclass);
2189
2135 for (genfs = policydb.genfs; genfs; genfs = genfs->next) { 2190 for (genfs = policydb.genfs; genfs; genfs = genfs->next) {
2136 cmp = strcmp(fstype, genfs->fstype); 2191 cmp = strcmp(fstype, genfs->fstype);
2137 if (cmp <= 0) 2192 if (cmp <= 0)
@@ -2377,7 +2432,7 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid)
2377 u32 len; 2432 u32 len;
2378 int rc = 0; 2433 int rc = 0;
2379 2434
2380 if (!ss_initialized || !selinux_mls_enabled) { 2435 if (!ss_initialized || !policydb.mls_enabled) {
2381 *new_sid = sid; 2436 *new_sid = sid;
2382 goto out; 2437 goto out;
2383 } 2438 }
@@ -2478,7 +2533,7 @@ int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type,
2478 /* we don't need to check ss_initialized here since the only way both 2533 /* we don't need to check ss_initialized here since the only way both
2479 * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the 2534 * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the
2480 * security server was initialized and ss_initialized was true */ 2535 * security server was initialized and ss_initialized was true */
2481 if (!selinux_mls_enabled) { 2536 if (!policydb.mls_enabled) {
2482 *peer_sid = SECSID_NULL; 2537 *peer_sid = SECSID_NULL;
2483 return 0; 2538 return 0;
2484 } 2539 }
@@ -2535,7 +2590,7 @@ int security_get_classes(char ***classes, int *nclasses)
2535 read_lock(&policy_rwlock); 2590 read_lock(&policy_rwlock);
2536 2591
2537 *nclasses = policydb.p_classes.nprim; 2592 *nclasses = policydb.p_classes.nprim;
2538 *classes = kcalloc(*nclasses, sizeof(*classes), GFP_ATOMIC); 2593 *classes = kcalloc(*nclasses, sizeof(**classes), GFP_ATOMIC);
2539 if (!*classes) 2594 if (!*classes)
2540 goto out; 2595 goto out;
2541 2596
@@ -2582,7 +2637,7 @@ int security_get_permissions(char *class, char ***perms, int *nperms)
2582 } 2637 }
2583 2638
2584 *nperms = match->permissions.nprim; 2639 *nperms = match->permissions.nprim;
2585 *perms = kcalloc(*nperms, sizeof(*perms), GFP_ATOMIC); 2640 *perms = kcalloc(*nperms, sizeof(**perms), GFP_ATOMIC);
2586 if (!*perms) 2641 if (!*perms)
2587 goto out; 2642 goto out;
2588 2643
diff --git a/security/selinux/ss/symtab.c b/security/selinux/ss/symtab.c
index 837658a98a54..bcf9f620426e 100644
--- a/security/selinux/ss/symtab.c
+++ b/security/selinux/ss/symtab.c
@@ -4,7 +4,6 @@
4 * Author : Stephen Smalley, <sds@epoch.ncsc.mil> 4 * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
5 */ 5 */
6#include <linux/kernel.h> 6#include <linux/kernel.h>
7#include <linux/slab.h>
8#include <linux/string.h> 7#include <linux/string.h>
9#include <linux/errno.h> 8#include <linux/errno.h>
10#include "symtab.h" 9#include "symtab.h"