diff options
| author | Guido Trentalancia <guido@trentalancia.com> | 2010-02-03 10:40:20 -0500 |
|---|---|---|
| committer | James Morris <jmorris@namei.org> | 2010-02-03 17:06:36 -0500 |
| commit | 0719aaf5ead7555b7b7a4a080ebf2826a871384e (patch) | |
| tree | 19c0b16b1013d84a8b8092737d38e60f3dd7e939 /security | |
| parent | 42596eafdd75257a640f64701b9b07090bcd84b0 (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.h | 3 | ||||
| -rw-r--r-- | security/selinux/selinuxfs.c | 3 | ||||
| -rw-r--r-- | security/selinux/ss/context.h | 12 | ||||
| -rw-r--r-- | security/selinux/ss/mls.c | 26 | ||||
| -rw-r--r-- | security/selinux/ss/mls.h | 2 | ||||
| -rw-r--r-- | security/selinux/ss/mls_types.h | 7 | ||||
| -rw-r--r-- | security/selinux/ss/policydb.c | 24 | ||||
| -rw-r--r-- | security/selinux/ss/policydb.h | 4 | ||||
| -rw-r--r-- | security/selinux/ss/services.c | 62 |
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 @@ | |||
| 57 | struct netlbl_lsm_secattr; | 57 | struct netlbl_lsm_secattr; |
| 58 | 58 | ||
| 59 | extern int selinux_enabled; | 59 | extern int selinux_enabled; |
| 60 | extern int selinux_mls_enabled; | ||
| 61 | 60 | ||
| 62 | /* Policy capabilities */ | 61 | /* Policy capabilities */ |
| 63 | enum { | 62 | enum { |
| @@ -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 | ||
| 82 | int security_mls_enabled(void); | ||
| 83 | |||
| 83 | int security_load_policy(void *data, size_t len); | 84 | int security_load_policy(void *data, size_t len); |
| 84 | 85 | ||
| 85 | int security_policycap_supported(unsigned int req_cap); | 86 | int 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 | ||
| 83 | static inline int mls_context_cmp(struct context *c1, struct context *c2) | 77 | static 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 | ||
| 94 | static inline void mls_context_destroy(struct context *c) | 85 | static 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 | */ |
| 410 | static inline int mls_range_set(struct context *context, | 410 | int 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, | |||
| 427 | int mls_setup_user_range(struct context *fromcon, struct user_datum *user, | 427 | int 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, | |||
| 559 | void mls_export_netlbl_lvl(struct context *context, | 559 | void 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, | |||
| 579 | void mls_import_netlbl_lvl(struct context *context, | 579 | void 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 | ||
| 40 | int mls_from_string(char *str, struct context *context, gfp_t gfp_mask); | 40 | int mls_from_string(char *str, struct context *context, gfp_t gfp_mask); |
| 41 | 41 | ||
| 42 | int mls_range_set(struct context *context, struct mls_range *range); | ||
| 43 | |||
| 42 | int mls_convert_context(struct policydb *oldp, | 44 | int 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 | ||
| 19 | struct mls_level { | 20 | struct mls_level { |
| 20 | u32 sens; /* sensitivity */ | 21 | u32 sens; /* sensitivity */ |
| @@ -27,18 +28,12 @@ struct mls_range { | |||
| 27 | 28 | ||
| 28 | static inline int mls_level_eq(struct mls_level *l1, struct mls_level *l2) | 29 | static 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 | ||
| 37 | static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2) | 35 | static 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 | ||
| 55 | int selinux_mls_enabled; | ||
| 56 | |||
| 57 | static unsigned int symtab_sizes[SYM_NUM] = { | 55 | static 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 */ |
| 187 | struct policydb { | 189 | struct 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 | ||
| 239 | int 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 | } |
