Date: Wed, 24 Nov 2004 15:58:36 GMT From: Andrew Reisse <areisse@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 65787 for review Message-ID: <200411241558.iAOFwaaJ041789@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=65787 Change 65787 by areisse@areisse_tislabs on 2004/11/24 15:58:17 Begin merging checkpolicy changes from selinux version 2004081908. Affected files ... .. //depot/projects/trustedbsd/sebsd/contrib/sebsd/checkpolicy/checkpolicy.c#7 integrate .. //depot/projects/trustedbsd/sebsd/contrib/sebsd/checkpolicy/checkpolicy.h#3 integrate .. //depot/projects/trustedbsd/sebsd/contrib/sebsd/checkpolicy/genpolusers.c#1 branch .. //depot/projects/trustedbsd/sebsd/contrib/sebsd/checkpolicy/policy_parse.y#4 integrate .. //depot/projects/trustedbsd/sebsd/contrib/sebsd/checkpolicy/policy_scan.l#3 integrate .. //depot/projects/trustedbsd/sebsd/contrib/sebsd/checkpolicy/users.l#1 branch .. //depot/projects/trustedbsd/sebsd/contrib/sebsd/checkpolicy/users.y#1 branch .. //depot/projects/trustedbsd/sebsd/contrib/sebsd/checkpolicy/write.c#2 integrate Differences ... ==== //depot/projects/trustedbsd/sebsd/contrib/sebsd/checkpolicy/checkpolicy.c#7 (text+ko) ==== @@ -1,10 +1,21 @@ /* - * Author : Stephen Smalley (NAI Labs), <ssmalley@nai.com> + * Author : Stephen Smalley, <sds@epoch.ncsc.mil> + */ + +/* Updated: Karl MacMillan <kmacmillan@tresys.com> + * + * Added conditional policy language extensions + * + * Updated: James Morris <jmorris@intercode.com.au> + * + * Added IPv6 support. * - * The policy compiler was originally written while I was employed by NSA, - * but I have implemented a number of extensions and revisions since - * joining NAI Labs. + * Copyright (C) 2003 - 2004 Tresys Technology, LLC + * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2. */ /* FLASK */ @@ -27,6 +38,11 @@ * If '-d' is specified, then checkpolicy permits the user * to interactively test the security server functions with * the loaded policy configuration. + * + * If '-c' is specified, then the supplied parameter is used to + * determine which policy version to use for generating binary + * policy. This is for compatibility with older kernels. If any + * booleans or conditional rules are thrown away a warning is printed. */ #ifdef __FreeBSD__ @@ -59,6 +75,8 @@ extern queue_t id_queue; extern unsigned int policydb_errors; extern unsigned long policydb_lineno; +extern unsigned long source_lineno; +extern char source_file[]; extern unsigned int pass; extern FILE *yyin; @@ -68,6 +86,7 @@ char *txtfile = "policy.conf"; char *binfile = "policy"; +unsigned int policyvers = POLICYDB_VERSION_MAX; int selinux_enforcing = 1; int avc_ss_reset(__u32 seqno) @@ -77,15 +96,16 @@ void usage(char *progname) { - printf("usage: %s [-b] [-d] [-o output_file] [input_file]\n", progname); + printf("usage: %s [-b] [-d] [-c policyvers (%d-%d)] [-o output_file] [input_file]\n", + progname, POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX); exit(1); } static int print_sid(security_id_t sid, - context_struct_t * context, void *data) + context_struct_t * context __attribute__ ((unused)), void *data __attribute__ ((unused))) { security_context_t scontext; - unsigned int scontext_len; + size_t scontext_len; int rc; rc = security_sid_to_context(sid, &scontext, &scontext_len); @@ -112,7 +132,7 @@ return 0; } -static int type_attr_remove(hashtab_key_t key, hashtab_datum_t datum, void *p) +static int type_attr_remove(hashtab_key_t key __attribute__ ((unused)), hashtab_datum_t datum, void *p __attribute__ ((unused))) { type_datum_t *typdatum; @@ -249,14 +269,49 @@ } #endif -extern char *av_to_string(__u32 tclass, access_vector_t av); +static void cond_check_type_rules_list(cond_av_list_t *list) +{ + cond_av_list_t *cur = list; + + while (cur) { + if (cur->node->datum.specified & AVTAB_TYPE) { + if (avtab_search(&policydbp->te_avtab, &cur->node->key, AVTAB_TYPE)) { + fprintf(stderr, "conditional type rule for (%s, %s : %s) conflicts with entry in base policy; " + "conditional rule discarded.\n", policydbp->p_type_val_to_name[cur->node->key.source_type-1], + policydbp->p_type_val_to_name[cur->node->key.target_type-1], + policydbp->p_class_val_to_name[cur->node->key.target_class-1]); + cur->node->parse_context = (void*)0; + } else { + cur->node->parse_context = (void*)1; + } + } else { + cur->node->parse_context = (void*)1; + } + cur = cur->next; + } +} + +/* check for duplicate type rules - this has to be done after all of + * the parsing is finished because the conditional and base type rules + * are collected in the same pass */ +static void cond_check_type_rules(void) +{ + cond_list_t *node; + + for (node = policydbp->cond_list; node != NULL; node = node->next) { + cond_check_type_rules_list(node->true_list); + cond_check_type_rules_list(node->false_list); + } +} + +extern char *av_to_string(uint32_t tclass, access_vector_t av); -void check_assertion_helper(int stype, int ttype, ebitmap_t *tclasses, +void check_assertion_helper(unsigned int stype, unsigned int ttype, ebitmap_t *tclasses, access_vector_t *avp, unsigned long line) { avtab_key_t avkey; avtab_datum_t *avdatump; - int k; + unsigned int k; for (k = ebitmap_startbit(tclasses); k < ebitmap_length(tclasses); k++) { @@ -282,7 +337,7 @@ void check_assertions(void) { te_assert_t *a, *tmp; - int i, j; + unsigned int i, j; a = te_assertions; while (a) { @@ -308,6 +363,77 @@ } } +int display_bools() +{ + int i; + + for (i = 0; i < policydbp->p_bools.nprim; i++) { + printf("%s : %d\n", policydbp->p_bool_val_to_name[i], + policydbp->bool_val_to_struct[i]->state); + } + return 0; +} + +void display_expr(cond_expr_t *exp) +{ + + cond_expr_t *cur; + for (cur = exp; cur != NULL; cur = cur->next) { + switch (cur->expr_type) { + case COND_BOOL: + printf("%s ", policydbp->p_bool_val_to_name[cur->bool - 1]); + break; + case COND_NOT: + printf("! "); + break; + case COND_OR: + printf("|| "); + break; + case COND_AND: + printf("&& "); + break; + case COND_XOR: + printf("^ "); + break; + case COND_EQ: + printf("== "); + break; + case COND_NEQ: + printf("!= "); + break; + default: + printf("error!"); + break; + } + } +} + +int display_cond_expressions() +{ + cond_node_t *cur; + + for (cur = policydbp->cond_list; cur != NULL; cur = cur->next) { + printf("expression: "); + display_expr(cur->expr); + printf("current state: %d\n", cur->cur_state); + } + return 0; +} + +int change_bool(char *name, int state) +{ + cond_bool_datum_t *bool; + + bool = hashtab_search(policydbp->p_bools.table, name); + if (bool == NULL) { + printf("Could not find bool %s\n", name); + return -1; + } + bool->state = state; + evaluate_conds(policydbp); + return 0; +} + int main(int argc, char **argv) { security_class_t tclass; @@ -327,7 +453,7 @@ struct stat sb; size_t filelen; - while ((ch = getopt(argc, argv, "o:dbV")) != EOF) { + while ((ch = getopt(argc, argv, "o:dbVc:")) != EOF) { switch (ch) { case 'o': outfile = optarg; @@ -340,17 +466,39 @@ debug = 1; break; case 'V': -#ifdef CONFIG_SECURITY_SELINUX_MLS - printf("%d-mls\n", POLICYDB_VERSION); -#else - printf("%d\n", POLICYDB_VERSION); -#endif - exit(0); + show_version = 1; + break; + case 'c': { + long int n = strtol(optarg, NULL, 10); + if (errno) { + fprintf(stderr, "Invalid policyvers specified: %s\n", optarg); + usage(argv[0]); + exit(1); + } + if (n < POLICYDB_VERSION_MIN || n > POLICYDB_VERSION_MAX) { + fprintf(stderr, "policyvers value %ld not in range %d-%d\n", + n, POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX); + usage(argv[0]); + exit(1); + } + if (policyvers != n) + policyvers = n; + break; + } default: usage(argv[0]); } } + if (show_version) { +#ifdef CONFIG_SECURITY_SELINUX_MLS + printf("%d-mls (compatibility range %d-%d)\n", policyvers, POLICYDB_VERSION_MAX, POLICYDB_VERSION_MIN); +#else + printf("%d (compatibility range %d-%d)\n", policyvers, POLICYDB_VERSION_MAX, POLICYDB_VERSION_MIN); +#endif + exit(0); + } + if (optind != argc) { file = argv[optind++]; if (optind != argc) @@ -402,7 +550,7 @@ yyin = fopen(file, "r"); if (!yyin) { fprintf(stderr, "%s: unable to open %s\n", argv[0], - file); + file); exit(1); } @@ -423,6 +571,8 @@ } rewind(yyin); policydb_lineno = 1; + source_file[0] = '\0'; + source_lineno = 1; yyrestart(yyin); pass = 2; if (yyparse() || policydb_errors) { @@ -431,10 +581,19 @@ } queue_destroy(id_queue); + cond_check_type_rules(); + cond_optimize_lists(policydb.cond_list); + check_assertions(); if (policydb_errors) exit(1); + if (policyvers >= POLICYDB_VERSION_NLCLASS && + policydb.p_classes.nprim < SECCLASS_NETLINK_DNRT_SOCKET) { + fprintf(stderr, "%s: policy lacks new netlink classes, unable to generate policy version %d\n", argv[0], policyvers); + exit(1); + } + /* remove type attributes */ hashtab_map_remove_on_error(policydb.p_types.table, type_attr_remove, 0, 0); @@ -448,7 +607,7 @@ if (outfile) { printf("%s: writing binary representation (version %d) to %s\n", - argv[0], POLICYDB_VERSION, outfile); + argv[0], policyvers, outfile); outfp = fopen(outfile, "w"); if (!outfp) { perror(outfile); @@ -484,6 +643,9 @@ printf("c) Call fs_use\n"); printf("d) Call genfs_sid\n"); printf("e) Call get_user_sids\n"); + printf("f) display conditional bools\n"); + printf("g) display conditional expressions\n"); + printf("h) change a boolean value\n"); #ifdef EQUIVTYPES printf("z) Show equivalent types\n"); #endif @@ -730,14 +892,47 @@ printf("if_sid %d default_msg_sid %d\n", ssid, tsid); break; - case 'b': + case 'b': { + char *p; + int family, len; + struct in_addr addr4; + struct in6_addr addr6; + + printf("protocol family? "); + fgets(ans, sizeof(ans), stdin); + ans[strlen(ans) - 1] = 0; + if (!strcasecmp(ans, "ipv4")) + family = AF_INET; + else if (!strcasecmp(ans, "ipv6")) + family = AF_INET6; + else { + printf("unknown protocol family\n"); + break; + } + printf("node address? "); fgets(ans, sizeof(ans), stdin); ans[strlen(ans) - 1] = 0; + + if (family == AF_INET) { + p = (char *)&addr4; + len = sizeof(addr4); + } else { + p = (char *)&addr6; + len = sizeof(addr6); + } + + if (inet_pton(family, ans, p) < 1) { + printf("error parsing address\n"); + break; + } + + sepol_node_sid(family, p, len, &ssid); addr = inet_addr(ans); security_node_sid(AF_INET, &addr, sizeof addr, &ssid); printf("sid %d\n", ssid); break; + } case 'c': printf("fstype? "); fgets(ans, sizeof(ans), stdin); @@ -825,6 +1020,37 @@ break; } break; + case 'f': + display_bools(); + break; + case 'g': + display_cond_expressions(); + break; + case 'h': + printf("name? "); + fgets(ans, sizeof(ans), stdin); + ans[strlen(ans) - 1] = 0; + + name = malloc((strlen(ans) + 1) * sizeof(char)); + if (name == NULL) { + fprintf(stderr, "couldn't malloc string.\n"); + break; + } + strcpy(name, ans); + + + printf("state? "); + fgets(ans, sizeof(ans), stdin); + ans[strlen(ans) - 1] = 0; + + if (atoi(ans)) + state = 1; + else + state = 0; + + change_bool(name, state); + free(name); + break; #ifdef EQUIVTYPES case 'z': identify_equiv_types(); ==== //depot/projects/trustedbsd/sebsd/contrib/sebsd/checkpolicy/checkpolicy.h#3 (text+ko) ==== ==== //depot/projects/trustedbsd/sebsd/contrib/sebsd/checkpolicy/policy_parse.y#4 (text+ko) ==== @@ -3,6 +3,16 @@ * Author : Stephen Smalley, <sds@epoch.ncsc.mil> */ +/* Updated: David Caplan, <dac@tresys.com> + * + * Added conditional policy language extensions + * + * Copyright (C) 2003 - 2004 Tresys Technology, LLC + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2. + */ + /* FLASK */ %{ @@ -20,12 +30,22 @@ #include "flask.h" #include "security.h" +/* + * We need the following so we have a valid error return code in yacc + * when we have a parse error for a conditional rule. We can't check + * for NULL (ie 0) because that is a potentially valid return. + */ +static cond_av_list_t *conditional_unused_error_code; +#define COND_ERR (cond_av_list_t *)&conditional_unused_error_code + #define TRUE 1 #define FALSE 0 policydb_t *policydbp; queue_t id_queue = 0; unsigned int pass; +char *curfile = 0; +unsigned int curline; extern unsigned long policydb_lineno; @@ -48,6 +68,7 @@ static int define_common_base(void); static int define_av_base(void); static int define_attrib(void); +static int define_typealias(void); static int define_type(int alias); static int define_compute_type(int which); static int define_te_avtab(int which); @@ -57,24 +78,38 @@ static int define_role_trans(void); static int define_role_allow(void); static int define_constraint(constraint_expr_t *expr); -static constraint_expr_t *define_cexpr(__u32 expr_type, void *arg1, void* arg2); +static int define_bool(); +static int define_conditional(cond_expr_t *expr,cond_av_list_t *t_list, cond_av_list_t *f_list ); +static cond_expr_t *define_cond_expr(uint32_t expr_type, void *arg1, void* arg2); +static cond_av_list_t *define_cond_pol_list(cond_av_list_t *avlist, cond_av_list_t *stmt); +static cond_av_list_t *define_cond_compute_type(int which); +static cond_av_list_t *define_cond_te_avtab(int which); +static cond_av_list_t *cond_list_append(cond_av_list_t *sl, avtab_key_t *key, avtab_datum_t *datum); +static void cond_reduce_insert_list(cond_av_list_t *new, cond_av_list_t **active, cond_av_list_t **inactive, int state ); +static uintptr_t define_cexpr(uint32_t expr_type, uintptr_t arg1, uintptr_t arg2); static int define_user(void); static int parse_security_context(context_struct_t *c); static int define_initial_sid_context(void); static int define_fs_use(int behavior); static int define_genfs_context(int has_type); -static int define_fs_context(int major, int minor); -static int define_port_context(int low, int high); +static int define_fs_context(unsigned int major, unsigned int minor); +static int define_port_context(unsigned int low, unsigned int high); static int define_netif_context(void); -static int define_node_context(int addr, int mask); +static int define_ipv4_node_context(unsigned int addr, unsigned int mask); +static int define_ipv6_node_context(void); %} %union { - int val; + unsigned int val; + uintptr_t valptr; void *ptr; } -%type <ptr> role_def roles cexpr cexpr_prim op roleop +%type <ptr> cond_expr cond_expr_prim cond_pol_list +%type <ptr> cond_allow_def cond_auditallow_def cond_auditdeny_def cond_dontaudit_def +%type <ptr> cond_transition_def cond_te_avtab_def cond_rule_def +%type <ptr> role_def roles +%type <valptr> cexpr cexpr_prim op roleop %type <val> ipv4_addr_def number %token PATH @@ -86,10 +121,14 @@ %token SID %token ROLE %token ROLES +%token TYPEALIAS %token TYPE %token TYPES %token ALIAS %token ATTRIBUTE +%token BOOL +%token IF +%token ELSE %token TYPE_TRANSITION %token TYPE_MEMBER %token TYPE_CHANGE @@ -113,22 +152,26 @@ %token FSUSEXATTR FSUSETASK FSUSETRANS %token GENFSCON %token U1 U2 R1 R2 T1 T2 -%token NOT AND OR +%token NOT AND OR XOR +%token CTRUE CFALSE %token IDENTIFIER %token USER_IDENTIFIER %token NUMBER %token EQUALS %token NOTEQUAL +%token IPV6_ADDR %left OR +%left XOR %left AND %right NOT %left EQUALS NOTEQUAL %% -policy : classes initial_sids access_vectors +policy : classes initial_sids access_vectors { if (pass == 1) { if (policydb_index_classes(policydbp)) return -1; } } opt_mls te_rbac users opt_constraints - { if (pass == 2) { if (policydb_index_others(policydbp)) return -1;} } + { if (pass == 1) { if (policydb_index_bools(policydbp)) return -1;} + if (pass == 2) { if (policydb_index_others(policydbp, 1)) return -1;} } initial_sid_contexts opt_fs_contexts fs_uses opt_genfs_contexts net_contexts ; classes : class_def @@ -202,7 +245,7 @@ {if (define_level()) return -1;} | LEVEL identifier ';' {if (define_level()) return -1;} - ; + ; base_perms : opt_common_base av_base ; opt_common_base : common_base @@ -244,8 +287,11 @@ ; te_decl : attribute_def | type_def + | typealias_def + | bool_def | transition_def | te_avtab_def + | cond_stmt_def ; attribute_def : ATTRIBUTE identifier ';' { if (define_attrib()) return -1;} @@ -255,9 +301,105 @@ | TYPE identifier opt_attr_list ';' {if (define_type(0)) return -1;} ; +typealias_def : TYPEALIAS identifier alias_def ';' + {if (define_typealias()) return -1;} + ; opt_attr_list : ',' id_comma_list | ; +bool_def : BOOL identifier bool_val ';' + {if (define_bool()) return -1;} + ; +bool_val : CTRUE + { if (insert_id("T",0)) return -1; } + | CFALSE + { if (insert_id("F",0)) return -1; } + ; +cond_stmt_def : IF cond_expr '{' cond_pol_list '}' + { if (pass == 2) { if (define_conditional((cond_expr_t*)$2, (cond_av_list_t*)$4,(cond_av_list_t*) 0) < 0) return -1; }} + | IF cond_expr '{' cond_pol_list '}' ELSE '{' cond_pol_list '}' + { if (pass == 2) { if (define_conditional((cond_expr_t*)$2,(cond_av_list_t*)$4,(cond_av_list_t*)$8) < 0 ) return -1; }} + | IF cond_expr '{' cond_pol_list '}' ELSE '{' '}' + { if (pass == 2) { if (define_conditional((cond_expr_t*)$2,(cond_av_list_t*)$4,(cond_av_list_t*) 0) < 0 ) return -1; }} + | IF cond_expr '{' '}' ELSE '{' cond_pol_list '}' + { if (pass == 2) { if (define_conditional((cond_expr_t*)$2,(cond_av_list_t*) 0,(cond_av_list_t*) $7) < 0 ) return -1; }} + | IF cond_expr '{' '}' ELSE '{' '}' + /* do nothing */ + | IF cond_expr '{' '}' + /* do nothing */ + ; +cond_expr : '(' cond_expr ')' + { $$ = $2;} + | NOT cond_expr + { $$ = define_cond_expr(COND_NOT, $2, 0); + if ($$ == 0) return -1; } + | cond_expr AND cond_expr + { $$ = define_cond_expr(COND_AND, $1, $3); + if ($$ == 0) return -1; } + | cond_expr OR cond_expr + { $$ = define_cond_expr(COND_OR, $1, $3); + if ($$ == 0) return -1; } + | cond_expr XOR cond_expr + { $$ = define_cond_expr(COND_XOR, $1, $3); + if ($$ == 0) return -1; } + | cond_expr EQUALS cond_expr + { $$ = define_cond_expr(COND_EQ, $1, $3); + if ($$ == 0) return -1; } + | cond_expr NOTEQUAL cond_expr + { $$ = define_cond_expr(COND_NEQ, $1, $3); + if ($$ == 0) return -1; } + | cond_expr_prim + { $$ = $1; } + ; +cond_expr_prim : identifier + { $$ = define_cond_expr(COND_BOOL,0, 0); + if ($$ == COND_ERR) return -1; } + ; +cond_pol_list : cond_rule_def + { $$ = define_cond_pol_list((cond_av_list_t *) 0, (cond_av_list_t *)$1);} + | cond_pol_list cond_rule_def + { $$ = define_cond_pol_list((cond_av_list_t *)$1, (cond_av_list_t *)$2); } + ; +cond_rule_def : cond_transition_def + { $$ = $1; } + | cond_te_avtab_def + { $$ = $1; } + ; +cond_transition_def : TYPE_TRANSITION names names ':' names identifier ';' + { $$ = define_cond_compute_type(AVTAB_TRANSITION) ; + if ($$ == COND_ERR) return -1;} + | TYPE_MEMBER names names ':' names identifier ';' + { $$ = define_cond_compute_type(AVTAB_MEMBER) ; + if ($$ == COND_ERR) return -1;} + | TYPE_CHANGE names names ':' names identifier ';' + { $$ = define_cond_compute_type(AVTAB_CHANGE) ; + if ($$ == COND_ERR) return -1;} + ; +cond_te_avtab_def : cond_allow_def + { $$ = $1; } + | cond_auditallow_def + { $$ = $1; } + | cond_auditdeny_def + { $$ = $1; } + | cond_dontaudit_def + { $$ = $1; } + ; +cond_allow_def : ALLOW names names ':' names names ';' + { $$ = define_cond_te_avtab(AVTAB_ALLOWED) ; + if ($$ == COND_ERR) return -1; } + ; +cond_auditallow_def : AUDITALLOW names names ':' names names ';' + { $$ = define_cond_te_avtab(AVTAB_AUDITALLOW) ; + if ($$ == COND_ERR) return -1; } + ; +cond_auditdeny_def : AUDITDENY names names ':' names names ';' + { $$ = define_cond_te_avtab(AVTAB_AUDITDENY) ; + if ($$ == COND_ERR) return -1; } + ; +cond_dontaudit_def : DONTAUDIT names names ':' names names ';' + { $$ = define_cond_te_avtab(-AVTAB_AUDITDENY); + if ($$ == COND_ERR) return -1; } + ; transition_def : TYPE_TRANSITION names names ':' names identifier ';' {if (define_compute_type(AVTAB_TRANSITION)) return -1;} | TYPE_MEMBER names names ':' names identifier ';' @@ -331,64 +473,64 @@ { $$ = $1; } ; cexpr_prim : U1 op U2 - { $$ = define_cexpr(CEXPR_ATTR, (void*)CEXPR_USER, $2); + { $$ = define_cexpr(CEXPR_ATTR, CEXPR_USER, $2); if ($$ == 0) return -1; } | R1 roleop R2 - { $$ = define_cexpr(CEXPR_ATTR, (void*)CEXPR_ROLE, $2); + { $$ = define_cexpr(CEXPR_ATTR, CEXPR_ROLE, $2); if ($$ == 0) return -1; } | T1 op T2 - { $$ = define_cexpr(CEXPR_ATTR, (void*)CEXPR_TYPE, $2); + { $$ = define_cexpr(CEXPR_ATTR, CEXPR_TYPE, $2); if ($$ == 0) return -1; } | U1 op { if (insert_separator(1)) return -1; } user_names_push - { $$ = define_cexpr(CEXPR_NAMES, (void*)CEXPR_USER, $2); + { $$ = define_cexpr(CEXPR_NAMES, CEXPR_USER, $2); if ($$ == 0) return -1; } | U2 op { if (insert_separator(1)) return -1; } user_names_push - { $$ = define_cexpr(CEXPR_NAMES, (void*)(CEXPR_USER | CEXPR_TARGET), $2); + { $$ = define_cexpr(CEXPR_NAMES, (CEXPR_USER | CEXPR_TARGET), $2); if ($$ == 0) return -1; } | R1 op { if (insert_separator(1)) return -1; } names_push - { $$ = define_cexpr(CEXPR_NAMES, (void*)CEXPR_ROLE, $2); + { $$ = define_cexpr(CEXPR_NAMES, CEXPR_ROLE, $2); if ($$ == 0) return -1; } | R2 op { if (insert_separator(1)) return -1; } names_push - { $$ = define_cexpr(CEXPR_NAMES, (void*)(CEXPR_ROLE | CEXPR_TARGET), $2); + { $$ = define_cexpr(CEXPR_NAMES, (CEXPR_ROLE | CEXPR_TARGET), $2); if ($$ == 0) return -1; } | T1 op { if (insert_separator(1)) return -1; } names_push - { $$ = define_cexpr(CEXPR_NAMES, (void*)CEXPR_TYPE, $2); + { $$ = define_cexpr(CEXPR_NAMES, CEXPR_TYPE, $2); if ($$ == 0) return -1; } | T2 op { if (insert_separator(1)) return -1; } names_push - { $$ = define_cexpr(CEXPR_NAMES, (void*)(CEXPR_TYPE | CEXPR_TARGET), $2); + { $$ = define_cexpr(CEXPR_NAMES, (CEXPR_TYPE | CEXPR_TARGET), $2); if ($$ == 0) return -1; } | SAMEUSER - { $$ = define_cexpr(CEXPR_ATTR, (void*)CEXPR_USER, (void*)CEXPR_EQ); + { $$ = define_cexpr(CEXPR_ATTR, CEXPR_USER, CEXPR_EQ); if ($$ == 0) return -1; } | SOURCE ROLE { if (insert_separator(1)) return -1; } names_push - { $$ = define_cexpr(CEXPR_NAMES, (void*)CEXPR_ROLE, (void*)CEXPR_EQ); + { $$ = define_cexpr(CEXPR_NAMES, CEXPR_ROLE, CEXPR_EQ); if ($$ == 0) return -1; } | TARGET ROLE { if (insert_separator(1)) return -1; } names_push - { $$ = define_cexpr(CEXPR_NAMES, (void*)(CEXPR_ROLE | CEXPR_TARGET), (void*)CEXPR_EQ); + { $$ = define_cexpr(CEXPR_NAMES, (CEXPR_ROLE | CEXPR_TARGET), CEXPR_EQ); if ($$ == 0) return -1; } | ROLE roleop - { $$ = define_cexpr(CEXPR_ATTR, (void*)CEXPR_ROLE, (void*)$2); + { $$ = define_cexpr(CEXPR_ATTR, CEXPR_ROLE, $2); if ($$ == 0) return -1; } | SOURCE TYPE { if (insert_separator(1)) return -1; } names_push - { $$ = define_cexpr(CEXPR_NAMES, (void*)CEXPR_TYPE, (void*)CEXPR_EQ); + { $$ = define_cexpr(CEXPR_NAMES, CEXPR_TYPE, CEXPR_EQ); if ($$ == 0) return -1; } | TARGET TYPE { if (insert_separator(1)) return -1; } names_push - { $$ = define_cexpr(CEXPR_NAMES, (void*)(CEXPR_TYPE | CEXPR_TARGET), (void*)CEXPR_EQ); + { $$ = define_cexpr(CEXPR_NAMES, (CEXPR_TYPE | CEXPR_TARGET), CEXPR_EQ); if ($$ == 0) return -1; } ; op : EQUALS - { $$ = (void*)CEXPR_EQ; } + { $$ = CEXPR_EQ; } | NOTEQUAL - { $$ = (void*)CEXPR_NEQ; } + { $$ = CEXPR_NEQ; } ; roleop : op { $$ = $1; } | DOM - { $$ = (void*)CEXPR_DOM; } + { $$ = CEXPR_DOM; } | DOMBY - { $$ = (void*)CEXPR_DOMBY; } + { $$ = CEXPR_DOMBY; } | INCOMP - { $$ = (void*)CEXPR_INCOMP; } + { $$ = CEXPR_INCOMP; } ; users : user_def | users user_def @@ -452,7 +594,9 @@ | node_contexts node_context_def ; node_context_def : NODECON ipv4_addr_def ipv4_addr_def security_context_def - {if (define_node_context($2,$3)) return -1;} + {if (define_ipv4_node_context($2,$3)) return -1;} + | NODECON ipv6_addr ipv6_addr security_context_def + {if (define_ipv6_node_context()) return -1;} ; fs_uses : fs_use_def | fs_uses fs_use_def @@ -524,6 +668,8 @@ | tilde nested_id_set { if (insert_id("~", 0)) return -1; if (insert_separator(0)) return -1; } + | identifier '-' { if (insert_id("-", 0)) return -1; } identifier + { if (insert_separator(0)) return -1; } ; tilde_push : tilde { if (insert_id("~", 1)) return -1; } @@ -550,7 +696,7 @@ ; nested_id_list : nested_id_element | nested_id_list nested_id_element ; -nested_id_element : identifier | nested_id_set +nested_id_element : identifier | '-' { if (insert_id("-", 0)) return -1; } identifier | nested_id_set ; identifier : IDENTIFIER { if (insert_id(yytext,0)) return -1; } @@ -578,7 +724,12 @@ number : NUMBER { $$ = strtoul(yytext,NULL,0); } ; +ipv6_addr : IPV6_ADDR + { if (insert_id(yytext,0)) return -1; } + ; %% +#define DEBUG 1 + static int insert_separator(int push) { int error; @@ -1410,16 +1561,12 @@ while ((base = queue_remove(id_queue))) { if (!strcmp(base, "read")) { perdatum->base_perms |= MLS_BASE_READ; - cladatum->mlsperms.read |= (1 << (perdatum->value - 1)); } else if (!strcmp(base, "write")) { perdatum->base_perms |= MLS_BASE_WRITE; - cladatum->mlsperms.write |= (1 << (perdatum->value - 1)); } else if (!strcmp(base, "readby")) { perdatum->base_perms |= MLS_BASE_READBY; - cladatum->mlsperms.readby |= (1 << (perdatum->value - 1)); } else if (!strcmp(base, "writeby")) { perdatum->base_perms |= MLS_BASE_WRITEBY; - cladatum->mlsperms.writeby |= (1 << (perdatum->value - 1)); } else if (strcmp(base, "none")) { sprintf(errormsg, "base permission %s is not defined", base); yyerror(errormsg); @@ -1432,6 +1579,9 @@ free(id); } + /* Set MLS base permission masks */ + hashtab_map(cladatum->permissions.table, common_base_set, cladatum); + return 0; #else yyerror("MLS base permission definition in non-MLS configuration"); @@ -1481,7 +1631,62 @@ return 0; } +static int define_typealias(void) +{ + char *id; + type_datum_t *t, *aliasdatum;; + int ret; + + + if (pass == 2) { + while ((id = queue_remove(id_queue))) + free(id); + return 0; + } + + id = (char *) queue_remove(id_queue); + if (!id) { + yyerror("no type name for typealias definition?"); + return -1; + } + t = hashtab_search(policydbp->p_types.table, id); + if (!t || t->isattr) { + sprintf(errormsg, "unknown type %s", id); + yyerror(errormsg); + free(id); + return -1; + } + + while ((id = queue_remove(id_queue))) { + aliasdatum = (type_datum_t *) malloc(sizeof(type_datum_t)); + if (!aliasdatum) { + yyerror("out of memory"); + return -1; + } + memset(aliasdatum, 0, sizeof(type_datum_t)); + aliasdatum->value = t->value; + + ret = hashtab_insert(policydbp->p_types.table, + (hashtab_key_t) id, (hashtab_datum_t) aliasdatum); + + if (ret == HASHTAB_PRESENT) { + sprintf(errormsg, "name conflict for type alias %s", id); + yyerror(errormsg); + free(aliasdatum); + free(id); + return -1; + } + if (ret == HASHTAB_OVERFLOW) { + yyerror("hash table overflow"); + free(aliasdatum); + free(id); + return -1; + } + } + return 0; +} + static int define_type(int alias) { char *id; @@ -1665,15 +1870,19 @@ static int set_types(ebitmap_t *set, - char *id) + ebitmap_t *negset, + char *id, + int *add) { type_datum_t *t; - int i; + unsigned int i; if (strcmp(id, "*") == 0) { - /* set all types */ - for (i = 0; i < policydbp->p_types.nprim; i++) - ebitmap_set_bit(set, i, TRUE); + /* set all types not in negset */ + for (i = 0; i < policydbp->p_types.nprim; i++) { + if (!ebitmap_get_bit(negset, i)) + ebitmap_set_bit(set, i, TRUE); + } free(id); return 0; } @@ -1690,6 +1899,12 @@ return 0; } + if (strcmp(id, "-") == 0) { + *add = 0; + free(id); + return 0; + } + t = hashtab_search(policydbp->p_types.table, id); if (!t) { sprintf(errormsg, "unknown type %s", id); @@ -1699,18 +1914,42 @@ } if (t->isattr) { - /* set all types with this attribute */ + /* set or clear all types with this attribute, + but do not set anything explicitly cleared previously */ for (i = ebitmap_startbit(&t->types); i < ebitmap_length(&t->types); i++) { if (!ebitmap_get_bit(&t->types, i)) continue; - ebitmap_set_bit(set, i, TRUE); + if (!(*add)) { + ebitmap_set_bit(set, i, FALSE); + ebitmap_set_bit(negset, i, TRUE); + } else if (!ebitmap_get_bit(negset, i)) { + ebitmap_set_bit(set, i, TRUE); +#if VERBOSE + } else { + char *name = type_val_to_name(i+1); + sprintf(errormsg, "ignoring %s due to prior -%s", name, name); + yywarn(errormsg); +#endif + } } } else { - /* set one type */ - ebitmap_set_bit(set, t->value - 1, TRUE); + /* set or clear one type, but do not set anything + explicitly cleared previously */ + if (!(*add)) { + ebitmap_set_bit(set, t->value - 1, FALSE); >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200411241558.iAOFwaaJ041789>