diff options
Diffstat (limited to 'libqpol/src')
-rw-r--r-- | libqpol/src/Makefile.am | 1 | ||||
-rw-r--r-- | libqpol/src/libqpol.map | 1 | ||||
-rw-r--r-- | libqpol/src/module_compiler.c | 12 | ||||
-rw-r--r-- | libqpol/src/module_compiler.h | 1 | ||||
-rw-r--r-- | libqpol/src/policy_define.c | 188 | ||||
-rw-r--r-- | libqpol/src/policy_define.h | 2 | ||||
-rw-r--r-- | libqpol/src/policy_parse.y | 13 | ||||
-rw-r--r-- | libqpol/src/policy_scan.l | 1 |
8 files changed, 216 insertions, 3 deletions
diff --git a/libqpol/src/Makefile.am b/libqpol/src/Makefile.am index 34d87a6..0889a61 100644 --- a/libqpol/src/Makefile.am +++ b/libqpol/src/Makefile.am @@ -48,6 +48,7 @@ libqpol_a_SOURCES = \ syn_rule_internal.h \ syn_rule_query.c \ terule_query.c \ + ftrule_query.c \ type_query.c \ user_query.c \ util.c \ diff --git a/libqpol/src/libqpol.map b/libqpol/src/libqpol.map index dd293bc..6973cca 100644 --- a/libqpol/src/libqpol.map +++ b/libqpol/src/libqpol.map @@ -34,6 +34,7 @@ VERS_1.2 { qpol_policy_reevaluate_conds; qpol_portcon_*; qpol_range_trans_*; + qpol_filename_trans_*; qpol_role_*; qpol_syn_avrule_*; qpol_syn_terule_*; diff --git a/libqpol/src/module_compiler.c b/libqpol/src/module_compiler.c index dc19798..b06e285 100644 --- a/libqpol/src/module_compiler.c +++ b/libqpol/src/module_compiler.c @@ -1247,6 +1247,18 @@ void append_role_allow(role_allow_rule_t * role_allow_rules) } /* this doesn't actually append, but really prepends it */ +void append_filename_trans(filename_trans_rule_t * filename_trans_rules) +{ + avrule_decl_t *decl = stack_top->decl; + + /* filename transitions are not allowed within conditionals */ + assert(stack_top->type == 1); + + filename_trans_rules->next = decl->filename_trans_rules; + decl->filename_trans_rules = filename_trans_rules; +} + +/* this doesn't actually append, but really prepends it */ void append_range_trans(range_trans_rule_t * range_tr_rules) { avrule_decl_t *decl = stack_top->decl; diff --git a/libqpol/src/module_compiler.h b/libqpol/src/module_compiler.h index 489086d..d46dca6 100644 --- a/libqpol/src/module_compiler.h +++ b/libqpol/src/module_compiler.h @@ -86,6 +86,7 @@ void append_avrule(avrule_t * avrule); void append_role_trans(role_trans_rule_t * role_tr_rules); void append_role_allow(role_allow_rule_t * role_allow_rules); void append_range_trans(range_trans_rule_t * range_tr_rules); +void append_filename_trans(filename_trans_rule_t * filename_trans_rules); /* Create a new optional block and add it to the global policy. * During the second pass resolve the block's requirements. Return 0 diff --git a/libqpol/src/policy_define.c b/libqpol/src/policy_define.c index c94f7aa..fad6b60 100644 --- a/libqpol/src/policy_define.c +++ b/libqpol/src/policy_define.c @@ -2132,7 +2132,9 @@ int define_role_trans(void) free(id); /* This ebitmap business is just to ensure that there are not conflicting role_trans rules */ -#ifdef HAVE_SEPOL_USER_ROLE_MAPPING +#ifdef HAVE_SEPOL_ROLE_ATTRS + if (role_set_expand(&roles, &e_roles, policydbp, NULL, NULL)) +#elif HAVE_SEPOL_USER_ROLE_MAPPING if (role_set_expand(&roles, &e_roles, policydbp, NULL)) #else if (role_set_expand(&roles, &e_roles, policydbp)) @@ -2226,6 +2228,190 @@ int define_role_allow(void) return 0; } +avrule_t *define_cond_filename_trans(void) +{ + yyerror("type transitions with a filename not allowed inside " + "conditionals\n"); + return COND_ERR; +} + +int define_filename_trans(void) +{ + char *id, *name = NULL; + type_set_t stypes, ttypes; + ebitmap_t e_stypes, e_ttypes; + ebitmap_t e_tclasses; + 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; + int add; + + if (pass == 1) { + /* stype */ + while ((id = queue_remove(id_queue))) + free(id); + /* ttype */ + while ((id = queue_remove(id_queue))) + free(id); + /* tclass */ + while ((id = queue_remove(id_queue))) + free(id); + /* otype */ + id = queue_remove(id_queue); + free(id); + /* name */ + id = queue_remove(id_queue); + free(id); + return 0; + } + + + add = 1; + type_set_init(&stypes); + while ((id = queue_remove(id_queue))) { + if (set_types(&stypes, id, &add, 0)) + goto bad; + } + + add =1; + type_set_init(&ttypes); + while ((id = queue_remove(id_queue))) { + if (set_types(&ttypes, id, &add, 0)) + goto bad; + } + + 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); + } + + id = (char *)queue_remove(id_queue); + if (!id) { + yyerror("no otype in transition definition?"); + goto bad; + } + if (!is_id_in_scope(SYM_TYPES, id)) { + yyerror2("type %s is not within scope", id); + free(id); + goto bad; + } + typdatum = hashtab_search(policydbp->p_types.table, id); + if (!typdatum) { + yyerror2("unknown type %s used in transition definition", id); + goto bad; + } + free(id); + otype = typdatum->s.value; + + name = queue_remove(id_queue); + if (!name) { + yyerror("no pathname specified in filename_trans definition?"); + goto bad; + } + + /* We expand the class set into seperate rules. We expand the types + * just to make sure there are not duplicates. They will get turned + * into seperate rules later */ + ebitmap_init(&e_stypes); + if (type_set_expand(&stypes, &e_stypes, policydbp, 1)) + goto bad; + + ebitmap_init(&e_ttypes); + if (type_set_expand(&ttypes, &e_ttypes, policydbp, 1)) + goto bad; + + ebitmap_for_each_bit(&e_tclasses, cnode, c) { + if (!ebitmap_node_get_bit(cnode, c)) + continue; + ebitmap_for_each_bit(&e_stypes, snode, s) { + if (!ebitmap_node_get_bit(snode, s)) + continue; + ebitmap_for_each_bit(&e_ttypes, tnode, t) { + if (!ebitmap_node_get_bit(tnode, t)) + continue; + + for (ft = policydbp->filename_trans; ft; ft = ft->next) { + if (ft->stype == (s + 1) && + ft->ttype == (t + 1) && + ft->tclass == (c + 1) && + !strcmp(ft->name, name)) { + yyerror2("duplicate filename transition for: filename_trans %s %s %s:%s", + name, + policydbp->p_type_val_to_name[s], + policydbp->p_type_val_to_name[t], + policydbp->p_class_val_to_name[c]); + goto bad; + } + } + + ft = malloc(sizeof(*ft)); + if (!ft) { + yyerror("out of memory"); + goto bad; + } + memset(ft, 0, sizeof(*ft)); + + ft->next = policydbp->filename_trans; + policydbp->filename_trans = ft; + + ft->name = strdup(name); + if (!ft->name) { + yyerror("out of memory"); + goto bad; + } + ft->stype = s + 1; + ft->ttype = t + 1; + ft->tclass = c + 1; + ft->otype = otype; + } + } + + /* Now add the real rule since we didn't find any duplicates */ + ftr = malloc(sizeof(*ftr)); + if (!ftr) { + yyerror("out of memory"); + goto bad; + } + filename_trans_rule_init(ftr); + append_filename_trans(ftr); + + ftr->name = strdup(name); + ftr->stypes = stypes; + ftr->ttypes = ttypes; + ftr->tclass = c + 1; + ftr->otype = otype; + } + + free(name); + ebitmap_destroy(&e_stypes); + ebitmap_destroy(&e_ttypes); + ebitmap_destroy(&e_tclasses); + + return 0; + +bad: + free(name); + return -1; +} + static constraint_expr_t *constraint_expr_clone(constraint_expr_t * expr) { constraint_expr_t *h = NULL, *l = NULL, *e, *newe; diff --git a/libqpol/src/policy_define.h b/libqpol/src/policy_define.h index 7be626c..f273fed 100644 --- a/libqpol/src/policy_define.h +++ b/libqpol/src/policy_define.h @@ -26,6 +26,7 @@ avrule_t *define_cond_compute_type(int which); avrule_t *define_cond_pol_list(avrule_t * avlist, avrule_t * stmt); avrule_t *define_cond_te_avtab(int which); +avrule_t *define_cond_filename_trans(void); cond_expr_t *define_cond_expr(uint32_t expr_type, void *arg1, void *arg2); int define_attrib(void); int define_av_perms(int inherits); @@ -58,6 +59,7 @@ int define_range_trans(int class_specified); int define_role_allow(void); int define_role_trans(void); int define_role_types(void); +int define_filename_trans(void); int define_sens(void); int define_te_avtab(int which); int define_typealias(void); diff --git a/libqpol/src/policy_parse.y b/libqpol/src/policy_parse.y index 84f4114..dc16c6f 100644 --- a/libqpol/src/policy_parse.y +++ b/libqpol/src/policy_parse.y @@ -98,6 +98,7 @@ extern char *qpol_src_inputlim;/* end of data */ %type <require_func> require_decl_def %token PATH +%token FILENAME %token CLONE %token COMMON %token CLASS @@ -360,7 +361,10 @@ cond_rule_def : cond_transition_def | require_block { $$ = NULL; } ; -cond_transition_def : TYPE_TRANSITION names names ':' names identifier ';' +cond_transition_def : TYPE_TRANSITION names names ':' names identifier filename ';' + { $$ = define_cond_filename_trans() ; + if ($$ == COND_ERR) return -1;} + | TYPE_TRANSITION names names ':' names identifier ';' { $$ = define_cond_compute_type(AVRULE_TRANSITION) ; if ($$ == COND_ERR) return -1;} | TYPE_MEMBER names names ':' names identifier ';' @@ -395,7 +399,9 @@ cond_dontaudit_def : DONTAUDIT names names ':' names names ';' { $$ = define_cond_te_avtab(AVRULE_DONTAUDIT); if ($$ == COND_ERR) return -1; } ; -transition_def : TYPE_TRANSITION names names ':' names identifier ';' +transition_def : TYPE_TRANSITION names names ':' names identifier filename ';' + {if (define_filename_trans()) return -1; } + | TYPE_TRANSITION names names ':' names identifier ';' {if (define_compute_type(AVRULE_TRANSITION)) return -1;} | TYPE_MEMBER names names ':' names identifier ';' {if (define_compute_type(AVRULE_MEMBER)) return -1;} @@ -752,6 +758,9 @@ identifier : IDENTIFIER path : PATH { if (insert_id(yytext,0)) return -1; } ; +filename : FILENAME + { yytext[strlen(yytext) - 1] = '\0'; if (insert_id(yytext + 1,0)) return -1; } + ; number : NUMBER { $$ = strtoul(yytext,NULL,0); } ; diff --git a/libqpol/src/policy_scan.l b/libqpol/src/policy_scan.l index 75485f3..30203cd 100644 --- a/libqpol/src/policy_scan.l +++ b/libqpol/src/policy_scan.l @@ -235,6 +235,7 @@ POLICYCAP { return(POLICYCAP); } permissive | PERMISSIVE { return(PERMISSIVE); } "/"({alnum}|[_\.\-/])* { return(PATH); } +\"({alnum}|[_\.\-])+\" { return(FILENAME); } {letter}({alnum}|[_\-])*([\.]?({alnum}|[_\-]))* { return(IDENTIFIER); } {digit}+|0x{hexval}+ { return(NUMBER); } {digit}{1,3}(\.{digit}{1,3}){3} { return(IPV4_ADDR); } |