From: <ssm...@us...> - 2008-03-24 20:18:08
|
Revision: 2855 http://selinux.svn.sourceforge.net/selinux/?rev=2855&view=rev Author: ssmalley Date: 2008-03-24 13:17:15 -0700 (Mon, 24 Mar 2008) Log Message: ----------- Author: Eric Paris Email: ep...@re... Subject: libsepol: add permissive domain support Date: Mon, 24 Mar 2008 09:51:37 -0400 This patch adds support for permissive types. In the kernel policy format the permissive types are in a bitmap referenced by the type value. In the module policy format a new field in the type_datum_t called 'flags' was added. The only currently defined flag is TYPE_FLAGS_PERMISSIVE. Checkpolicy can set the permissive flag on the type_datum_t in question and that flag will persist on disk. It will be OR'd at link time against the type in the base policy. At expand time we build the bit array the kernel uses. Signed-off-by: Eric Paris <ep...@re...> Acked-by: Stephen Smalley <sd...@ty...> Modified Paths: -------------- trunk/libsepol/include/sepol/policydb/policydb.h trunk/libsepol/src/expand.c trunk/libsepol/src/link.c trunk/libsepol/src/policydb.c trunk/libsepol/src/write.c Modified: trunk/libsepol/include/sepol/policydb/policydb.h =================================================================== --- trunk/libsepol/include/sepol/policydb/policydb.h 2008-03-20 19:01:26 UTC (rev 2854) +++ trunk/libsepol/include/sepol/policydb/policydb.h 2008-03-24 20:17:15 UTC (rev 2855) @@ -143,6 +143,8 @@ #define TYPE_ALIAS 2 /* alias in modular policy */ uint32_t flavor; ebitmap_t types; /* types with this attribute */ +#define TYPE_FLAGS_PERMISSIVE 0x01 + uint32_t flags; } type_datum_t; /* User attributes */ @@ -470,6 +472,10 @@ ebitmap_t policycaps; + /* this bitmap is referenced by type NOT the typical type-1 used in other + bitmaps. Someday the 0 bit may be used for global permissive */ + ebitmap_t permissive_map; + unsigned policyvers; unsigned handle_unknown; @@ -588,10 +594,11 @@ #define POLICYDB_VERSION_AVTAB 20 #define POLICYDB_VERSION_RANGETRANS 21 #define POLICYDB_VERSION_POLCAP 22 +#define POLICYDB_VERSION_PERMISSIVE 23 /* Range of policy versions we understand*/ #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE -#define POLICYDB_VERSION_MAX POLICYDB_VERSION_POLCAP +#define POLICYDB_VERSION_MAX POLICYDB_VERSION_PERMISSIVE /* Module versions and specific changes*/ #define MOD_POLICYDB_VERSION_BASE 4 @@ -600,9 +607,10 @@ #define MOD_POLICYDB_VERSION_RANGETRANS 6 #define MOD_POLICYDB_VERSION_MLS_USERS 6 #define MOD_POLICYDB_VERSION_POLCAP 7 +#define MOD_POLICYDB_VERSION_PERMISSIVE 8 #define MOD_POLICYDB_VERSION_MIN MOD_POLICYDB_VERSION_BASE -#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_POLCAP +#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_PERMISSIVE #define POLICYDB_CONFIG_MLS 1 Modified: trunk/libsepol/src/expand.c =================================================================== --- trunk/libsepol/src/expand.c 2008-03-20 19:01:26 UTC (rev 2854) +++ trunk/libsepol/src/expand.c 2008-03-24 20:17:15 UTC (rev 2855) @@ -92,6 +92,7 @@ memset(new_type, 0, sizeof(type_datum_t)); new_type->flavor = type->flavor; + new_type->flags = type->flags; new_type->s.value = ++state->out->p_types.nprim; if (new_type->s.value > UINT16_MAX) { free(new_id); @@ -112,6 +113,12 @@ return -1; } + if (new_type->flags & TYPE_FLAGS_PERMISSIVE) + if (ebitmap_set_bit(&state->out->permissive_map, new_type->s.value, 1)) { + ERR(state->handle, "Out of memory!\n"); + return -1; + } + return 0; } @@ -480,6 +487,8 @@ else assert(0); /* unreachable */ + new_alias->flags = alias->flags; + ret = hashtab_insert(state->out->p_types.table, (hashtab_key_t) new_id, (hashtab_datum_t) new_alias); @@ -492,6 +501,13 @@ } state->typemap[alias->s.value - 1] = new_alias->s.value; + + if (new_alias->flags & TYPE_FLAGS_PERMISSIVE) + if (ebitmap_set_bit(&state->out->permissive_map, new_alias->s.value, 1)) { + ERR(state->handle, "Out of memory!"); + return -1; + } + return 0; } Modified: trunk/libsepol/src/link.c =================================================================== --- trunk/libsepol/src/link.c 2008-03-20 19:01:26 UTC (rev 2854) +++ trunk/libsepol/src/link.c 2008-03-24 20:17:15 UTC (rev 2855) @@ -405,6 +405,8 @@ state->cur_mod_name, id); return -1; } + /* permissive should pass to the base type */ + base_type->flags |= (type->flags & TYPE_FLAGS_PERMISSIVE); } else { if (state->verbose) INFO(state->handle, "copying type %s", id); @@ -418,6 +420,7 @@ goto cleanup; } new_type->primary = type->primary; + new_type->flags = type->flags; new_type->flavor = type->flavor; /* for attributes, the writing of new_type->types is done in type_fix_callback() */ @@ -441,6 +444,7 @@ } new_type->primary = type->primary; new_type->flavor = type->flavor; + new_type->flags = type->flags; new_type->s.value = base_type->s.value; if ((new_id = strdup(id)) == NULL) { goto cleanup; @@ -702,6 +706,8 @@ return -1; } + target_type->flags |= (type->flags & TYPE_FLAGS_PERMISSIVE); + base_type = hashtab_search(state->base->p_types.table, id); if (base_type == NULL) { if (state->verbose) @@ -713,6 +719,7 @@ } /* the linked copy always has TYPE_ALIAS style aliases */ new_type->primary = target_type->s.value; + new_type->flags = target_type->flags; new_type->flavor = TYPE_ALIAS; new_type->s.value = state->base->p_types.nprim + 1; if ((new_id = strdup(id)) == NULL) { @@ -747,6 +754,7 @@ base_type->flavor = TYPE_ALIAS; base_type->primary = target_type->s.value; + base_type->flags |= (target_type->flags & TYPE_FLAGS_PERMISSIVE); } /* the aliases map points from its value to its primary so when this module Modified: trunk/libsepol/src/policydb.c =================================================================== --- trunk/libsepol/src/policydb.c 2008-03-20 19:01:26 UTC (rev 2854) +++ trunk/libsepol/src/policydb.c 2008-03-24 20:17:15 UTC (rev 2855) @@ -105,6 +105,12 @@ .ocon_num = OCON_NODE6 + 1, }, { + .type = POLICY_KERN, + .version = POLICYDB_VERSION_PERMISSIVE, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + }, + { .type = POLICY_BASE, .version = MOD_POLICYDB_VERSION_BASE, .sym_num = SYM_NUM, @@ -129,6 +135,12 @@ .ocon_num = OCON_NODE6 + 1, }, { + .type = POLICY_BASE, + .version = MOD_POLICYDB_VERSION_PERMISSIVE, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + }, + { .type = POLICY_MOD, .version = MOD_POLICYDB_VERSION_BASE, .sym_num = SYM_NUM, @@ -150,7 +162,14 @@ .type = POLICY_MOD, .version = MOD_POLICYDB_VERSION_POLCAP, .sym_num = SYM_NUM, - .ocon_num = 0}, + .ocon_num = 0 + }, + { + .type = POLICY_MOD, + .version = MOD_POLICYDB_VERSION_PERMISSIVE, + .sym_num = SYM_NUM, + .ocon_num = 0 + }, }; #if 0 @@ -467,6 +486,8 @@ ebitmap_init(&p->policycaps); + ebitmap_init(&p->permissive_map); + for (i = 0; i < SYM_NUM; i++) { p->sym_val_to_name[i] = NULL; rc = symtab_init(&p->symtab[i], symtab_sizes[i]); @@ -992,6 +1013,8 @@ ebitmap_destroy(&p->policycaps); + ebitmap_destroy(&p->permissive_map); + symtabs_destroy(p->symtab); for (i = 0; i < SYM_NUM; i++) { @@ -1907,19 +1930,22 @@ { char *key = 0; type_datum_t *typdatum; - uint32_t buf[4]; + uint32_t buf[5]; size_t len; - int rc; + int rc, to_read; typdatum = calloc(1, sizeof(type_datum_t)); if (!typdatum) return -1; - if (p->policy_type == POLICY_KERN) { - rc = next_entry(buf, fp, sizeof(uint32_t) * 3); - } else { - rc = next_entry(buf, fp, sizeof(uint32_t) * 4); - } + if (p->policy_type == POLICY_KERN) + to_read = 3; + else if (p->policyvers >= MOD_POLICYDB_VERSION_PERMISSIVE) + to_read = 5; + else + to_read = 4; + + rc = next_entry(buf, fp, sizeof(uint32_t) * to_read); if (rc < 0) goto bad; @@ -1928,6 +1954,8 @@ typdatum->primary = le32_to_cpu(buf[2]); if (p->policy_type != POLICY_KERN) { typdatum->flavor = le32_to_cpu(buf[3]); + if (p->policyvers >= MOD_POLICYDB_VERSION_PERMISSIVE) + typdatum->flags = le32_to_cpu(buf[4]); if (ebitmap_read(&typdatum->types, fp)) goto bad; } @@ -3157,6 +3185,12 @@ goto bad; } + if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE && + p->policy_type == POLICY_KERN) { + if (ebitmap_read(&p->permissive_map, fp)) + goto bad; + } + for (i = 0; i < info->sym_num; i++) { rc = next_entry(buf, fp, sizeof(uint32_t) * 2); if (rc < 0) Modified: trunk/libsepol/src/write.c =================================================================== --- trunk/libsepol/src/write.c 2008-03-20 19:01:26 UTC (rev 2854) +++ trunk/libsepol/src/write.c 2008-03-24 20:17:15 UTC (rev 2855) @@ -959,6 +959,12 @@ buf[items++] = cpu_to_le32(typdatum->primary); if (p->policy_type != POLICY_KERN) { buf[items++] = cpu_to_le32(typdatum->flavor); + if (p->policyvers >= MOD_POLICYDB_VERSION_PERMISSIVE) + buf[items++] = cpu_to_le32(typdatum->flags); + else if (typdatum->flags & TYPE_FLAGS_PERMISSIVE) + WARN(fp->handle, "Warning! Module policy version %d cannnot " + "support permissive types, but one was defined", + p->policyvers); } items2 = put_entry(buf, sizeof(uint32_t), items, fp); if (items != items2) @@ -1618,6 +1624,27 @@ return POLICYDB_ERROR; } + if (p->policyvers < POLICYDB_VERSION_PERMISSIVE && + p->policy_type == POLICY_KERN) { + ebitmap_node_t *tnode; + unsigned int i; + + ebitmap_for_each_bit(&p->permissive_map, tnode, i) { + if (ebitmap_node_get_bit(tnode, i)) { + WARN(fp->handle, "Warning! Policy version %d cannot " + "support permissive types, but some were defined", + p->policyvers); + break; + } + } + } + + if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE && + p->policy_type == POLICY_KERN) { + if (ebitmap_write(&p->permissive_map, fp) == -1) + return POLICYDB_ERROR; + } + num_syms = info->sym_num; for (i = 0; i < num_syms; i++) { buf[0] = cpu_to_le32(p->symtab[i].nprim); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |