From: Darrel Goeddel <dgoeddel@TrustedCS.com>
To: SELinux List <selinux@tycho.nsa.gov>,
Serge Hallyn <serue@us.ibm.com>,
Christopher PeBenito <cpebenito@tresys.com>,
Joshua Brindle <jbrindle@tresys.com>,
Stephen Smalley <sds@tycho.nsa.gov>,
Karl MacMillan <kmacmillan@mentalrootkit.com>
Subject: [RFC PATCH] allow range_transitions and MLS users in modules
Date: Mon, 18 Sep 2006 12:49:34 -0500 [thread overview]
Message-ID: <450EDC2E.50009@trustedcs.com> (raw)
- Add the ability to require MLS sensitivities and categories in policy
modules.
- Remove the restrictions on defining users in MLS-enabled modules.
- Handle range_trans_rules in modules.
This all allows range_transition statements to be used in policy modules
and allows definition of users in MLS policy modules.
I haven't tested this as much as I would like, but it is working nicely
for me. I have built several policies (MLS, non-MLS, strict, targeted,
etc.) and have built several modules exercising the new functionality.
I'd appreciate any feedback you may have at this point.
---
checkpolicy/module_compiler.c | 110 ++++++++++++++++++++++++
checkpolicy/module_compiler.h | 2
checkpolicy/policy_parse.y | 7 -
libsepol/src/link.c | 189 ++++++++++++++++++++++++++++++++++++------
libsepol/src/policydb.c | 6 +
5 files changed, 283 insertions(+), 31 deletions(-)
diff --exclude=.svn -ruNp selinux/checkpolicy/module_compiler.c selinux-modular-mls/checkpolicy/module_compiler.c
--- selinux/checkpolicy/module_compiler.c 2006-09-05 06:44:56.000000000 -0500
+++ selinux-modular-mls/checkpolicy/module_compiler.c 2006-09-08 16:12:22.000000000 -0500
@@ -937,6 +937,116 @@ int require_bool(int pass)
}
}
+int require_sens(int pass)
+{
+ char *id = queue_remove(id_queue);
+ level_datum_t *level = NULL;
+ int retval;
+ if (pass == 2) {
+ free(id);
+ return 0;
+ }
+ if (!id) {
+ yyerror("no sensitivity name");
+ return -1;
+ }
+ level = calloc(1, sizeof(level_datum_t));
+ if (!level) {
+ free(id);
+ yyerror("Out of memory!");
+ return -1;
+ }
+ level->level = malloc(sizeof(mls_level_t));
+ if (!level->level) {
+ free(id);
+ free(level);
+ yyerror("Out of memory!");
+ return -1;
+ }
+ mls_level_init(level->level);
+ retval = require_symbol(SYM_LEVELS, id, (hashtab_datum_t *) level,
+ &level->level->sens, &level->level->sens);
+ if (retval != 0) {
+ free(id);
+ mls_level_destroy(level->level);
+ free(level->level);
+ free(level);
+ }
+ switch (retval) {
+ case -3:{
+ yyerror("Out of memory!");
+ return -1;
+ }
+ case -2:{
+ yyerror("duplicate declaration of sensitivity");
+ return -1;
+ }
+ case -1:{
+ yyerror("could not require sensitivity here");
+ return -1;
+ }
+ case 0:{
+ return 0;
+ }
+ case 1:{
+ return 0; /* sensitivity already required */
+ }
+ default:{
+ assert(0); /* should never get here */
+ }
+ }
+}
+
+int require_cat(int pass)
+{
+ char *id = queue_remove(id_queue);
+ cat_datum_t *cat = NULL;
+ int retval;
+ if (pass == 2) {
+ free(id);
+ return 0;
+ }
+ if (!id) {
+ yyerror("no category name");
+ return -1;
+ }
+ cat = calloc(1, sizeof(cat_datum_t));
+ if (!cat) {
+ free(id);
+ yyerror("Out of memory!");
+ return -1;
+ }
+ retval = require_symbol(SYM_CATS, id, (hashtab_datum_t *) cat,
+ &cat->s.value, &cat->s.value);
+ if (retval != 0) {
+ free(id);
+ free(cat);
+ }
+ switch (retval) {
+ case -3:{
+ yyerror("Out of memory!");
+ return -1;
+ }
+ case -2:{
+ yyerror("duplicate declaration of category");
+ return -1;
+ }
+ case -1:{
+ yyerror("could not require category here");
+ return -1;
+ }
+ case 0:{
+ return 0;
+ }
+ case 1:{
+ return 0; /* category already required */
+ }
+ default:{
+ assert(0); /* should never get here */
+ }
+ }
+}
+
static int is_scope_in_stack(scope_datum_t * scope, scope_stack_t * stack)
{
int i;
diff --exclude=.svn -ruNp selinux/checkpolicy/module_compiler.h selinux-modular-mls/checkpolicy/module_compiler.h
--- selinux/checkpolicy/module_compiler.h 2006-09-05 06:44:56.000000000 -0500
+++ selinux-modular-mls/checkpolicy/module_compiler.h 2006-09-08 16:12:22.000000000 -0500
@@ -56,6 +56,8 @@ int require_type(int pass);
int require_attribute(int pass);
int require_user(int pass);
int require_bool(int pass);
+int require_sens(int pass);
+int require_cat(int pass);
/* Check if an identifier is within the scope of the current
* declaration or any of its parents. Return 1 if it is, 0 if not.
diff --exclude=.svn -ruNp selinux/checkpolicy/policy_parse.y selinux-modular-mls/checkpolicy/policy_parse.y
--- selinux/checkpolicy/policy_parse.y 2006-09-05 06:17:18.000000000 -0500
+++ selinux-modular-mls/checkpolicy/policy_parse.y 2006-09-08 12:09:35.000000000 -0500
@@ -834,10 +834,8 @@ require_decl_def : ROLE {
| ATTRIBUTE { $$ = require_attribute; }
| USER { $$ = require_user; }
| BOOL { $$ = require_bool; }
-/* MLS-enabled modules are not implemented at this time.
| SENSITIVITY { $$ = require_sens; }
| CATEGORY { $$ = require_cat; }
-*/
;
require_id_list : identifier
{ if ($<require_func>0 (pass)) return -1; }
@@ -3682,11 +3680,6 @@ static int define_user(void)
level_datum_t *levdatum;
int l;
- if (policydbp->policy_type == POLICY_MOD && mlspol) {
- yyerror("Users cannot be declared in MLS modules");
- return -1;
- }
-
if (pass == 1) {
while ((id = queue_remove(id_queue)))
free(id);
diff --exclude=.svn -ruNp selinux/libsepol/src/link.c selinux-modular-mls/libsepol/src/link.c
--- selinux/libsepol/src/link.c 2006-09-05 06:44:54.000000000 -0500
+++ selinux-modular-mls/libsepol/src/link.c 2006-09-08 16:12:21.000000000 -0500
@@ -468,25 +468,8 @@ static int user_copy_callback(hashtab_ke
char *id = key, *new_id = NULL;
user_datum_t *user, *base_user, *new_user = NULL;
link_state_t *state = (link_state_t *) data;
- scope_datum_t *scope;
user = (user_datum_t *) datum;
- if (state->base->mls) {
- scope =
- hashtab_search(state->cur->policy->p_users_scope.table, id);
- if (!scope) {
- ERR(state->handle,
- "No scope information for user %s in module %s\n",
- id, state->cur_mod_name);
- return -1;
- }
- if (scope->scope == SCOPE_DECL) {
- ERR(state->handle,
- "Users cannot be declared in MLS modules");
- return -1;
- }
- /* required users fall through */
- }
base_user = hashtab_search(state->base->p_users.table, id);
if (base_user == NULL) {
@@ -502,9 +485,8 @@ static int user_copy_callback(hashtab_ke
goto cleanup;
}
user_datum_init(new_user);
- /* new_users's roles field will be copied during
- fix_user_callback(). the MLS fields are currently
- unimplemented */
+ /* new_users's roles and MLS fields will be copied during
+ user_fix_callback(). */
new_user->s.value = state->base->p_users.nprim + 1;
@@ -592,10 +574,72 @@ static int bool_copy_callback(hashtab_ke
return -1;
}
+static int sens_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
+ void *data)
+{
+ char *id = key;
+ level_datum_t *level, *base_level;
+ link_state_t *state = (link_state_t *) data;
+ scope_datum_t *scope;
+
+ level = (level_datum_t *) datum;
+
+ base_level = hashtab_search(state->base->p_levels.table, id);
+ if (!base_level) {
+ scope =
+ hashtab_search(state->cur->policy->p_sens_scope.table, id);
+ if (!scope)
+ return -SEPOL_LINK_ERROR;
+ if (scope->scope == SCOPE_DECL) {
+ /* disallow declarations in modules */
+ ERR(state->handle,
+ "%s: Modules may not declare new sensitivities.",
+ state->cur_mod_name);
+ return -SEPOL_LINK_NOTSUP;
+ }
+ }
+
+ state->cur->map[SYM_LEVELS][level->level->sens - 1] =
+ base_level->level->sens;
+
+ return 0;
+}
+
+static int cat_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
+ void *data)
+{
+ char *id = key;
+ cat_datum_t *cat, *base_cat;
+ link_state_t *state = (link_state_t *) data;
+ scope_datum_t *scope;
+
+ cat = (cat_datum_t *) datum;
+
+ base_cat = hashtab_search(state->base->p_cats.table, id);
+ if (!base_cat) {
+ scope =
+ hashtab_search(state->cur->policy->p_cat_scope.table, id);
+ if (!scope)
+ return -SEPOL_LINK_ERROR;
+ if (scope->scope == SCOPE_DECL) {
+ /* disallow declarations in modules */
+ ERR(state->handle,
+ "%s: Modules may not declare new categories.",
+ state->cur_mod_name);
+ return -SEPOL_LINK_NOTSUP;
+ }
+ }
+
+ state->cur->map[SYM_CATS][cat->s.value - 1] = base_cat->s.value;
+
+ return 0;
+}
+
static int (*copy_callback_f[SYM_NUM]) (hashtab_key_t key,
hashtab_datum_t datum, void *datap) = {
NULL, class_copy_callback, role_copy_callback, type_copy_callback,
- user_copy_callback, bool_copy_callback, NULL, NULL};
+ user_copy_callback, bool_copy_callback, sens_copy_callback,
+ cat_copy_callback};
/* The aliases have to be copied after the types and attributes to be
* certain that the base symbol table will have the type that the
@@ -783,6 +827,43 @@ static int role_set_or_convert(role_set_
return -1;
}
+static int mls_level_convert(mls_semantic_level_t * src,
+ mls_semantic_level_t * dst, policy_module_t * mod)
+{
+ mls_semantic_cat_t *src_cat, *new_cat;
+
+ assert(mod->map[SYM_LEVELS][src->sens - 1]);
+ dst->sens = mod->map[SYM_LEVELS][src->sens - 1];
+
+ for (src_cat = src->cat; src_cat; src_cat = src_cat->next) {
+ new_cat =
+ (mls_semantic_cat_t *) calloc(1,
+ sizeof(mls_semantic_cat_t));
+ if (!new_cat)
+ return -1;
+
+ new_cat->next = dst->cat;
+ dst->cat = new_cat;
+
+ assert(mod->map[SYM_CATS][src_cat->low - 1]);
+ dst->cat->low = mod->map[SYM_CATS][src_cat->low - 1];
+ assert(mod->map[SYM_CATS][src_cat->high - 1]);
+ dst->cat->high = mod->map[SYM_CATS][src_cat->high - 1];
+ }
+
+ return 0;
+}
+
+static int mls_range_convert(mls_semantic_range_t * src,
+ mls_semantic_range_t * dst, policy_module_t * mod)
+{
+ if (mls_level_convert(&src->level[0], &dst->level[0], mod))
+ return -1;
+ if (mls_level_convert(&src->level[1], &dst->level[1], mod))
+ return -1;
+ return 0;
+}
+
static int role_fix_callback(hashtab_key_t key, hashtab_datum_t datum,
void *data)
{
@@ -893,13 +974,16 @@ static int user_fix_callback(hashtab_key
user_datum_t *user, *new_user = NULL;
link_state_t *state = (link_state_t *) data;
policy_module_t *mod = state->cur;
+ symtab_t *usertab;
user = (user_datum_t *) datum;
if (state->dest_decl == NULL)
- return 0;
+ usertab = &state->base->p_users;
+ else
+ usertab = &state->dest_decl->p_users;
- new_user = hashtab_search(state->dest_decl->p_users.table, id);
+ new_user = hashtab_search(usertab->table, id);
assert(new_user != NULL);
if (state->verbose) {
@@ -910,6 +994,12 @@ static int user_fix_callback(hashtab_key
goto cleanup;
}
+ if (mls_range_convert(&user->range, &new_user->range, mod))
+ goto cleanup;
+
+ if (mls_level_convert(&user->dfltlevel, &new_user->dfltlevel, mod))
+ goto cleanup;
+
return 0;
cleanup:
@@ -1096,6 +1186,55 @@ static int copy_role_allow_list(role_all
return -1;
}
+static int copy_range_trans_list(range_trans_rule_t * rules,
+ range_trans_rule_t ** dst,
+ policy_module_t * mod, link_state_t * state)
+{
+ range_trans_rule_t *rule, *new_rule = NULL;
+ unsigned int i;
+ ebitmap_node_t *cnode;
+
+ for (rule = rules; rule; rule = rule->next) {
+ new_rule =
+ (range_trans_rule_t *) malloc(sizeof(range_trans_rule_t));
+ if (!new_rule)
+ goto cleanup;
+
+ range_trans_rule_init(new_rule);
+
+ new_rule->next = *dst;
+ *dst = new_rule;
+
+ if (type_set_convert(&rule->stypes, &new_rule->stypes,
+ mod, state))
+ goto cleanup;
+
+ if (type_set_convert(&rule->ttypes, &new_rule->ttypes,
+ mod, state))
+ goto cleanup;
+
+ ebitmap_for_each_bit(&rule->tclasses, cnode, i) {
+ if (ebitmap_node_get_bit(cnode, i)) {
+ assert(mod->map[SYM_CLASSES][i]);
+ if (ebitmap_set_bit
+ (&new_rule->tclasses,
+ mod->map[SYM_CLASSES][i] - 1, 1)) {
+ goto cleanup;
+ }
+ }
+ }
+
+ if (mls_range_convert(&rule->trange, &new_rule->trange, mod))
+ goto cleanup;
+ }
+ return 0;
+
+ cleanup:
+ ERR(state->handle, "Out of memory!");
+ range_trans_rule_list_destroy(new_rule);
+ return -1;
+}
+
static int copy_cond_list(cond_node_t * list, cond_node_t ** dst,
policy_module_t * module, link_state_t * state)
{
@@ -1278,6 +1417,10 @@ static int copy_avrule_decl(link_state_t
return -1;
}
+ if (copy_range_trans_list(src_decl->range_tr_rules,
+ &dest_decl->range_tr_rules, module, state))
+ return -1;
+
/* finally copy any identifiers local to this declaration */
ret = copy_identifiers(state, src_decl->symtab, dest_decl);
if (ret < 0) {
diff --exclude=.svn -ruNp selinux/libsepol/src/policydb.c selinux-modular-mls/libsepol/src/policydb.c
--- selinux/libsepol/src/policydb.c 2006-09-05 06:44:54.000000000 -0500
+++ selinux-modular-mls/libsepol/src/policydb.c 2006-09-08 16:12:21.000000000 -0500
@@ -502,7 +502,11 @@ int policydb_user_cache(hashtab_key_t ke
return -1;
}
- if (p->policy_type != POLICY_KERN) {
+ /* we do not expand user's MLS info in kernel policies because the
+ * semantic representation is not present and we do not expand user's
+ * MLS info in module policies because all of the necessary mls
+ * information is not present */
+ if (p->policy_type != POLICY_KERN && p->policy_type != POLICY_MOD) {
mls_range_destroy(&user->exp_range);
if (mls_semantic_range_expand(&user->range,
&user->exp_range, p, NULL)) {
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
next reply other threads:[~2006-09-18 17:49 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-09-18 17:49 Darrel Goeddel [this message]
2006-09-18 18:01 ` [RFC PATCH] allow range_transitions and MLS users in modules Joshua Brindle
2006-09-18 18:39 ` Darrel Goeddel
2006-09-19 12:07 ` Joshua Brindle
2006-09-22 19:51 ` Christopher J. PeBenito
2006-09-24 4:17 ` Joshua Brindle
2006-09-24 15:16 ` Joshua Brindle
2006-09-25 13:32 ` Darrel Goeddel
2006-09-25 19:36 ` [PATCH take 2] " Darrel Goeddel
2006-09-25 19:58 ` Joshua Brindle
2006-09-26 17:49 ` [PATCH take 3] " Darrel Goeddel
2006-09-26 17:56 ` Joshua Brindle
2006-09-28 12:20 ` Joshua Brindle
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=450EDC2E.50009@trustedcs.com \
--to=dgoeddel@trustedcs.com \
--cc=cpebenito@tresys.com \
--cc=jbrindle@tresys.com \
--cc=kmacmillan@mentalrootkit.com \
--cc=sds@tycho.nsa.gov \
--cc=selinux@tycho.nsa.gov \
--cc=serue@us.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.