> How do we handle the case when filename component contains whitespaces? > Or multibyte characters? > Right now, I don't think this issue has higher priority, because it is hard to imagine actual case we need to set up special cases in TYPE_TRANSITON on files with whitespace or multibyte names. (So, my two patches I sent does not handle these cases right now.) Thanks, -- NEC Europe Ltd, SAP Global Competence Center KaiGai Kohei <kohei.kaigai@xxxxxxxxxx> > -----Original Message----- > From: owner-selinux@xxxxxxxxxxxxx [mailto:owner-selinux@xxxxxxxxxxxxx] On > Behalf Of Kohei Kaigai > Sent: 31. MÃrz 2011 12:46 > To: Eric Paris; selinux@xxxxxxxxxxxxx > Cc: method@xxxxxxxxxxxxxxx; sds@xxxxxxxxxxxxx > Subject: RE: [PATCH] checkpolicy: add support for using last path component > in type transition rules > > I have a question in a corner case. > > How do we handle the case when filename component contains whitespaces? > Or multibyte characters? > > Rught now, policy_scan.l of checkpolicy defines IDENTIFIER element as follows: > > {letter}({alnum}|[_\-])*([\.]?({alnum}|[_\-]))* { return(IDENTIFIER); } > > I think it is an issue in corner case, however, to be considered. > > IMO, it is not a good idea to handle multibyte support by ourselves. > The security policy should have same character set with other stuffs. > > Regarding to whitespaces, is it possible to define a syntax without conflicts > to the existing syntax? > > Thanks, > -- > NEC Europe Ltd, Global Competence Center > KaiGai Kohei <kohei.kaigai@xxxxxxxxxx> > > > > -----Original Message----- > > From: owner-selinux@xxxxxxxxxxxxx [mailto:owner-selinux@xxxxxxxxxxxxx] On > > Behalf Of Eric Paris > > Sent: 28. MÃrz 2011 19:00 > > To: selinux@xxxxxxxxxxxxx > > Cc: method@xxxxxxxxxxxxxxx; sds@xxxxxxxxxxxxx > > Subject: [PATCH] checkpolicy: add support for using last path component in > > type transition rules > > > > This patch adds support for using the last path component as part of the > > information in making labeling decisions for new objects. A example > > rule looks like so: > > > > type_transition unconfined_t etc_t:file system_conf_t eric; > > > > This rule says if unconfined_t creates a file in a directory labeled > > etc_t and the last path component is "eric" (no globbing, no matching > > magic, just exact strcmp) it should be labeled system_conf_t. > > > > The kernel and policy representation does not have support for such > > rules in conditionals, and thus policy explicitly notes that fact if > > such a rule is added to a conditional. > > > > Signed-off-by: Eric Paris <eparis@xxxxxxxxxx> > > --- > > > > diff -up checkpolicy-2.0.23/module_compiler.c.eparis2 > > checkpolicy-2.0.23/module_compiler.c > > --- checkpolicy-2.0.23/module_compiler.c.eparis2 2010-12-21 > > 16:35:45.000000000 -0500 > > +++ checkpolicy-2.0.23/module_compiler.c 2011-03-23 > 14:19:51.152530839 > > -0400 > > @@ -1313,6 +1313,18 @@ void append_role_allow(role_allow_rule_t > > } > > > > /* 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 -up checkpolicy-2.0.23/module_compiler.h.eparis2 > > checkpolicy-2.0.23/module_compiler.h > > --- checkpolicy-2.0.23/module_compiler.h.eparis2 2010-12-21 > > 16:35:45.000000000 -0500 > > +++ checkpolicy-2.0.23/module_compiler.h 2011-03-23 > 14:19:51.154531123 > > -0400 > > @@ -80,6 +80,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 -up checkpolicy-2.0.23/policy_define.c.eparis2 > > checkpolicy-2.0.23/policy_define.c > > --- checkpolicy-2.0.23/policy_define.c.eparis2 2010-12-21 > > 16:35:45.000000000 -0500 > > +++ checkpolicy-2.0.23/policy_define.c 2011-03-28 > 13:50:57.667710915 > > -0400 > > @@ -2196,6 +2196,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 -up checkpolicy-2.0.23/policy_define.h.eparis2 > > checkpolicy-2.0.23/policy_define.h > > --- checkpolicy-2.0.23/policy_define.h.eparis2 2010-12-21 > > 16:35:45.000000000 -0500 > > +++ checkpolicy-2.0.23/policy_define.h 2011-03-28 > 13:50:05.489297128 > > -0400 > > @@ -16,6 +16,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); > > @@ -47,6 +48,7 @@ int define_range_trans(int class_specifi > > 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 -up checkpolicy-2.0.23/policy_parse.y.eparis2 > > checkpolicy-2.0.23/policy_parse.y > > --- checkpolicy-2.0.23/policy_parse.y.eparis2 2011-03-23 > > 14:19:51.133528148 -0400 > > +++ checkpolicy-2.0.23/policy_parse.y 2011-03-28 13:49:03.489482156 > > -0400 > > @@ -342,7 +342,10 @@ cond_rule_def : cond_transitio > > | require_block > > { $$ = NULL; } > > ; > > -cond_transition_def : TYPE_TRANSITION names names ':' names identifier > > ';' > > +cond_transition_def : TYPE_TRANSITION names names ':' names identifier > > identifier ';' > > + { $$ = 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 ';' > > @@ -377,7 +380,10 @@ cond_dontaudit_def : DONTAUDIT names nam > > { $$ = 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 > > identifier ';' > > + {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;} > > diff -up checkpolicy-2.0.23/test/dismod.c.eparis2 > > checkpolicy-2.0.23/test/dismod.c > > --- checkpolicy-2.0.23/test/dismod.c.eparis2 2011-03-23 > > 14:19:51.142529423 -0400 > > +++ checkpolicy-2.0.23/test/dismod.c 2011-03-23 14:19:51.160531973 > > -0400 > > @@ -52,6 +52,7 @@ > > #define DISPLAY_AVBLOCK_ROLE_ALLOW 4 > > #define DISPLAY_AVBLOCK_REQUIRES 5 > > #define DISPLAY_AVBLOCK_DECLARES 6 > > +#define DISPLAY_AVBLOCK_FILENAME_TRANS 7 > > > > static policydb_t policydb; > > extern unsigned int ss_initialized; > > @@ -480,6 +481,18 @@ void display_role_allow(role_allow_rule_ > > } > > } > > > > +void display_filename_trans(filename_trans_rule_t * tr, policydb_t * p, > FILE > > * fp) > > +{ > > + for (; tr; tr = tr->next) { > > + fprintf(fp, "filename transition %s", tr->name); > > + display_type_set(&tr->stypes, 0, p, fp); > > + display_type_set(&tr->ttypes, 0, p, fp); > > + display_id(p, fp, SYM_CLASSES, tr->tclass - 1, ":"); > > + display_id(p, fp, SYM_TYPES, tr->otype - 1, ""); > > + fprintf(fp, "\n"); > > + } > > +} > > + > > int role_display_callback(hashtab_key_t key, hashtab_datum_t datum, void > > *data) > > { > > role_datum_t *role; > > @@ -647,6 +660,11 @@ int display_avdecl(avrule_decl_t * decl, > > } > > break; > > } > > + case DISPLAY_AVBLOCK_FILENAME_TRANS: > > + display_filename_trans(decl->filename_trans_rules, > > policy, > > + out_fp); > > + return -1; > > + break; > > default:{ > > assert(0); > > } > > @@ -812,6 +830,7 @@ int menu() > > printf("c) Display policy capabilities\n"); > > printf("l) Link in a module\n"); > > printf("u) Display the unknown handling setting\n"); > > + printf("F) Display filename_trans rules\n"); > > printf("\n"); > > printf("f) set output file\n"); > > printf("m) display menu\n"); > > @@ -947,6 +966,11 @@ int main(int argc, char **argv) > > if (out_fp != stdout) > > printf("\nOutput to file: %s\n", > > OutfileName); > > break; > > + case 'F': > > + fprintf(out_fp, "filename_trans rules:\n"); > > + display_avblock(DISPLAY_AVBLOCK_FILENAME_TRANS, > > + 0, &policydb, out_fp); > > + break; > > case 'l': > > link_module(&policydb, out_fp); > > break; > > diff -up checkpolicy-2.0.23/test/dispol.c.eparis2 > > checkpolicy-2.0.23/test/dispol.c > > --- checkpolicy-2.0.23/test/dispol.c.eparis2 2010-12-21 > > 16:35:45.000000000 -0500 > > +++ checkpolicy-2.0.23/test/dispol.c 2011-03-23 14:19:51.162532256 > > -0400 > > @@ -341,6 +341,21 @@ static void display_permissive(policydb_ > > } > > } > > > > +static void display_filename_trans(policydb_t *p, FILE *fp) > > +{ > > + filename_trans_t *ft; > > + > > + fprintf(fp, "filename_trans rules:\n"); > > + for (ft = p->filename_trans; ft; ft = ft->next) { > > + fprintf(fp, "%s\n", ft->name); > > + display_id(p, fp, SYM_TYPES, ft->stype - 1, ""); > > + display_id(p, fp, SYM_TYPES, ft->ttype - 1, ""); > > + display_id(p, fp, SYM_CLASSES, ft->tclass - 1, ":"); > > + display_id(p, fp, SYM_TYPES, ft->otype - 1, ""); > > + fprintf(fp, "\n"); > > + } > > +} > > + > > int menu() > > { > > printf("\nSelect a command:\n"); > > @@ -355,6 +370,8 @@ int menu() > > printf("c) display policy capabilities\n"); > > printf("p) display the list of permissive types\n"); > > printf("u) display unknown handling setting\n"); > > + printf("F) display filename_trans rules\n"); > > + printf("\n"); > > printf("f) set output file\n"); > > printf("m) display menu\n"); > > printf("q) quit\n"); > > @@ -492,6 +509,9 @@ int main(int argc, char **argv) > > if (out_fp != stdout) > > printf("\nOutput to file: %s\n", > > OutfileName); > > break; > > + case 'F': > > + display_filename_trans(&policydb, out_fp); > > + break; > > case 'q': > > policydb_destroy(&policydb); > > exit(0); > > > > > > > > -- > > This message was distributed to subscribers of the selinux mailing list. > > If you no longer wish to subscribe, send mail to majordomo@xxxxxxxxxxxxx > with > > the words "unsubscribe selinux" without quotes as the message. > > > > > > Click > > > https://www.mailcontrol.com/sr/5jPLEbCyJS7TndxI!oX7UlEvFrFJ1EkCf!VcU6Gcvz > > z3ej9D!FP2EWnZ9OOh!frND2OX8tvfK1ylpYdScFxEUA== to report this email as > > spam. > > > -- > This message was distributed to subscribers of the selinux mailing list. > If you no longer wish to subscribe, send mail to majordomo@xxxxxxxxxxxxx with > the words "unsubscribe selinux" without quotes as the message. -- This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to majordomo@xxxxxxxxxxxxx with the words "unsubscribe selinux" without quotes as the message.