checkpolicy: allow genfscon statements in modules
PATCH v3 1/1 checkpolicy: allow genfscon statements in modules
This patch provides the checkpolicy support for the usage of genfscon statements in policy modules. It also provides dismod/dispol entries to look at the genfscon entries in a policy module in order to verify proper sorting. The module must declare/require all of the components of the context associated with the declaration but the actual validation of that context is delayed until link time.
Comments and criticism appreciated.
Signed-off-by Eric Paris <[email protected]>
---
policy_define.c | 50 +++++++++++++++++++++++++++----------------------- policy_parse.y | 13 +++++++------ test/dismod.c | 31 +++++++++++++++++++++++++++++++ test/dispol.c | 29 +++++++++++++++++++++++++++++ 4 files changed, 94 insertions(+), 29 deletions(-)
policy_define.c +27 -23
@@ -68,7 +68,6 @@ extern int yyerror(char *msg);static char errormsg[ERRORMSG_LEN +1 ] = {0 };static int id_has_dot (char *id); -static int parse_security_context (context_struct_t *c);/* initialize all of the state variables for the scanner/parser */ void init_parser (int pass_number)
@@ -3008,7 +3007,7 @@ int define_user(void)return 0 ; } -static int parse_security_context (context_struct_t * c) +static int parse_security_context (context_struct_t *c,uint32_t check_valid) {char *id;role_datum_t *role;
@@ -3160,7 +3159,7 @@ static int parse_security_context(contex } } -if (!policydb_context_isvalid (policydbp, c)) { +if (check_valid && !policydb_context_isvalid (policydbp, c)) {yyerror ("invalid security context" ); goto bad; }
@@ -3180,7 +3179,7 @@ int define_initial_sid_context(void)if (pass ==1 ) { id = (char *)queue_remove (id_queue);free (id); -parse_security_context (NULL ); +parse_security_context (NULL ,1 );return 0 ; }
@@ -3208,7 +3207,7 @@ int define_initial_sid_context(void)/* no need to keep the sid name */ free (id); -if (parse_security_context (&c->context[0 ])) +if (parse_security_context (&c->context[0 ],1 ))return -1 ;return 0 ;
@@ -3219,8 +3218,8 @@ int define_fs_context(unsigned int majorocontext_t *newc, *c, *head;if (pass ==1 ) { -parse_security_context (NULL ); -parse_security_context (NULL ); +parse_security_context (NULL ,1 ); +parse_security_context (NULL ,1 );return 0 ; }
@@ -3239,12 +3238,12 @@ int define_fs_context(unsigned int major }sprintf (newc->u.name,"%02x:%02x" , major, minor); -if (parse_security_context (&newc->context[0 ])) { +if (parse_security_context (&newc->context[0 ],1 )) {free (newc->u.name);free (newc);return -1 ; } -if (parse_security_context (&newc->context[1 ])) { +if (parse_security_context (&newc->context[1 ],1 )) {context_destroy (&newc->context[0 ]);free (newc->u.name);free (newc);
@@ -3279,7 +3278,7 @@ int define_port_context(unsigned int lowif (pass ==1 ) { id = (char *)queue_remove (id_queue);free (id); -parse_security_context (NULL ); +parse_security_context (NULL ,1 );return 0 ; }
@@ -3315,7 +3314,7 @@ int define_port_context(unsigned int lowreturn -1 ; } -if (parse_security_context (&newc->context[0 ])) { +if (parse_security_context (&newc->context[0 ],1 )) {free (newc);return -1 ; }
@@ -3360,8 +3359,8 @@ int define_netif_context(void)if (pass ==1 ) {free (queue_remove (id_queue)); -parse_security_context (NULL ); -parse_security_context (NULL ); +parse_security_context (NULL ,1 ); +parse_security_context (NULL ,1 );return 0 ; }
@@ -3377,12 +3376,12 @@ int define_netif_context(void)free (newc);return -1 ; } -if (parse_security_context (&newc->context[0 ])) { +if (parse_security_context (&newc->context[0 ],1 )) {free (newc->u.name);free (newc);return -1 ; } -if (parse_security_context (&newc->context[1 ])) { +if (parse_security_context (&newc->context[1 ],1 )) {context_destroy (&newc->context[0 ]);free (newc->u.name);free (newc);
@@ -3417,7 +3416,7 @@ int define_ipv4_node_context()if (pass ==1 ) {free (queue_remove (id_queue));free (queue_remove (id_queue)); -parse_security_context (NULL ); +parse_security_context (NULL ,1 ); goto out; }
@@ -3464,7 +3463,7 @@ int define_ipv4_node_context() newc->u.node.addr = addr.s_addr; newc->u.node.mask = mask.s_addr; -if (parse_security_context (&newc->context[0 ])) { +if (parse_security_context (&newc->context[0 ],1 )) {free (newc);return -1 ; }
@@ -3498,7 +3497,7 @@ int define_ipv6_node_context(void)if (pass ==1 ) {free (queue_remove (id_queue));free (queue_remove (id_queue)); -parse_security_context (NULL ); +parse_security_context (NULL ,1 ); goto out; }
@@ -3545,7 +3544,7 @@ int define_ipv6_node_context(void)memcpy (&newc->u.node6.addr[0 ], &addr.s6_addr32[0 ],16 );memcpy (&newc->u.node6.mask[0 ], &mask.s6_addr32[0 ],16 ); -if (parse_security_context (&newc->context[0 ])) { +if (parse_security_context (&newc->context[0 ],1 )) {free (newc); rc =-1 ; goto out;
@@ -3577,7 +3576,7 @@ int define_fs_use(int behavior)if (pass ==1 ) {free (queue_remove (id_queue)); -parse_security_context (NULL ); +parse_security_context (NULL ,1 );return 0 ; }
@@ -3594,7 +3593,7 @@ int define_fs_use(int behavior)return -1 ; } newc->v.behavior = behavior; -if (parse_security_context (&newc->context[0 ])) { +if (parse_security_context (&newc->context[0 ],1 )) {free (newc->u.name);free (newc);return -1 ;
@@ -3624,13 +3623,14 @@ int define_genfs_context_helper(char *fsocontext_t *newc, *c, *head, *p;char *type =NULL ;int len, len2; +uint32_t check_valid;if (pass ==1 ) {free (fstype);free (queue_remove (id_queue));if (has_type)free (queue_remove (id_queue)); -parse_security_context (NULL ); +parse_security_context (NULL ,0 );return 0 ; }
@@ -3701,7 +3701,11 @@ int define_genfs_context_helper(char *fs goto fail; } } -if (parse_security_context (&newc->context[0 ])) +if (policydbp->policy_type ==POLICY_MOD ) + check_valid =0 ; +else + check_valid =1 ; +if (parse_security_context (&newc->context[0 ], check_valid)) goto fail; head = genfs->head;
policy_parse.y +7 -6
@@ -612,12 +612,12 @@ fs_use_def : FSUSEXATTR ide | FSUSETRANS identifier security_context_def ';' {if (define_fs_use(SECURITY_FS_USE_TRANS)) return -1;} ; -opt_genfs_contexts : genfs_contexts - | - ; -genfs_contexts : genfs_context_def - | genfs_contexts genfs_context_def - ; +opt_genfs_contexts : genfs_context_defs + | /* empty */ + ; +genfs_context_defs : genfs_context_defs genfs_context_def + | genfs_context_def + ; genfs_context_def : GENFSCON identifier path '-' identifier security_context_def {if (define_genfs_context(1)) return -1;} | GENFSCON identifier path '-' '-' {insert_id("-", 0);} security_context_def
@@ -734,6 +734,7 @@ avrule_decl : rbac_decl | cond_stmt_def | require_block | optional_block + | genfs_context_defs | ';' ; require_block : REQUIRE '{' require_list '}'
test/dismod.c +31 -0
@@ -787,6 +787,32 @@ static void display_policycaps(policydb_ } } +static void display_context (policydb_t *p,context_struct_t *context,FILE *fp) +{ +char *user, *role, *type; + user = p->p_user_val_to_name[context->user -1 ]; + role = p->p_role_val_to_name[context->role -1 ]; + type = p->p_type_val_to_name[context->type -1 ]; +fprintf (fp,"%s:%s:%s" , user, role, type); +} + +static void display_genfs_context (policydb_t *p,FILE *fp) +{ +genfs_t *genfs = p->genfs; +ocontext_t *context; +while (genfs) { +fprintf (fp,"genfs_context: fs=%s\n" , genfs->fstype); + context = genfs->head; +while (context) { +fprintf (fp,"\t%-32s\t%d\t" , context->u.name, context->v.sclass); +display_context (p, &context->context[0 ], fp); +fprintf (fp,"\n" ); + context = context->next; + } + genfs = genfs->next; + } +} +int menu () {printf ("\nSelect a command:\n" );
@@ -804,6 +830,7 @@ int menu()printf ("a) Display avrule requirements\n" );printf ("b) Display avrule declarations\n" );printf ("c) Display policy capabilities\n" ); +printf ("g) Display genfs_context entries\n" );printf ("l) Link in a module\n" );printf ("u) Display the unknown handling setting\n" );printf ("\n" );
@@ -936,6 +963,10 @@ int main(int argc, char **argv)if (out_fp != stdout)printf ("\nOutput to file: %s\n" , OutfileName);break ; +case 'g' : +case 'G' : +display_genfs_context (&policydb, out_fp); +break ;case 'l' :link_module (&policydb, out_fp);break ;
test/dispol.c +29 -0
@@ -319,6 +319,31 @@ static void display_policycaps(policydb_ } } +static void display_context (policydb_t *p,context_struct_t *context,FILE *fp) +{ +char *user, *role, *type; + user = p->p_user_val_to_name[context->user -1 ]; + role = p->p_role_val_to_name[context->role -1 ]; + type = p->p_type_val_to_name[context->type -1 ]; +fprintf (fp,"%s:%s:%s" , user, role, type); +} +static void display_genfs_context (policydb_t *p,FILE *fp) +{ +genfs_t *genfs = p->genfs; +ocontext_t *context; +while (genfs) { +fprintf (fp,"genfs_context: fs=%s\n" , genfs->fstype); + context = genfs->head; +while (context) { +fprintf (fp,"\t%-32s\t%d\t" , context->u.name, context->v.sclass); +display_context (p, &context->context[0 ], fp); +fprintf (fp,"\n" ); + context = context->next; + } + genfs = genfs->next; + } +} +static void display_id (policydb_t *p,FILE *fp,uint32_t symbol_type,uint32_t symbol_value,char *prefix) {
@@ -353,6 +378,7 @@ int menu()printf ("7) change a boolean value\n" );printf ("\n" );printf ("c) display policy capabilities\n" ); +printf ("g) display all genfs_context entries\n" );printf ("p) display the list of permissive types\n" );printf ("u) display unknown handling setting\n" );printf ("f) set output file\n" );
@@ -470,6 +496,9 @@ int main(int argc, char **argv)case 'c' :display_policycaps (&policydb, out_fp);break ; +case 'g' : +display_genfs_context (&policydb, out_fp); +break ;case 'p' :display_permissive (&policydb, out_fp);break ;
--
This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to [email protected] with the words "unsubscribe selinux" without quotes as the message.