diff --git a/checkpolicy/policy_define.c b/checkpolicy/policy_define.c index 1bf669c..a86c6b3 100644 --- a/checkpolicy/policy_define.c +++ b/checkpolicy/policy_define.c @@ -327,6 +327,126 @@ int define_initial_sid(void) return -1; } +static int read_classes(ebitmap_t *e_classes) +{ + char *id; + class_datum_t *cladatum; + + while ((id = queue_remove(id_queue))) { + if (!is_id_in_scope(SYM_CLASSES, id)) { + yyerror2("class %s is not within scope", id); + return -1; + } + cladatum = hashtab_search(policydbp->p_classes.table, id); + if (!cladatum) { + yyerror2("unknown class %s", id); + return -1; + } + if (ebitmap_set_bit(e_classes, cladatum->s.value - 1, TRUE)) { + yyerror("Out of memory"); + return -1; + } + free(id); + } + return 0; +} + +int define_default_user(int which) +{ + char *id; + class_datum_t *cladatum; + + if (pass == 1) { + while ((id = queue_remove(id_queue))) + free(id); + return 0; + } + + while ((id = queue_remove(id_queue))) { + if (!is_id_in_scope(SYM_CLASSES, id)) { + yyerror2("class %s is not within scope", id); + return -1; + } + cladatum = hashtab_search(policydbp->p_classes.table, id); + if (!cladatum) { + yyerror2("unknown class %s", id); + return -1; + } + if (cladatum->default_user && cladatum->default_user != which) { + yyerror2("conflicting default user information for class %s", id); + return -1; + } + cladatum->default_user = which; + free(id); + } + + return 0; +} + +int define_default_role(int which) +{ + char *id; + class_datum_t *cladatum; + + if (pass == 1) { + while ((id = queue_remove(id_queue))) + free(id); + return 0; + } + + while ((id = queue_remove(id_queue))) { + if (!is_id_in_scope(SYM_CLASSES, id)) { + yyerror2("class %s is not within scope", id); + return -1; + } + cladatum = hashtab_search(policydbp->p_classes.table, id); + if (!cladatum) { + yyerror2("unknown class %s", id); + return -1; + } + if (cladatum->default_role && cladatum->default_role != which) { + yyerror2("conflicting default role information for class %s", id); + return -1; + } + cladatum->default_role = which; + free(id); + } + + return 0; +} + +int define_default_range(int which) +{ + char *id; + class_datum_t *cladatum; + + if (pass == 1) { + while ((id = queue_remove(id_queue))) + free(id); + return 0; + } + + while ((id = queue_remove(id_queue))) { + if (!is_id_in_scope(SYM_CLASSES, id)) { + yyerror2("class %s is not within scope", id); + return -1; + } + cladatum = hashtab_search(policydbp->p_classes.table, id); + if (!cladatum) { + yyerror2("unknown class %s", id); + return -1; + } + if (cladatum->default_range && cladatum->default_range != which) { + yyerror2("conflicting default range information for class %s", id); + return -1; + } + cladatum->default_range = which; + free(id); + } + + return 0; +} + int define_common_perms(void) { char *id = 0, *perm = 0; @@ -1360,7 +1480,6 @@ int define_compute_type_helper(int which, avrule_t ** rule) { char *id; type_datum_t *datum; - class_datum_t *cladatum; ebitmap_t tclasses; ebitmap_node_t *node; avrule_t *avrule; @@ -1387,23 +1506,8 @@ int define_compute_type_helper(int which, avrule_t ** rule) } ebitmap_init(&tclasses); - while ((id = queue_remove(id_queue))) { - if (!is_id_in_scope(SYM_CLASSES, id)) { - yyerror2("class %s is not within scope", id); - free(id); - goto bad; - } - cladatum = hashtab_search(policydbp->p_classes.table, id); - if (!cladatum) { - yyerror2("unknown class %s", id); - goto bad; - } - if (ebitmap_set_bit(&tclasses, cladatum->s.value - 1, TRUE)) { - yyerror("Out of memory"); - goto bad; - } - free(id); - } + if (read_classes(&tclasses)) + goto bad; id = (char *)queue_remove(id_queue); if (!id) { @@ -1628,25 +1732,9 @@ int define_te_avtab_helper(int which, avrule_t ** rule) } ebitmap_init(&tclasses); - while ((id = queue_remove(id_queue))) { - if (!is_id_in_scope(SYM_CLASSES, id)) { - yyerror2("class %s is not within scope", id); - ret = -1; - goto out; - } - cladatum = hashtab_search(policydbp->p_classes.table, id); - if (!cladatum) { - yyerror2("unknown class %s used in rule", id); - ret = -1; - goto out; - } - if (ebitmap_set_bit(&tclasses, cladatum->s.value - 1, TRUE)) { - yyerror("Out of memory"); - ret = -1; - goto out; - } - free(id); - } + ret = read_classes(&tclasses); + if (ret) + goto out; perms = NULL; ebitmap_for_each_bit(&tclasses, node, i) { @@ -2242,22 +2330,8 @@ int define_role_trans(int class_specified) } if (class_specified) { - while ((id = queue_remove(id_queue))) { - if (!is_id_in_scope(SYM_CLASSES, id)) { - yyerror2("class %s is not within scope", id); - free(id); - return -1; - } - cladatum = hashtab_search(policydbp->p_classes.table, - id); - if (!cladatum) { - yyerror2("unknow class %s", id); - return -1; - } - - ebitmap_set_bit(&e_classes, cladatum->s.value - 1, TRUE); - free(id); - } + if (read_classes(&e_classes)) + return -1; } else { cladatum = hashtab_search(policydbp->p_classes.table, "process"); @@ -2410,7 +2484,6 @@ int define_filename_trans(void) ebitmap_node_t *snode, *tnode, *cnode; filename_trans_t *ft; filename_trans_rule_t *ftr; - class_datum_t *cladatum; type_datum_t *typdatum; uint32_t otype; unsigned int c, s, t; @@ -2451,23 +2524,8 @@ int define_filename_trans(void) } ebitmap_init(&e_tclasses); - while ((id = queue_remove(id_queue))) { - if (!is_id_in_scope(SYM_CLASSES, id)) { - yyerror2("class %s is not within scope", id); - free(id); - goto bad; - } - cladatum = hashtab_search(policydbp->p_classes.table, id); - if (!cladatum) { - yyerror2("unknown class %s", id); - goto bad; - } - if (ebitmap_set_bit(&e_tclasses, cladatum->s.value - 1, TRUE)) { - yyerror("Out of memory"); - goto bad; - } - free(id); - } + if (read_classes(&e_tclasses)) + goto bad; id = (char *)queue_remove(id_queue); if (!id) { @@ -4549,23 +4607,8 @@ int define_range_trans(int class_specified) } if (class_specified) { - while ((id = queue_remove(id_queue))) { - if (!is_id_in_scope(SYM_CLASSES, id)) { - yyerror2("class %s is not within scope", id); - free(id); - goto out; - } - cladatum = hashtab_search(policydbp->p_classes.table, - id); - if (!cladatum) { - yyerror2("unknown class %s", id); - goto out; - } - - ebitmap_set_bit(&rule->tclasses, cladatum->s.value - 1, - TRUE); - free(id); - } + if (read_classes(&rule->tclasses)) + goto out; } else { cladatum = hashtab_search(policydbp->p_classes.table, "process"); diff --git a/checkpolicy/policy_define.h b/checkpolicy/policy_define.h index 92a9be7..ccbe56f 100644 --- a/checkpolicy/policy_define.h +++ b/checkpolicy/policy_define.h @@ -24,6 +24,9 @@ int define_av_perms(int inherits); int define_bool_tunable(int is_tunable); int define_category(void); int define_class(void); +int define_default_user(int which); +int define_default_role(int which); +int define_default_range(int which); int define_common_perms(void); int define_compute_type(int which); int define_conditional(cond_expr_t *expr, avrule_t *t_list, avrule_t *f_list ); diff --git a/checkpolicy/policy_parse.y b/checkpolicy/policy_parse.y index d808111..d92cc32 100644 --- a/checkpolicy/policy_parse.y +++ b/checkpolicy/policy_parse.y @@ -143,6 +143,8 @@ typedef int (* require_func_t)(); %token POLICYCAP %token PERMISSIVE %token FILESYSTEM +%token DEFAULT_USER DEFAULT_ROLE DEFAULT_RANGE +%token LOW_HIGH LOW HIGH %left OR %left XOR @@ -157,7 +159,7 @@ base_policy : { if (define_policy(pass, 0) == -1) return -1; } classes initial_sids access_vectors { if (pass == 1) { if (policydb_index_classes(policydbp)) return -1; } else if (pass == 2) { if (policydb_index_others(NULL, policydbp, 0)) return -1; }} - opt_mls te_rbac users opt_constraints + opt_default_rules opt_mls te_rbac users opt_constraints { if (pass == 1) { if (policydb_index_bools(policydbp)) return -1;} else if (pass == 2) { if (policydb_index_others(NULL, policydbp, 0)) return -1;}} initial_sid_contexts opt_fs_contexts opt_fs_uses opt_genfs_contexts net_contexts opt_dev_contexts @@ -195,6 +197,39 @@ av_perms_def : CLASS identifier '{' identifier_list '}' | CLASS identifier INHERITS identifier '{' identifier_list '}' {if (define_av_perms(TRUE)) return -1;} ; +opt_default_rules : default_rules + | + ; +default_rules : default_user_def + | default_role_def + | default_range_def + | default_rules default_user_def + | default_rules default_role_def + | default_rules default_range_def + ; +default_user_def : DEFAULT_USER names SOURCE ';' + {if (define_default_user(DEFAULT_SOURCE)) return -1; } + | DEFAULT_USER names TARGET ';' + {if (define_default_user(DEFAULT_TARGET)) return -1; } + ; +default_role_def : DEFAULT_ROLE names SOURCE ';' + {if (define_default_role(DEFAULT_SOURCE)) return -1; } + | DEFAULT_ROLE names TARGET ';' + {if (define_default_role(DEFAULT_TARGET)) return -1; } + ; +default_range_def : DEFAULT_RANGE names SOURCE LOW ';' + {if (define_default_range(DEFAULT_SOURCE_LOW)) return -1; } + | DEFAULT_RANGE names SOURCE HIGH ';' + {if (define_default_range(DEFAULT_SOURCE_HIGH)) return -1; } + | DEFAULT_RANGE names SOURCE LOW_HIGH ';' + {if (define_default_range(DEFAULT_SOURCE_LOW_HIGH)) return -1; } + | DEFAULT_RANGE names TARGET LOW ';' + {if (define_default_range(DEFAULT_TARGET_LOW)) return -1; } + | DEFAULT_RANGE names TARGET HIGH ';' + {if (define_default_range(DEFAULT_TARGET_HIGH)) return -1; } + | DEFAULT_RANGE names TARGET LOW_HIGH ';' + {if (define_default_range(DEFAULT_TARGET_LOW_HIGH)) return -1; } + ; opt_mls : mls | ; diff --git a/checkpolicy/policy_scan.l b/checkpolicy/policy_scan.l index 9b24db5..e767b5f 100644 --- a/checkpolicy/policy_scan.l +++ b/checkpolicy/policy_scan.l @@ -221,6 +221,18 @@ policycap | POLICYCAP { return(POLICYCAP); } permissive | PERMISSIVE { return(PERMISSIVE); } +default_user | +DEFAULT_USER { return(DEFAULT_USER); } +default_role | +DEFAULT_ROLE { return(DEFAULT_ROLE); } +default_range | +DEFAULT_RANGE { return(DEFAULT_RANGE); } +low-high | +LOW-HIGH { return(LOW_HIGH); } +high | +HIGH { return(HIGH); } +low | +LOW { return(LOW); } "/"({alnum}|[_\.\-/])* { return(PATH); } \"({alnum}|[_\.\-\~])+\" { return(FILENAME); } {letter}({alnum}|[_\-])*([\.]?({alnum}|[_\-]))* { return(IDENTIFIER); }