aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorGuido Trentalancia <guido@trentalancia.com>2010-02-03 10:40:20 -0500
committerJames Morris <jmorris@namei.org>2010-02-03 17:06:36 -0500
commit0719aaf5ead7555b7b7a4a080ebf2826a871384e (patch)
tree19c0b16b1013d84a8b8092737d38e60f3dd7e939 /security
parent42596eafdd75257a640f64701b9b07090bcd84b0 (diff)
selinux: allow MLS->non-MLS and vice versa upon policy reload
Allow runtime switching between different policy types (e.g. from a MLS/MCS policy to a non-MLS/non-MCS policy or viceversa). Signed-off-by: Guido Trentalancia <guido@trentalancia.com> Acked-by: Stephen Smalley <sds@tycho.nsa.gov> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security')
-rw-r--r--security/selinux/include/security.h3
-rw-r--r--security/selinux/selinuxfs.c3
-rw-r--r--security/selinux/ss/context.h12
-rw-r--r--security/selinux/ss/mls.c26
-rw-r--r--security/selinux/ss/mls.h2
-rw-r--r--security/selinux/ss/mls_types.h7
-rw-r--r--security/selinux/ss/policydb.c24
-rw-r--r--security/selinux/ss/policydb.h4
-rw-r--r--security/selinux/ss/services.c62
9 files changed, 84 insertions, 59 deletions
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 022cf067aa3f..1f7c2491d3dc 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -57,7 +57,6 @@
57struct netlbl_lsm_secattr; 57struct netlbl_lsm_secattr;
58 58
59extern int selinux_enabled; 59extern int selinux_enabled;
60extern int selinux_mls_enabled;
61 60
62/* Policy capabilities */ 61/* Policy capabilities */
63enum { 62enum {
@@ -80,6 +79,8 @@ extern int selinux_policycap_openperm;
80/* limitation of boundary depth */ 79/* limitation of boundary depth */
81#define POLICYDB_BOUNDS_MAXDEPTH 4 80#define POLICYDB_BOUNDS_MAXDEPTH 4
82 81
82int security_mls_enabled(void);
83
83int security_load_policy(void *data, size_t len); 84int security_load_policy(void *data, size_t len);
84 85
85int security_policycap_supported(unsigned int req_cap); 86int security_policycap_supported(unsigned int req_cap);
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index b7bb0f5ec07c..a1cfc464bbb9 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -282,7 +282,8 @@ static ssize_t sel_read_mls(struct file *filp, char __user *buf,
282 char tmpbuf[TMPBUFLEN]; 282 char tmpbuf[TMPBUFLEN];
283 ssize_t length; 283 ssize_t length;
284 284
285 length = scnprintf(tmpbuf, TMPBUFLEN, "%d", selinux_mls_enabled); 285 length = scnprintf(tmpbuf, TMPBUFLEN, "%d",
286 security_mls_enabled());
286 return simple_read_from_buffer(buf, count, ppos, tmpbuf, length); 287 return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
287} 288}
288 289
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/mls.c b/security/selinux/ss/mls.c
index 443ae7370144..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++) {
@@ -516,7 +516,7 @@ int mls_compute_sid(struct context *scontext,
516 struct range_trans rtr; 516 struct range_trans rtr;
517 struct mls_range *r; 517 struct mls_range *r;
518 518
519 if (!selinux_mls_enabled) 519 if (!policydb.mls_enabled)
520 return 0; 520 return 0;
521 521
522 switch (specified) { 522 switch (specified) {
@@ -559,7 +559,7 @@ int mls_compute_sid(struct context *scontext,
559void mls_export_netlbl_lvl(struct context *context, 559void mls_export_netlbl_lvl(struct context *context,
560 struct netlbl_lsm_secattr *secattr) 560 struct netlbl_lsm_secattr *secattr)
561{ 561{
562 if (!selinux_mls_enabled) 562 if (!policydb.mls_enabled)
563 return; 563 return;
564 564
565 secattr->attr.mls.lvl = context->range.level[0].sens - 1; 565 secattr->attr.mls.lvl = context->range.level[0].sens - 1;
@@ -579,7 +579,7 @@ void mls_export_netlbl_lvl(struct context *context,
579void mls_import_netlbl_lvl(struct context *context, 579void mls_import_netlbl_lvl(struct context *context,
580 struct netlbl_lsm_secattr *secattr) 580 struct netlbl_lsm_secattr *secattr)
581{ 581{
582 if (!selinux_mls_enabled) 582 if (!policydb.mls_enabled)
583 return; 583 return;
584 584
585 context->range.level[0].sens = secattr->attr.mls.lvl + 1; 585 context->range.level[0].sens = secattr->attr.mls.lvl + 1;
@@ -601,7 +601,7 @@ int mls_export_netlbl_cat(struct context *context,
601{ 601{
602 int rc; 602 int rc;
603 603
604 if (!selinux_mls_enabled) 604 if (!policydb.mls_enabled)
605 return 0; 605 return 0;
606 606
607 rc = ebitmap_netlbl_export(&context->range.level[0].cat, 607 rc = ebitmap_netlbl_export(&context->range.level[0].cat,
@@ -629,7 +629,7 @@ int mls_import_netlbl_cat(struct context *context,
629{ 629{
630 int rc; 630 int rc;
631 631
632 if (!selinux_mls_enabled) 632 if (!policydb.mls_enabled)
633 return 0; 633 return 0;
634 634
635 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 5b92c0219207..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,
@@ -455,7 +453,7 @@ static int policydb_index_others(struct policydb *p)
455 453
456 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",
457 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);
458 if (selinux_mls_enabled) 456 if (p->mls_enabled)
459 printk(", %d sens, %d cats", p->p_levels.nprim, 457 printk(", %d sens, %d cats", p->p_levels.nprim,
460 p->p_cats.nprim); 458 p->p_cats.nprim);
461 printk("\n"); 459 printk("\n");
@@ -1717,14 +1715,12 @@ int policydb_read(struct policydb *p, void *fp)
1717 int i, j, rc; 1715 int i, j, rc;
1718 __le32 buf[4]; 1716 __le32 buf[4];
1719 u32 nodebuf[8]; 1717 u32 nodebuf[8];
1720 u32 len, len2, config, nprim, nel, nel2; 1718 u32 len, len2, nprim, nel, nel2;
1721 char *policydb_str; 1719 char *policydb_str;
1722 struct policydb_compat_info *info; 1720 struct policydb_compat_info *info;
1723 struct range_trans *rt; 1721 struct range_trans *rt;
1724 struct mls_range *r; 1722 struct mls_range *r;
1725 1723
1726 config = 0;
1727
1728 rc = policydb_init(p); 1724 rc = policydb_init(p);
1729 if (rc) 1725 if (rc)
1730 goto out; 1726 goto out;
@@ -1772,7 +1768,7 @@ int policydb_read(struct policydb *p, void *fp)
1772 kfree(policydb_str); 1768 kfree(policydb_str);
1773 policydb_str = NULL; 1769 policydb_str = NULL;
1774 1770
1775 /* Read the version, config, and table sizes. */ 1771 /* Read the version and table sizes. */
1776 rc = next_entry(buf, fp, sizeof(u32)*4); 1772 rc = next_entry(buf, fp, sizeof(u32)*4);
1777 if (rc < 0) 1773 if (rc < 0)
1778 goto bad; 1774 goto bad;
@@ -1787,13 +1783,7 @@ int policydb_read(struct policydb *p, void *fp)
1787 } 1783 }
1788 1784
1789 if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) { 1785 if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) {
1790 if (ss_initialized && !selinux_mls_enabled) { 1786 p->mls_enabled = 1;
1791 printk(KERN_ERR "SELinux: Cannot switch between non-MLS"
1792 " and MLS policies\n");
1793 goto bad;
1794 }
1795 selinux_mls_enabled = 1;
1796 config |= POLICYDB_CONFIG_MLS;
1797 1787
1798 if (p->policyvers < POLICYDB_VERSION_MLS) { 1788 if (p->policyvers < POLICYDB_VERSION_MLS) {
1799 printk(KERN_ERR "SELinux: security policydb version %d " 1789 printk(KERN_ERR "SELinux: security policydb version %d "
@@ -1801,12 +1791,6 @@ int policydb_read(struct policydb *p, void *fp)
1801 p->policyvers); 1791 p->policyvers);
1802 goto bad; 1792 goto bad;
1803 } 1793 }
1804 } else {
1805 if (ss_initialized && selinux_mls_enabled) {
1806 printk(KERN_ERR "SELinux: Cannot switch between MLS and"
1807 " non-MLS policies\n");
1808 goto bad;
1809 }
1810 } 1794 }
1811 p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN); 1795 p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN);
1812 p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN); 1796 p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN);
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index 193736b64de8..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
@@ -185,6 +187,8 @@ struct genfs {
185 187
186/* The policy database */ 188/* The policy database */
187struct policydb { 189struct policydb {
190 int mls_enabled;
191
188 /* symbol tables */ 192 /* symbol tables */
189 struct symtab symtab[SYM_NUM]; 193 struct symtab symtab[SYM_NUM];
190#define p_commons symtab[SYM_COMMONS] 194#define p_commons symtab[SYM_COMMONS]
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 2abbc49914e6..4e976f58b980 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.
@@ -232,6 +236,10 @@ static void map_decision(u16 tclass, struct av_decision *avd,
232 } 236 }
233} 237}
234 238
239int security_mls_enabled(void)
240{
241 return policydb.mls_enabled;
242}
235 243
236/* 244/*
237 * Return the boolean value of a constraint expression 245 * Return the boolean value of a constraint expression
@@ -1550,6 +1558,8 @@ static int convert_context(u32 key,
1550{ 1558{
1551 struct convert_context_args *args; 1559 struct convert_context_args *args;
1552 struct context oldc; 1560 struct context oldc;
1561 struct ocontext *oc;
1562 struct mls_range *range;
1553 struct role_datum *role; 1563 struct role_datum *role;
1554 struct type_datum *typdatum; 1564 struct type_datum *typdatum;
1555 struct user_datum *usrdatum; 1565 struct user_datum *usrdatum;
@@ -1620,9 +1630,39 @@ static int convert_context(u32 key,
1620 goto bad; 1630 goto bad;
1621 c->type = typdatum->value; 1631 c->type = typdatum->value;
1622 1632
1623 rc = mls_convert_context(args->oldp, args->newp, c); 1633 /* Convert the MLS fields if dealing with MLS policies */
1624 if (rc) 1634 if (args->oldp->mls_enabled && args->newp->mls_enabled) {
1625 goto bad; 1635 rc = mls_convert_context(args->oldp, args->newp, c);
1636 if (rc)
1637 goto bad;
1638 } else if (args->oldp->mls_enabled && !args->newp->mls_enabled) {
1639 /*
1640 * Switching between MLS and non-MLS policy:
1641 * free any storage used by the MLS fields in the
1642 * context for all existing entries in the sidtab.
1643 */
1644 mls_context_destroy(c);
1645 } else if (!args->oldp->mls_enabled && args->newp->mls_enabled) {
1646 /*
1647 * Switching between non-MLS and MLS policy:
1648 * ensure that the MLS fields of the context for all
1649 * existing entries in the sidtab are filled in with a
1650 * suitable default value, likely taken from one of the
1651 * initial SIDs.
1652 */
1653 oc = args->newp->ocontexts[OCON_ISID];
1654 while (oc && oc->sid[0] != SECINITSID_UNLABELED)
1655 oc = oc->next;
1656 if (!oc) {
1657 printk(KERN_ERR "SELinux: unable to look up"
1658 " the initial SIDs list\n");
1659 goto bad;
1660 }
1661 range = &oc->context[0].range;
1662 rc = mls_range_set(c, range);
1663 if (rc)
1664 goto bad;
1665 }
1626 1666
1627 /* Check the validity of the new context. */ 1667 /* Check the validity of the new context. */
1628 if (!policydb_context_isvalid(args->newp, c)) { 1668 if (!policydb_context_isvalid(args->newp, c)) {
@@ -1718,6 +1758,12 @@ int security_load_policy(void *data, size_t len)
1718 if (policydb_read(&newpolicydb, fp)) 1758 if (policydb_read(&newpolicydb, fp))
1719 return -EINVAL; 1759 return -EINVAL;
1720 1760
1761 /* If switching between different policy types, log MLS status */
1762 if (policydb.mls_enabled && !newpolicydb.mls_enabled)
1763 printk(KERN_INFO "SELinux: Disabling MLS support...\n");
1764 else if (!policydb.mls_enabled && newpolicydb.mls_enabled)
1765 printk(KERN_INFO "SELinux: Enabling MLS support...\n");
1766
1721 rc = policydb_load_isids(&newpolicydb, &newsidtab); 1767 rc = policydb_load_isids(&newpolicydb, &newsidtab);
1722 if (rc) { 1768 if (rc) {
1723 printk(KERN_ERR "SELinux: unable to load the initial SIDs\n"); 1769 printk(KERN_ERR "SELinux: unable to load the initial SIDs\n");
@@ -1749,8 +1795,12 @@ int security_load_policy(void *data, size_t len)
1749 args.oldp = &policydb; 1795 args.oldp = &policydb;
1750 args.newp = &newpolicydb; 1796 args.newp = &newpolicydb;
1751 rc = sidtab_map(&newsidtab, convert_context, &args); 1797 rc = sidtab_map(&newsidtab, convert_context, &args);
1752 if (rc) 1798 if (rc) {
1799 printk(KERN_ERR "SELinux: unable to convert the internal"
1800 " representation of contexts in the new SID"
1801 " table\n");
1753 goto err; 1802 goto err;
1803 }
1754 1804
1755 /* Save the old policydb and SID table to free later. */ 1805 /* Save the old policydb and SID table to free later. */
1756 memcpy(&oldpolicydb, &policydb, sizeof policydb); 1806 memcpy(&oldpolicydb, &policydb, sizeof policydb);
@@ -2346,7 +2396,7 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid)
2346 u32 len; 2396 u32 len;
2347 int rc = 0; 2397 int rc = 0;
2348 2398
2349 if (!ss_initialized || !selinux_mls_enabled) { 2399 if (!ss_initialized || !policydb.mls_enabled) {
2350 *new_sid = sid; 2400 *new_sid = sid;
2351 goto out; 2401 goto out;
2352 } 2402 }
@@ -2447,7 +2497,7 @@ int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type,
2447 /* we don't need to check ss_initialized here since the only way both 2497 /* we don't need to check ss_initialized here since the only way both
2448 * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the 2498 * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the
2449 * security server was initialized and ss_initialized was true */ 2499 * security server was initialized and ss_initialized was true */
2450 if (!selinux_mls_enabled) { 2500 if (!policydb.mls_enabled) {
2451 *peer_sid = SECSID_NULL; 2501 *peer_sid = SECSID_NULL;
2452 return 0; 2502 return 0;
2453 } 2503 }