> > 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.) > However, it is "right now". We may have possible bug about object names including whitespace such as "resolve.conf but fake". If we supply the name on the /selinux/create, sscanf picks "resolve.conf" as forth argument without " but fake", then we may receive specially configured security context unexpectedly. So, I think we need to handle this problem in this stage. One possible idea is using url encode to encapsulate characters neither alphabets nor numbers. E.g) "resolve.conf but fake" -> "resolve.conf%20but%20fake" Please any comments. 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: 1. April 2011 15:56 > 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 > > > 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. -- 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.