From owner-p4-projects Mon Jun 24 8:29:25 2002 Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id EF56937B401; Mon, 24 Jun 2002 08:28:09 -0700 (PDT) Delivered-To: perforce@freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id D245437B400 for ; Mon, 24 Jun 2002 08:28:07 -0700 (PDT) Received: (from perforce@localhost) by freefall.freebsd.org (8.11.6/8.11.6) id g5OFS7N50572 for perforce@freebsd.org; Mon, 24 Jun 2002 08:28:07 -0700 (PDT) (envelope-from cvance@tislabs.com) Date: Mon, 24 Jun 2002 08:28:07 -0700 (PDT) Message-Id: <200206241528.g5OFS7N50572@freefall.freebsd.org> X-Authentication-Warning: freefall.freebsd.org: perforce set sender to cvance@tislabs.com using -f From: Chris Vance Subject: PERFORCE change 13373 for review To: Perforce Change Reviews Sender: owner-p4-projects@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG http://people.freebsd.org/~peter/p4db/chv.cgi?CH=13373 Change 13373 by cvance@cvance_korben on 2002/06/24 08:27:35 Major update: - Update support for binary policy file versioning - Sync with SELinux to gain generic non-persistent fs support - Update policy parser/compiler - Revise build process for initial kernel sids, contexts, etc. - Sync with SELinux for dontaudit rules in policy parser/compiler - Sync with SELinux MLS support Still Missing: - True support for process/file labels - Updated policy Still Broken: - kernel avc_*_audit() call (auditing code was non-portable) Take Note: - policy format has changed, need new policy file to boot, put new policy in /etc/security/sebsd/policy.11 Affected files ... ... //depot/projects/trustedbsd/mac/contrib/sebsd/checkpolicy/checkpolicy.c#3 edit ... //depot/projects/trustedbsd/mac/contrib/sebsd/checkpolicy/policy_parse.y#3 edit ... //depot/projects/trustedbsd/mac/contrib/sebsd/checkpolicy/policy_scan.l#3 edit ... //depot/projects/trustedbsd/mac/sbin/sebsd_checkpolicy/Makefile#4 edit ... //depot/projects/trustedbsd/mac/sys/security/sebsd/avc/av_inherit.h#2 edit ... //depot/projects/trustedbsd/mac/sys/security/sebsd/avc/av_perm_to_string.h#2 edit ... //depot/projects/trustedbsd/mac/sys/security/sebsd/avc/av_permissions.h#2 edit ... //depot/projects/trustedbsd/mac/sys/security/sebsd/avc/avc.c#2 edit ... //depot/projects/trustedbsd/mac/sys/security/sebsd/avc/avc.h#5 edit ... //depot/projects/trustedbsd/mac/sys/security/sebsd/avc/avc_ss.h#2 edit ... //depot/projects/trustedbsd/mac/sys/security/sebsd/avc/class_to_string.h#2 edit ... //depot/projects/trustedbsd/mac/sys/security/sebsd/avc/common_perm_to_string.h#2 edit ... //depot/projects/trustedbsd/mac/sys/security/sebsd/avc/flask.h#1 add ... //depot/projects/trustedbsd/mac/sys/security/sebsd/avc/initial_sid_to_string.h#1 add ... //depot/projects/trustedbsd/mac/sys/security/sebsd/flask.h#2 delete ... //depot/projects/trustedbsd/mac/sys/security/sebsd/flask/Makefile#1 add ... //depot/projects/trustedbsd/mac/sys/security/sebsd/flask/README#1 add ... //depot/projects/trustedbsd/mac/sys/security/sebsd/flask/access_vectors#1 add ... //depot/projects/trustedbsd/mac/sys/security/sebsd/flask/initial_sids#1 add ... //depot/projects/trustedbsd/mac/sys/security/sebsd/flask/mkaccess_vector.sh#1 add ... //depot/projects/trustedbsd/mac/sys/security/sebsd/flask/mkflask.sh#1 add ... //depot/projects/trustedbsd/mac/sys/security/sebsd/flask/security_classes#1 add ... //depot/projects/trustedbsd/mac/sys/security/sebsd/sebsd.c#9 edit ... //depot/projects/trustedbsd/mac/sys/security/sebsd/sebsd.h#4 edit ... //depot/projects/trustedbsd/mac/sys/security/sebsd/sebsd_labels.h#1 add ... //depot/projects/trustedbsd/mac/sys/security/sebsd/ss/global.h#3 edit ... //depot/projects/trustedbsd/mac/sys/security/sebsd/ss/init.c#5 edit ... //depot/projects/trustedbsd/mac/sys/security/sebsd/ss/initial_sid_to_string.h#2 delete ... //depot/projects/trustedbsd/mac/sys/security/sebsd/ss/mls.c#3 edit ... //depot/projects/trustedbsd/mac/sys/security/sebsd/ss/mls.h#2 edit ... //depot/projects/trustedbsd/mac/sys/security/sebsd/ss/policydb.c#4 edit ... //depot/projects/trustedbsd/mac/sys/security/sebsd/ss/policydb.h#2 edit ... //depot/projects/trustedbsd/mac/sys/security/sebsd/ss/security.h#3 edit ... //depot/projects/trustedbsd/mac/sys/security/sebsd/ss/services.c#5 edit ... //depot/projects/trustedbsd/mac/sys/security/sebsd/ss/services.h#2 edit ... //depot/projects/trustedbsd/mac/sys/security/sebsd/ss/services_private.h#3 edit ... //depot/projects/trustedbsd/mac/sys/security/sebsd/ss/sidtab.c#5 edit ... //depot/projects/trustedbsd/mac/sys/security/sebsd/ss/sidtab.h#2 edit ... //depot/projects/trustedbsd/mac/sys/security/sebsd/ss/symtab.c#3 edit Differences ... ==== //depot/projects/trustedbsd/mac/contrib/sebsd/checkpolicy/checkpolicy.c#3 (text+ko) ==== @@ -47,6 +47,7 @@ #include "services.h" #include "queue.h" #include "checkpolicy.h" +#include "security.h" extern char *optarg; extern int optind; @@ -54,7 +55,7 @@ extern policydb_t *policydbp; extern queue_t id_queue; extern unsigned int policydb_errors; -extern unsigned int policydb_lineno; +extern unsigned long policydb_lineno; extern unsigned int pass; extern FILE *yyin; @@ -311,14 +312,14 @@ security_context_t scontext; access_vector_t allowed, decided, auditallow, auditdeny; class_datum_t *cladatum; - char ans[80 + 1], *perm, *file = txtfile, *outfile = NULL, *path; + char ans[80 + 1], *perm, *file = txtfile, *outfile = NULL, *path, *fstype; unsigned int scontext_len, pathlen, seqno, i; unsigned int protocol, port, addr; unsigned int binary = 0, debug = 0; int ret, ch, nel; FILE *fp, *outfp = NULL; - while ((ch = getopt(argc, argv, "o:db")) != EOF) { + while ((ch = getopt(argc, argv, "o:dbV")) != EOF) { switch (ch) { case 'o': outfile = optarg; @@ -330,6 +331,13 @@ case 'd': 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); default: usage(argv[0]); } @@ -396,8 +404,8 @@ printf("%s: policy configuration loaded\n", argv[0]); if (outfile) { - printf("%s: writing binary representation to %s\n", - argv[0], outfile); + printf("%s: writing binary representation (version %d) to %s\n", + argv[0], POLICYDB_VERSION, outfile); outfp = fopen(outfile, "w"); if (!outfp) { perror(outfile); @@ -430,8 +438,8 @@ printf("9) Call port_sid\n"); printf("a) Call netif_sid\n"); printf("b) Call node_sid\n"); - printf("c) Call nfs_sid\n"); - printf("d) Call devfs_sid\n"); + printf("c) Call fs_use\n"); + printf("d) Call genfs_sid\n"); printf("e) Call get_user_sids\n"); #ifdef EQUIVTYPES printf("z) Show equivalent types\n"); @@ -670,15 +678,36 @@ printf("sid %d\n", ssid); break; case 'c': - printf("NFS server IP address? "); + printf("fstype? "); fgets(ans, sizeof(ans), stdin); ans[strlen(ans) - 1] = 0; - addr = inet_addr(ans); - security_nfs_sid(AF_INET, &addr, sizeof addr, &ssid, &tsid); - printf("fs_sid %d file_sid %d\n", ssid, tsid); + security_fs_use(ans, &ret, &ssid); + switch (ret) { + case SECURITY_FS_USE_PSID: + printf("use persistent label mapping\n"); + break; + case SECURITY_FS_USE_TRANS: + printf("use transition SIDs\n"); + break; + case SECURITY_FS_USE_TASK: + printf("use task SIDs\n"); + break; + case SECURITY_FS_USE_GENFS: + printf("use genfs\n"); + break; + case SECURITY_FS_USE_NONE: + printf("no labeling support\n"); + break; + } + if (ret != SECURITY_FS_USE_PSID) + printf("sid %d\n", ssid); break; case 'd': - printf("name? "); + printf("fstype? "); + fgets(ans, sizeof(ans), stdin); + ans[strlen(ans) - 1] = 0; + fstype = strdup(ans); + printf("path? "); fgets(ans, sizeof(ans), stdin); ans[strlen(ans) - 1] = 0; path = strdup(ans); @@ -700,8 +729,9 @@ } tclass = cladatum->value; } - security_devfs_sid(path, tclass, &ssid); + security_genfs_sid(fstype, path, tclass, &ssid); printf("sid %d\n", ssid); + free(fstype); free(path); break; case 'e': ==== //depot/projects/trustedbsd/mac/contrib/sebsd/checkpolicy/policy_parse.y#3 (text+ko) ==== @@ -22,12 +22,13 @@ #include "services.h" #include "queue.h" #include "checkpolicy.h" +#include "security.h" policydb_t *policydbp; queue_t id_queue = 0; unsigned int pass; -extern unsigned int policydb_lineno; +extern unsigned long policydb_lineno; extern char yytext[]; extern int yywarn(char *msg); @@ -47,9 +48,9 @@ static int define_level(void); static int define_common_base(void); static int define_av_base(void); +static int define_attrib(void); static int define_type(int alias); static int define_compute_type(int which); -static int define_te_clone(void); static int define_te_avtab(int which); static int define_role_types(void); static role_datum_t *merge_roles_dom(role_datum_t *r1,role_datum_t *r2); @@ -61,7 +62,8 @@ static int define_user(void); static int parse_security_context(context_struct_t *c); static int define_initial_sid_context(void); -static int define_devfs_context(int has_type); +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_netif_context(void); @@ -80,6 +82,7 @@ %token TYPE %token TYPES %token ALIAS +%token ATTRIBUTE %token TYPE_TRANSITION %token TYPE_MEMBER %token TYPE_CHANGE @@ -95,9 +98,13 @@ %token ALLOW %token AUDITALLOW %token AUDITDENY +%token DONTAUDIT %token SOURCE %token TARGET %token SAMEUSER +%token FSCON PORTCON NETIFCON NODECON +%token FSUSEPSID FSUSETASK FSUSETRANS +%token GENFSCON %token U1 U2 R1 R2 T1 T2 %token NOT AND OR %token IDENTIFIER @@ -112,9 +119,9 @@ %% policy : classes initial_sids access_vectors { if (pass == 1) { if (policydb_index_classes(policydbp)) return -1; } } - opt_mls te_rbac users constraints + opt_mls te_rbac users opt_constraints { if (pass == 2) { if (policydb_index_others(policydbp)) return -1;} } - initial_sid_contexts fs_contexts devfs_contexts net_contexts + initial_sid_contexts opt_fs_contexts fs_uses opt_genfs_contexts net_contexts ; classes : class_def | classes class_def @@ -128,8 +135,11 @@ initial_sid_def : SID identifier {if (define_initial_sid()) return -1;} ; -access_vectors : common_perms av_perms +access_vectors : opt_common_perms av_perms ; +opt_common_perms : common_perms + | + ; common_perms : common_perms_def | common_perms common_perms_def ; @@ -149,7 +159,7 @@ opt_mls : mls | ; -mls : sensitivities dominance categories levels base_perms +mls : sensitivities dominance opt_categories levels base_perms ; sensitivities : sensitivity_def | sensitivities sensitivity_def @@ -166,6 +176,9 @@ | DOMINANCE '{' identifier_list '}' {if (define_dominance()) return -1;} ; +opt_categories : categories + | + ; categories : category_def | categories category_def ; @@ -182,8 +195,11 @@ | LEVEL identifier ';' {if (define_level()) return -1;} ; -base_perms : common_base av_base +base_perms : opt_common_base av_base ; +opt_common_base : common_base + | + ; common_base : common_base_def | common_base common_base_def ; @@ -218,14 +234,14 @@ | role_trans_def | role_allow_def ; -te_decl : type_def +te_decl : attribute_def + | type_def | transition_def | te_avtab_def - | te_clone_def ; -te_clone_def : CLONE identifier identifier ';' - {if (define_te_clone()) return -1;} - ; +attribute_def : ATTRIBUTE identifier ';' + { if (define_attrib()) return -1;} + ; type_def : TYPE identifier alias_def opt_attr_list ';' {if (define_type(1)) return -1;} | TYPE identifier opt_attr_list ';' @@ -244,6 +260,7 @@ te_avtab_def : allow_def | auditallow_def | auditdeny_def + | dontaudit_def | neverallow_def ; allow_def : ALLOW names names ':' names names ';' @@ -255,6 +272,9 @@ auditdeny_def : AUDITDENY names names ':' names names ';' {if (define_te_avtab(AVTAB_AUDITDENY)) return -1; } ; +dontaudit_def : DONTAUDIT names names ':' names names ';' + {if (define_te_avtab(-AVTAB_AUDITDENY)) return -1; } + ; neverallow_def : NEVERALLOW names names ':' names names ';' {if (define_te_avtab(-AVTAB_ALLOWED)) return -1; } ; @@ -279,6 +299,9 @@ | ROLE identifier_push '{' roles '}' {$$ = (int) define_role_dom((role_datum_t*)$4); if ($$ == 0) return -1;} ; +opt_constraints : constraints + | + ; constraints : constraint_def | constraints constraint_def ; @@ -381,51 +404,69 @@ initial_sid_context_def : SID identifier security_context_def {if (define_initial_sid_context()) return -1;} ; +opt_fs_contexts : fs_contexts + | + ; fs_contexts : fs_context_def | fs_contexts fs_context_def ; -fs_context_def : number number security_context_def security_context_def - {if (define_fs_context($1,$2)) return -1;} +fs_context_def : FSCON number number security_context_def security_context_def + {if (define_fs_context($2,$3)) return -1;} ; -net_contexts : port_contexts netif_contexts node_contexts opt_nfs_contexts +net_contexts : opt_port_contexts opt_netif_contexts opt_node_contexts ; +opt_port_contexts : port_contexts + | + ; port_contexts : port_context_def | port_contexts port_context_def ; -port_context_def : identifier number security_context_def - {if (define_port_context($2,$2)) return -1;} - | identifier number '-' number security_context_def - {if (define_port_context($2,$4)) return -1;} +port_context_def : PORTCON identifier number security_context_def + {if (define_port_context($3,$3)) return -1;} + | PORTCON identifier number '-' number security_context_def + {if (define_port_context($3,$5)) return -1;} ; +opt_netif_contexts : netif_contexts + | + ; netif_contexts : netif_context_def | netif_contexts netif_context_def ; -netif_context_def : identifier security_context_def security_context_def - {if (define_netif_context()) return -1;} +netif_context_def : NETIFCON identifier security_context_def security_context_def + {if (define_netif_context()) return -1;} ; +opt_node_contexts : node_contexts + | + ; node_contexts : node_context_def | node_contexts node_context_def ; -node_context_def : ipv4_addr_def ipv4_addr_def security_context_def - {if (define_node_context($1,$2)) return -1;} +node_context_def : NODECON ipv4_addr_def ipv4_addr_def security_context_def + {if (define_node_context($2,$3)) return -1;} ; -opt_nfs_contexts : nfs_contexts - | +fs_uses : fs_use_def + | fs_uses fs_use_def + ; +fs_use_def : FSUSEPSID identifier ';' + {if (define_fs_use(SECURITY_FS_USE_PSID)) return -1;} + | FSUSETASK identifier security_context_def ';' + {if (define_fs_use(SECURITY_FS_USE_TASK)) return -1;} + | FSUSETRANS identifier security_context_def ';' + {if (define_fs_use(SECURITY_FS_USE_TRANS)) return -1;} + ; +opt_genfs_contexts : genfs_contexts + | ; -nfs_contexts : nfs_context_def - | nfs_contexts nfs_context_def +genfs_contexts : genfs_context_def + | genfs_contexts genfs_context_def ; -nfs_context_def : ipv4_addr_def ipv4_addr_def security_context_def security_context_def - {if (define_nfs_context($1,$2)) return -1;} +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 + {if (define_genfs_context(1)) return -1;} + | GENFSCON identifier path security_context_def + {if (define_genfs_context(0)) return -1;} ; -devfs_contexts : devfs_context_def - | devfs_contexts devfs_context_def - ; -devfs_context_def : path '-' identifier security_context_def - {if (define_devfs_context(1)) return -1;} - | path security_context_def - {if (define_devfs_context(0)) return -1;} - ; ipv4_addr_def : number '.' number '.' number '.' number { unsigned int addr; @@ -1371,12 +1412,54 @@ #endif } +static int define_attrib(void) +{ + char *id; + type_datum_t *attr; + int ret; + + + if (pass == 2) { + free(queue_remove(id_queue)); + return 0; + } + id = (char *) queue_remove(id_queue); + if (!id) { + return -1; + } + + attr = hashtab_search(policydbp->p_types.table, id); + if (attr) { + sprintf(errormsg, "duplicate declaration for attribute %s\n", + id); + yyerror(errormsg); + return -1; + } + + attr = (type_datum_t *) malloc(sizeof(type_datum_t)); + if (!attr) { + yyerror("out of memory"); + return -1; + } + memset(attr, 0, sizeof(type_datum_t)); + attr->isattr = TRUE; + ret = hashtab_insert(policydbp->p_types.table, + id, (hashtab_datum_t) attr); + if (ret) { + yyerror("hash table overflow"); + return -1; + } + + return 0; +} + + static int define_type(int alias) { char *id; type_datum_t *datum, *aliasdatum, *attr; - int ret; + int ret, newattr = 0; if (pass == 2) { @@ -1453,8 +1536,39 @@ } while ((id = queue_remove(id_queue))) { +#ifdef CONFIG_SECURITY_SELINUX_MLS + if (!strcmp(id, "mlstrustedreader")) { + if (!ebitmap_set_bit(&policydbp->trustedreaders, datum->value - 1, TRUE)) { + yyerror("out of memory"); + free(id); + return -1; + } + } else if (!strcmp(id, "mlstrustedwriter")) { + if (!ebitmap_set_bit(&policydbp->trustedwriters, datum->value - 1, TRUE)) { + yyerror("out of memory"); + free(id); + return -1; + } + } else if (!strcmp(id, "mlstrustedobject")) { + if (!ebitmap_set_bit(&policydbp->trustedobjects, datum->value - 1, TRUE)) { + yyerror("out of memory"); + free(id); + return -1; + } + } +#endif attr = hashtab_search(policydbp->p_types.table, id); if (!attr) { + sprintf(errormsg, "attribute %s is not declared", id); +#if 1 + /* treat it as a fatal error */ + yyerror(errormsg); + return -1; +#else + /* Warn but automatically define the attribute. + Useful for quickly finding all those attributes you + forgot to declare. */ + yywarn(errormsg); attr = (type_datum_t *) malloc(sizeof(type_datum_t)); if (!attr) { yyerror("out of memory"); @@ -1468,14 +1582,21 @@ yyerror("hash table overflow"); return -1; } + newattr = 1; +#endif } else { - free(id); + newattr = 0; } + if (!attr->isattr) { - sprintf(errormsg, "name conflict for type attribute %s", id); + sprintf(errormsg, "%s is a type, not an attribute", id); yyerror(errormsg); return -1; } + + if (!newattr) + free(id); + ebitmap_set_bit(&attr->types, datum->value - 1, TRUE); } @@ -1738,12 +1859,16 @@ static int te_avtab_helper(int which, int stype, int ttype, - ebitmap_t *tclasses, access_vector_t *avp) + ebitmap_t *tclasses, access_vector_t *avp) { avtab_key_t avkey; avtab_datum_t avdatum, *avdatump; int ret, k; + if (which == -AVTAB_ALLOWED) { + yyerror("neverallow should not reach this function."); + return -1; + } for (k = ebitmap_startbit(tclasses); k < ebitmap_length(tclasses); k++) { if (!ebitmap_get_bit(tclasses, k)) @@ -1753,11 +1878,8 @@ avkey.target_class = k + 1; avdatump = avtab_search(&policydbp->te_avtab, &avkey, AVTAB_AV); if (!avdatump) { - if (which == -AVTAB_ALLOWED) { - continue; - } memset(&avdatum, 0, sizeof avdatum); - avdatum.specified = which; + avdatum.specified = (which > 0) ? which : -which; ret = avtab_insert(&policydbp->te_avtab, &avkey, &avdatum); if (ret) { yyerror("hash table overflow"); @@ -1770,18 +1892,7 @@ } } - if (which == -AVTAB_ALLOWED) { - if ((avdatump->specified & AVTAB_ALLOWED) && - (avtab_allowed(avdatump) & avp[k])) { - sprintf(errormsg, "assertion failed: allow %s %s:%s {%s } was granted.", type_val_to_name(stype+1), type_val_to_name(ttype+1), policydbp->p_class_val_to_name[k], - av_to_string(k+1, - avtab_allowed(avdatump) & avp[k])); - yyerror(errormsg); - } - continue; - } - - avdatump->specified |= which; + avdatump->specified |= ((which > 0) ? which : -which); switch (which) { case AVTAB_ALLOWED: @@ -1793,6 +1904,12 @@ case AVTAB_AUDITDENY: avtab_auditdeny(avdatump) |= avp[k]; break; + case -AVTAB_AUDITDENY: + if (avtab_auditdeny(avdatump)) + avtab_auditdeny(avdatump) &= ~avp[k]; + else + avtab_auditdeny(avdatump) = ~avp[k]; + break; } } @@ -1876,6 +1993,8 @@ if (strcmp(id, "~") == 0) { /* complement the set */ + if (which == -AVTAB_AUDITDENY) + yywarn("dontaudit rule with a ~?"); avp[i] = ~avp[i]; continue; } @@ -1943,167 +2062,6 @@ return -1; } - -typedef struct te_clone_args { - type_datum_t *src; - type_datum_t *tgt; -} te_clone_args_t; - -static int te_clone_transition( - avtab_key_t *k, - avtab_datum_t *d, - avtab_datum_t *newd, - te_clone_args_t *myargs) -{ - if (k->target_class == SECCLASS_PROCESS && - (avtab_transition(d) == myargs->src->value || - avtab_transition(d) == myargs->tgt->value)) { - /* - * Do not clone a process transition if - * if the new domain is equal to the - * source domain or to the target - * domain in the clone statement. - */ - return 0; - } - - if ((newd->specified & AVTAB_TRANSITION) && - avtab_transition(newd) != avtab_transition(d)) { - sprintf(errormsg, "conflicting type transition rule for (%s, %s:%s): default was %s, now is %s", type_val_to_name(myargs->tgt->value), type_val_to_name(k->target_type), policydbp->p_class_val_to_name[k->target_class-1], - type_val_to_name(avtab_transition(newd)), - type_val_to_name(avtab_transition(d))); - yywarn(errormsg); - } - - newd->specified |= AVTAB_TRANSITION; - avtab_transition(newd) = avtab_transition(d); - return 0; -} - - -static int te_clone_av( - avtab_key_t *k, - avtab_datum_t *d, - avtab_datum_t *newd, - te_clone_args_t *myargs) -{ - if (k->target_type == myargs->src->value || - k->target_type == myargs->tgt->value) { - /* - * Do not clone an access vector if - * the target domain is equal to the - * source domain or to the target domain - * in the clone statement. - */ - return 0; - } - - newd->specified |= d->specified; - if (d->specified & AVTAB_ALLOWED) - avtab_allowed(newd) |= avtab_allowed(d); - if (d->specified & AVTAB_AUDITALLOW) - avtab_auditallow(newd) |= avtab_auditallow(d); - if (d->specified & AVTAB_AUDITDENY) - avtab_auditdeny(newd) |= avtab_auditdeny(d); - return 0; -} - - -static int te_clone(avtab_key_t *k, avtab_datum_t *d, void *args) -{ - avtab_key_t newk; - avtab_datum_t newd, *newd_ptr; - te_clone_args_t *myargs = args; - int ret; - - if (k->source_type != myargs->src->value) - /* only clone entries for the source domain */ - return 0; - - newk.source_type = myargs->tgt->value; - newk.target_type = k->target_type; - newk.target_class = k->target_class; - memset(&newd, 0, sizeof newd); - - if (d->specified & AVTAB_AV) { - newd_ptr = avtab_search(&policydbp->te_avtab, &newk, AVTAB_AV); - if (!newd_ptr) - newd_ptr = &newd; - te_clone_av(k, d, newd_ptr, myargs); - } else if (d->specified & AVTAB_TRANSITION) { - newd_ptr = avtab_search(&policydbp->te_avtab, &newk, AVTAB_TYPE); - if (!newd_ptr) - newd_ptr = &newd; - te_clone_transition(k, d, newd_ptr, myargs); - } - - if (newd.specified == 0) - return 0; - - ret = avtab_insert(&policydbp->te_avtab, - &newk, &newd); - if (ret) { - yyerror("out of memory"); - return -1; - } - - return 0; -} - -static int define_te_clone(void) -{ - char *src_id, *tgt_id; - type_datum_t *src, *tgt; - te_clone_args_t args; - - if (pass == 1) { - src_id = queue_remove(id_queue); - free(src_id); - tgt_id = queue_remove(id_queue); - free(tgt_id); - return 0; - } - - src_id = queue_remove(id_queue); - if (!src_id) { - yyerror("No source domain?"); - return -1; - } - src = hashtab_search(policydbp->p_types.table, src_id); - if (!src || src->isattr) { - sprintf(errormsg, "unknown type %s used in rule", src_id); - yyerror(errormsg); - free(src_id); - return -1; - } - - tgt_id = queue_remove(id_queue); - if (!tgt_id) { - yyerror("No target domain?"); - free(src_id); - return -1; - } - tgt = hashtab_search(policydbp->p_types.table, tgt_id); - if (!tgt || tgt->isattr) { - sprintf(errormsg, "unknown type %s used in rule", tgt_id); - yyerror(errormsg); - free(src_id); - free(tgt_id); - return -1; - } - - sprintf(errormsg, "clone %s %s - Cloning rules are DEPRECATED, use macros.", src_id, tgt_id); - yywarn(errormsg); - free(src_id); - free(tgt_id); - - args.src = src; - args.tgt = tgt; - return avtab_map(&policydbp->te_avtab, - te_clone, (void *)&args); -} - - static int role_val_to_name_helper(hashtab_key_t key, hashtab_datum_t datum, void *p) { unsigned int value; @@ -3254,56 +3212,64 @@ return 0; } - -static int define_nfs_context(int addr, int mask) +static int define_fs_use(int behavior) { - ocontext_t *newc, *c, *l, *head; + ocontext_t *newc, *c, *head; if (pass == 1) { - parse_security_context(NULL); + free(queue_remove(id_queue)); + if (behavior != SECURITY_FS_USE_PSID) + parse_security_context(NULL); return 0; } - newc = malloc(sizeof(ocontext_t)); + newc = (ocontext_t *) malloc(sizeof(ocontext_t)); if (!newc) { yyerror("out of memory"); return -1; } memset(newc, 0, sizeof(ocontext_t)); - newc->u.node.addr = addr; - newc->u.node.mask = mask; - - if (parse_security_context(&newc->context[0])) { + newc->u.name = (char *) queue_remove(id_queue); + if (!newc->u.name) { free(newc); return -1; } - if (parse_security_context(&newc->context[1])) { - context_destroy(&newc->context[0]); - free(newc->u.name); - free(newc); - return -1; + newc->v.behavior = behavior; + if (behavior != SECURITY_FS_USE_PSID) { + if (parse_security_context(&newc->context[0])) { + free(newc->u.name); + free(newc); + return -1; + } } + head = policydbp->ocontexts[OCON_FSUSE]; - /* Place this at the end of the list, to retain - the matching order specified in the configuration. */ - head = policydbp->ocontexts[OCON_NFS]; - for (l = NULL, c = head; c; l = c, c = c->next); + for (c = head; c; c = c->next) { + if (!strcmp(newc->u.name, c->u.name)) { + sprintf(errormsg, "duplicate fs_use entry for filesystem type %s", newc->u.name); + yyerror(errormsg); + context_destroy(&newc->context[0]); + free(newc->u.name); + free(newc); + return -1; + } + } - if (l) - l->next = newc; - else - policydbp->ocontexts[OCON_NFS] = newc; - + newc->next = head; + policydbp->ocontexts[OCON_FSUSE] = newc; return 0; } -static int define_devfs_context(int has_type) +static int define_genfs_context_helper(char *fstype, int has_type) { - ocontext_t *newc, *c, *head; - char *type; + struct genfs *genfs_p, *genfs, *newgenfs; + ocontext_t *newc, *c, *head, *p; + char *type = NULL; + int len, len2; if (pass == 1) { + free(fstype); free(queue_remove(id_queue)); if (has_type) free(queue_remove(id_queue)); @@ -3311,6 +3277,28 @@ return 0; } + for (genfs_p = NULL, genfs = policydbp->genfs; + genfs; genfs_p = genfs, genfs = genfs->next) { + if (strcmp(fstype, genfs->fstype) <= 0) + break; + } + + if (!genfs || strcmp(fstype, genfs->fstype)) { + newgenfs = malloc(sizeof(struct genfs)); + if (!newgenfs) { + yyerror("out of memory"); + return -1; + } + memset(newgenfs, 0, sizeof(struct genfs)); + newgenfs->fstype = fstype; + newgenfs->next = genfs; + if (genfs_p) + genfs_p->next = newgenfs; + else + policydbp->genfs = newgenfs; + genfs = newgenfs; + } + newc = (ocontext_t *) malloc(sizeof(ocontext_t)); if (!newc) { yyerror("out of memory"); @@ -3319,10 +3307,8 @@ memset(newc, 0, sizeof(ocontext_t)); newc->u.name = (char *) queue_remove(id_queue); - if (!newc->u.name) { - free(newc); - return -1; - } + if (!newc->u.name) + goto fail; if (has_type) { type = (char *) queue_remove(id_queue); if (!type) @@ -3334,25 +3320,25 @@ } switch (type[0]) { case 'b': - newc->sclass = SECCLASS_BLK_FILE; + newc->v.sclass = SECCLASS_BLK_FILE; break; case 'c': - newc->sclass = SECCLASS_CHR_FILE; + newc->v.sclass = SECCLASS_CHR_FILE; break; case 'd': - newc->sclass = SECCLASS_DIR; + newc->v.sclass = SECCLASS_DIR; break; case 'p': - newc->sclass = SECCLASS_FIFO_FILE; + newc->v.sclass = SECCLASS_FIFO_FILE; break; case 'l': - newc->sclass = SECCLASS_LNK_FILE; + newc->v.sclass = SECCLASS_LNK_FILE; break; case 's': - newc->sclass = SECCLASS_SOCK_FILE; + newc->v.sclass = SECCLASS_SOCK_FILE; break; case '-': - newc->sclass = SECCLASS_FILE; + newc->v.sclass = SECCLASS_FILE; break; default: sprintf(errormsg, "invalid type %s", type); @@ -3360,36 +3346,47 @@ goto fail; } } - if (parse_security_context(&newc->context[0])) { - free(newc->u.name); - free(newc); - return -1; - } - head = policydbp->ocontexts[OCON_DEVFS]; + if (parse_security_context(&newc->context[0])) + goto fail; + + head = genfs->head; - for (c = head; c; c = c->next) { + for (p = NULL, c = head; c; p = c, c = c->next) { if (!strcmp(newc->u.name, c->u.name) && - newc->sclass == c->sclass) { - sprintf(errormsg, "duplicate entry for devfs entry %s", newc->u.name); + (!newc->v.sclass || !c->v.sclass || newc->v.sclass == c->v.sclass)) { + sprintf(errormsg, "duplicate entry for genfs entry (%s, %s)", fstype, newc->u.name); >>> TRUNCATED FOR MAIL (1000 lines) <<< To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe p4-projects" in the body of the message