00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <config.h>
00038
00039 #include <sys/types.h>
00040 #include <assert.h>
00041 #include <stdarg.h>
00042 #include <stdint.h>
00043 #include <stdio.h>
00044 #include <stdlib.h>
00045 #include <string.h>
00046 #include <sys/socket.h>
00047 #include <netinet/in.h>
00048 #include <arpa/inet.h>
00049 #include <stdlib.h>
00050
00051 #include <sepol/policydb/expand.h>
00052 #include <sepol/policydb/policydb.h>
00053 #include <sepol/policydb/services.h>
00054 #include <sepol/policydb/conditional.h>
00055 #include <sepol/policydb/flask.h>
00056 #include <sepol/policydb/hierarchy.h>
00057 #ifdef HAVE_SEPOL_POLICYCAPS
00058 #include <sepol/policydb/polcaps.h>
00059 #endif
00060
00061 #include "queue.h"
00062 #include <qpol/policy.h>
00063 #include "module_compiler.h"
00064 #include "policy_define.h"
00065
00066 policydb_t *policydbp;
00067 queue_t id_queue = 0;
00068 unsigned int pass;
00069 static int load_rules;
00070 static unsigned int num_rules = 0;
00071 char *curfile = 0;
00072 int mlspol = 0;
00073
00074 extern unsigned long policydb_lineno;
00075 extern unsigned long source_lineno;
00076 extern unsigned int policydb_errors;
00077
00078 extern int yywarn(char *msg);
00079 extern int yyerror(char *msg);
00080
00081 #define ERRORMSG_LEN 255
00082 static char errormsg[ERRORMSG_LEN + 1] = { 0 };
00083
00084 static int id_has_dot(char *id);
00085 static int parse_security_context(context_struct_t * c);
00086
00087
00088 void init_parser(int pass_number, int do_rules)
00089 {
00090 policydb_lineno = 1;
00091 source_lineno = 1;
00092 policydb_errors = 0;
00093 pass = pass_number;
00094 load_rules = do_rules;
00095 num_rules = 0;
00096 }
00097
00098 void yyerror2(char *fmt, ...)
00099 {
00100 va_list ap;
00101 va_start(ap, fmt);
00102 vsnprintf(errormsg, ERRORMSG_LEN, fmt, ap);
00103 yyerror(errormsg);
00104 va_end(ap);
00105 }
00106
00107 int define_mls(void)
00108 {
00109 mlspol = 1;
00110 policydbp->mls = 1;
00111
00112 return 0;
00113 }
00114
00115
00116
00117
00118
00119
00120
00121 static int insert_check_type_rule(avrule_t * rule, avtab_t * avtab, cond_av_list_t ** list, cond_av_list_t ** other)
00122 {
00123 int ret;
00124
00125 if (num_rules && !load_rules)
00126 return 2;
00127
00128 #ifdef SEPOL_DYNAMIC_AVTAB
00129 if (!avtab->htable)
00130 if (avtab_alloc(avtab, MAX_AVTAB_SIZE))
00131 return -1;
00132 #endif
00133
00134 ret = expand_rule(NULL, policydbp, rule, avtab, list, other, 0);
00135 if (ret < 0) {
00136 yyerror("Failed on expanding rule");
00137 }
00138 return ret;
00139 }
00140 int insert_separator(int push)
00141 {
00142 int error;
00143
00144 if (push)
00145 error = queue_push(id_queue, 0);
00146 else
00147 error = queue_insert(id_queue, 0);
00148
00149 if (error) {
00150 yyerror("queue overflow");
00151 return -1;
00152 }
00153 return 0;
00154 }
00155
00156 int insert_id(char *id, int push)
00157 {
00158 char *newid = 0;
00159 int error;
00160
00161 newid = (char *)malloc(strlen(id) + 1);
00162 if (!newid) {
00163 yyerror("out of memory");
00164 return -1;
00165 }
00166 strcpy(newid, id);
00167 if (push)
00168 error = queue_push(id_queue, (queue_element_t) newid);
00169 else
00170 error = queue_insert(id_queue, (queue_element_t) newid);
00171
00172 if (error) {
00173 yyerror("queue overflow");
00174 free(newid);
00175 return -1;
00176 }
00177 return 0;
00178 }
00179
00180
00181
00182 static int id_has_dot(char *id)
00183 {
00184 if (strchr(id, '.') >= id + 1) {
00185 return 1;
00186 }
00187 return 0;
00188 }
00189
00190 int define_class(void)
00191 {
00192 char *id = 0;
00193 class_datum_t *datum = 0;
00194 int ret;
00195 uint32_t value;
00196
00197 if (pass == 2) {
00198 id = queue_remove(id_queue);
00199 free(id);
00200 return 0;
00201 }
00202
00203 id = (char *)queue_remove(id_queue);
00204 if (!id) {
00205 yyerror("no class name for class definition?");
00206 return -1;
00207 }
00208 datum = (class_datum_t *) malloc(sizeof(class_datum_t));
00209 if (!datum) {
00210 yyerror("out of memory");
00211 goto bad;
00212 }
00213 memset(datum, 0, sizeof(class_datum_t));
00214 ret = declare_symbol(SYM_CLASSES, id, datum, &value, &value);
00215 switch (ret) {
00216 case -3:{
00217 yyerror("Out of memory!");
00218 goto bad;
00219 }
00220 case -2:{
00221 yyerror2("duplicate declaration of class %s", id);
00222 goto bad;
00223 }
00224 case -1:{
00225 yyerror("could not declare class here");
00226 goto bad;
00227 }
00228 case 0:
00229 case 1:{
00230 break;
00231 }
00232 default:{
00233 assert(0);
00234 }
00235 }
00236 datum->s.value = value;
00237 return 0;
00238
00239 bad:
00240 if (id)
00241 free(id);
00242 if (datum)
00243 free(datum);
00244 return -1;
00245 }
00246
00247 int define_polcap(void)
00248 {
00249 char *id = 0;
00250 int capnum;
00251
00252 if (pass == 2) {
00253 id = queue_remove(id_queue);
00254 free(id);
00255 return 0;
00256 }
00257
00258 id = (char *)queue_remove(id_queue);
00259 if (!id) {
00260 yyerror("no capability name for policycap definition?");
00261 goto bad;
00262 }
00263 #ifdef HAVE_SEPOL_POLICYCAPS
00264
00265 capnum = sepol_polcap_getnum(id);
00266 if (capnum < 0) {
00267 yyerror2("invalid policy capability name %s", id);
00268 goto bad;
00269 }
00270
00271
00272 if (ebitmap_set_bit(&policydbp->policycaps, capnum, TRUE)) {
00273 yyerror("out of memory");
00274 goto bad;
00275 }
00276 #else
00277 yyerror("This version of SETools does not have policycap enabled.");
00278 #endif
00279
00280 free(id);
00281 return 0;
00282
00283 bad:
00284 free(id);
00285 return -1;
00286 }
00287
00288 int define_initial_sid(void)
00289 {
00290 char *id = 0;
00291 ocontext_t *newc = 0, *c, *head;
00292
00293 if (pass == 2) {
00294 id = queue_remove(id_queue);
00295 free(id);
00296 return 0;
00297 }
00298
00299 id = (char *)queue_remove(id_queue);
00300 if (!id) {
00301 yyerror("no sid name for SID definition?");
00302 return -1;
00303 }
00304 newc = (ocontext_t *) malloc(sizeof(ocontext_t));
00305 if (!newc) {
00306 yyerror("out of memory");
00307 goto bad;
00308 }
00309 memset(newc, 0, sizeof(ocontext_t));
00310 newc->u.name = id;
00311 context_init(&newc->context[0]);
00312 head = policydbp->ocontexts[OCON_ISID];
00313
00314 for (c = head; c; c = c->next) {
00315 if (!strcmp(newc->u.name, c->u.name)) {
00316 yyerror2("duplicate initial SID %s", id);
00317 goto bad;
00318 }
00319 }
00320
00321 if (head) {
00322 newc->sid[0] = head->sid[0] + 1;
00323 } else {
00324 newc->sid[0] = 1;
00325 }
00326 newc->next = head;
00327 policydbp->ocontexts[OCON_ISID] = newc;
00328
00329 return 0;
00330
00331 bad:
00332 if (id)
00333 free(id);
00334 if (newc)
00335 free(newc);
00336 return -1;
00337 }
00338
00339 int define_common_perms(void)
00340 {
00341 char *id = 0, *perm = 0;
00342 common_datum_t *comdatum = 0;
00343 perm_datum_t *perdatum = 0;
00344 int ret;
00345
00346 if (pass == 2) {
00347 while ((id = queue_remove(id_queue)))
00348 free(id);
00349 return 0;
00350 }
00351
00352 id = (char *)queue_remove(id_queue);
00353 if (!id) {
00354 yyerror("no common name for common perm definition?");
00355 return -1;
00356 }
00357 comdatum = hashtab_search(policydbp->p_commons.table, id);
00358 if (comdatum) {
00359 yyerror2("duplicate declaration for common %s\n", id);
00360 return -1;
00361 }
00362 comdatum = (common_datum_t *) malloc(sizeof(common_datum_t));
00363 if (!comdatum) {
00364 yyerror("out of memory");
00365 goto bad;
00366 }
00367 memset(comdatum, 0, sizeof(common_datum_t));
00368 ret = hashtab_insert(policydbp->p_commons.table, (hashtab_key_t) id, (hashtab_datum_t) comdatum);
00369
00370 if (ret == SEPOL_EEXIST) {
00371 yyerror("duplicate common definition");
00372 goto bad;
00373 }
00374 if (ret == SEPOL_ENOMEM) {
00375 yyerror("hash table overflow");
00376 goto bad;
00377 }
00378 comdatum->s.value = policydbp->p_commons.nprim + 1;
00379 if (symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE)) {
00380 yyerror("out of memory");
00381 goto bad;
00382 }
00383 policydbp->p_commons.nprim++;
00384 while ((perm = queue_remove(id_queue))) {
00385 perdatum = (perm_datum_t *) malloc(sizeof(perm_datum_t));
00386 if (!perdatum) {
00387 yyerror("out of memory");
00388 goto bad_perm;
00389 }
00390 memset(perdatum, 0, sizeof(perm_datum_t));
00391 perdatum->s.value = comdatum->permissions.nprim + 1;
00392
00393 if (perdatum->s.value > (sizeof(sepol_access_vector_t) * 8)) {
00394 yyerror("too many permissions to fit in an access vector");
00395 goto bad_perm;
00396 }
00397 ret = hashtab_insert(comdatum->permissions.table, (hashtab_key_t) perm, (hashtab_datum_t) perdatum);
00398
00399 if (ret == SEPOL_EEXIST) {
00400 yyerror2("duplicate permission %s in common %s", perm, id);
00401 goto bad_perm;
00402 }
00403 if (ret == SEPOL_ENOMEM) {
00404 yyerror("hash table overflow");
00405 goto bad_perm;
00406 }
00407 comdatum->permissions.nprim++;
00408 }
00409
00410 return 0;
00411
00412 bad:
00413 if (id)
00414 free(id);
00415 if (comdatum)
00416 free(comdatum);
00417 return -1;
00418
00419 bad_perm:
00420 if (perm)
00421 free(perm);
00422 if (perdatum)
00423 free(perdatum);
00424 return -1;
00425 }
00426
00427 int define_av_perms(int inherits)
00428 {
00429 char *id;
00430 class_datum_t *cladatum;
00431 common_datum_t *comdatum;
00432 perm_datum_t *perdatum = 0, *perdatum2 = 0;
00433 int ret;
00434
00435 if (pass == 2) {
00436 while ((id = queue_remove(id_queue)))
00437 free(id);
00438 return 0;
00439 }
00440
00441 id = (char *)queue_remove(id_queue);
00442 if (!id) {
00443 yyerror("no tclass name for av perm definition?");
00444 return -1;
00445 }
00446 cladatum = (class_datum_t *) hashtab_search(policydbp->p_classes.table, (hashtab_key_t) id);
00447 if (!cladatum) {
00448 yyerror2("class %s is not defined", id);
00449 goto bad;
00450 }
00451 free(id);
00452
00453 if (cladatum->comdatum || cladatum->permissions.nprim) {
00454 yyerror("duplicate access vector definition");
00455 return -1;
00456 }
00457 if (symtab_init(&cladatum->permissions, PERM_SYMTAB_SIZE)) {
00458 yyerror("out of memory");
00459 return -1;
00460 }
00461 if (inherits) {
00462 id = (char *)queue_remove(id_queue);
00463 if (!id) {
00464 yyerror("no inherits name for access vector definition?");
00465 return -1;
00466 }
00467 comdatum = (common_datum_t *) hashtab_search(policydbp->p_commons.table, (hashtab_key_t) id);
00468
00469 if (!comdatum) {
00470 yyerror2("common %s is not defined", id);
00471 goto bad;
00472 }
00473 cladatum->comkey = id;
00474 cladatum->comdatum = comdatum;
00475
00476
00477
00478
00479
00480 cladatum->permissions.nprim += comdatum->permissions.nprim;
00481 }
00482 while ((id = queue_remove(id_queue))) {
00483 perdatum = (perm_datum_t *) malloc(sizeof(perm_datum_t));
00484 if (!perdatum) {
00485 yyerror("out of memory");
00486 goto bad;
00487 }
00488 memset(perdatum, 0, sizeof(perm_datum_t));
00489 perdatum->s.value = ++cladatum->permissions.nprim;
00490
00491 if (perdatum->s.value > (sizeof(sepol_access_vector_t) * 8)) {
00492 yyerror("too many permissions to fit in an access vector");
00493 goto bad;
00494 }
00495 if (inherits) {
00496
00497
00498
00499
00500
00501 perdatum2 = (perm_datum_t *) hashtab_search(cladatum->comdatum->permissions.table, (hashtab_key_t) id);
00502 if (perdatum2) {
00503 yyerror2("permission %s conflicts with an " "inherited permission", id);
00504 goto bad;
00505 }
00506 }
00507 ret = hashtab_insert(cladatum->permissions.table, (hashtab_key_t) id, (hashtab_datum_t) perdatum);
00508
00509 if (ret == SEPOL_EEXIST) {
00510 yyerror2("duplicate permission %s", id);
00511 goto bad;
00512 }
00513 if (ret == SEPOL_ENOMEM) {
00514 yyerror("hash table overflow");
00515 goto bad;
00516 }
00517 if (add_perm_to_class(perdatum->s.value, cladatum->s.value)) {
00518 yyerror("out of memory");
00519 goto bad;
00520 }
00521 }
00522
00523 return 0;
00524
00525 bad:
00526 if (id)
00527 free(id);
00528 if (perdatum)
00529 free(perdatum);
00530 return -1;
00531 }
00532
00533 int define_sens(void)
00534 {
00535 char *id;
00536 mls_level_t *level = 0;
00537 level_datum_t *datum = 0, *aliasdatum = 0;
00538 int ret;
00539 uint32_t value;
00540
00541 if (!mlspol) {
00542 yyerror("sensitivity definition in non-MLS configuration");
00543 return -1;
00544 }
00545
00546 if (pass == 2) {
00547 while ((id = queue_remove(id_queue)))
00548 free(id);
00549 return 0;
00550 }
00551
00552 id = (char *)queue_remove(id_queue);
00553 if (!id) {
00554 yyerror("no sensitivity name for sensitivity definition?");
00555 return -1;
00556 }
00557 if (id_has_dot(id)) {
00558 yyerror("sensitivity identifiers may not contain periods");
00559 goto bad;
00560 }
00561 level = (mls_level_t *) malloc(sizeof(mls_level_t));
00562 if (!level) {
00563 yyerror("out of memory");
00564 goto bad;
00565 }
00566 mls_level_init(level);
00567 level->sens = 0;
00568 ebitmap_init(&level->cat);
00569
00570 datum = (level_datum_t *) malloc(sizeof(level_datum_t));
00571 if (!datum) {
00572 yyerror("out of memory");
00573 goto bad;
00574 }
00575 level_datum_init(datum);
00576 datum->isalias = FALSE;
00577 datum->level = level;
00578
00579 ret = declare_symbol(SYM_LEVELS, id, datum, &value, &value);
00580 switch (ret) {
00581 case -3:{
00582 yyerror("Out of memory!");
00583 goto bad;
00584 }
00585 case -2:{
00586 yyerror("duplicate declaration of sensitivity level");
00587 goto bad;
00588 }
00589 case -1:{
00590 yyerror("could not declare sensitivity level here");
00591 goto bad;
00592 }
00593 case 0:
00594 case 1:{
00595 break;
00596 }
00597 default:{
00598 assert(0);
00599 }
00600 }
00601
00602 while ((id = queue_remove(id_queue))) {
00603 if (id_has_dot(id)) {
00604 yyerror("sensitivity aliases may not contain periods");
00605 goto bad_alias;
00606 }
00607 aliasdatum = (level_datum_t *) malloc(sizeof(level_datum_t));
00608 if (!aliasdatum) {
00609 yyerror("out of memory");
00610 goto bad_alias;
00611 }
00612 level_datum_init(aliasdatum);
00613 aliasdatum->isalias = TRUE;
00614 aliasdatum->level = level;
00615
00616 ret = declare_symbol(SYM_LEVELS, id, aliasdatum, NULL, &value);
00617 switch (ret) {
00618 case -3:{
00619 yyerror("Out of memory!");
00620 goto bad_alias;
00621 }
00622 case -2:{
00623 yyerror("duplicate declaration of sensitivity alias");
00624 goto bad_alias;
00625 }
00626 case -1:{
00627 yyerror("could not declare sensitivity alias here");
00628 goto bad_alias;
00629 }
00630 case 0:
00631 case 1:{
00632 break;
00633 }
00634 default:{
00635 assert(0);
00636 }
00637 }
00638 }
00639
00640 return 0;
00641
00642 bad:
00643 if (id)
00644 free(id);
00645 if (level)
00646 free(level);
00647 if (datum) {
00648 level_datum_destroy(datum);
00649 free(datum);
00650 }
00651 return -1;
00652
00653 bad_alias:
00654 if (id)
00655 free(id);
00656 if (aliasdatum) {
00657 level_datum_destroy(aliasdatum);
00658 free(aliasdatum);
00659 }
00660 return -1;
00661 }
00662
00663 int define_dominance(void)
00664 {
00665 level_datum_t *datum;
00666 int order;
00667 char *id;
00668
00669 if (!mlspol) {
00670 yyerror("dominance definition in non-MLS configuration");
00671 return -1;
00672 }
00673
00674 if (pass == 2) {
00675 while ((id = queue_remove(id_queue)))
00676 free(id);
00677 return 0;
00678 }
00679
00680 order = 0;
00681 while ((id = (char *)queue_remove(id_queue))) {
00682 datum = (level_datum_t *) hashtab_search(policydbp->p_levels.table, (hashtab_key_t) id);
00683 if (!datum) {
00684 yyerror2("unknown sensitivity %s used in dominance " "definition", id);
00685 free(id);
00686 return -1;
00687 }
00688 if (datum->level->sens != 0) {
00689 yyerror2("sensitivity %s occurs multiply in dominance " "definition", id);
00690 free(id);
00691 return -1;
00692 }
00693 datum->level->sens = ++order;
00694
00695
00696 free(id);
00697 }
00698
00699 if (order != policydbp->p_levels.nprim) {
00700 yyerror("all sensitivities must be specified in dominance definition");
00701 return -1;
00702 }
00703 return 0;
00704 }
00705
00706 int define_category(void)
00707 {
00708 char *id;
00709 cat_datum_t *datum = 0, *aliasdatum = 0;
00710 int ret;
00711 uint32_t value;
00712
00713 if (!mlspol) {
00714 yyerror("category definition in non-MLS configuration");
00715 return -1;
00716 }
00717
00718 if (pass == 2) {
00719 while ((id = queue_remove(id_queue)))
00720 free(id);
00721 return 0;
00722 }
00723
00724 id = (char *)queue_remove(id_queue);
00725 if (!id) {
00726 yyerror("no category name for category definition?");
00727 return -1;
00728 }
00729 if (id_has_dot(id)) {
00730 yyerror("category identifiers may not contain periods");
00731 goto bad;
00732 }
00733 datum = (cat_datum_t *) malloc(sizeof(cat_datum_t));
00734 if (!datum) {
00735 yyerror("out of memory");
00736 goto bad;
00737 }
00738 cat_datum_init(datum);
00739 datum->isalias = FALSE;
00740
00741 ret = declare_symbol(SYM_CATS, id, datum, &value, &value);
00742 switch (ret) {
00743 case -3:{
00744 yyerror("Out of memory!");
00745 goto bad;
00746 }
00747 case -2:{
00748 yyerror("duplicate declaration of category");
00749 goto bad;
00750 }
00751 case -1:{
00752 yyerror("could not declare category here");
00753 goto bad;
00754 }
00755 case 0:
00756 case 1:{
00757 break;
00758 }
00759 default:{
00760 assert(0);
00761 }
00762 }
00763 datum->s.value = value;
00764
00765 while ((id = queue_remove(id_queue))) {
00766 if (id_has_dot(id)) {
00767 yyerror("category aliases may not contain periods");
00768 goto bad_alias;
00769 }
00770 aliasdatum = (cat_datum_t *) malloc(sizeof(cat_datum_t));
00771 if (!aliasdatum) {
00772 yyerror("out of memory");
00773 goto bad_alias;
00774 }
00775 cat_datum_init(aliasdatum);
00776 aliasdatum->isalias = TRUE;
00777 aliasdatum->s.value = datum->s.value;
00778
00779 ret = declare_symbol(SYM_CATS, id, aliasdatum, NULL, &datum->s.value);
00780 switch (ret) {
00781 case -3:{
00782 yyerror("Out of memory!");
00783 goto bad_alias;
00784 }
00785 case -2:{
00786 yyerror("duplicate declaration of category aliases");
00787 goto bad_alias;
00788 }
00789 case -1:{
00790 yyerror("could not declare category aliases here");
00791 goto bad_alias;
00792 }
00793 case 0:
00794 case 1:{
00795 break;
00796 }
00797 default:{
00798 assert(0);
00799 }
00800 }
00801 }
00802
00803 return 0;
00804
00805 bad:
00806 if (id)
00807 free(id);
00808 if (datum) {
00809 cat_datum_destroy(datum);
00810 free(datum);
00811 }
00812 return -1;
00813
00814 bad_alias:
00815 if (id)
00816 free(id);
00817 if (aliasdatum) {
00818 cat_datum_destroy(aliasdatum);
00819 free(aliasdatum);
00820 }
00821 return -1;
00822 }
00823
00824 static int clone_level(hashtab_key_t key, hashtab_datum_t datum, void *arg)
00825 {
00826 level_datum_t *levdatum = (level_datum_t *) datum;
00827 mls_level_t *level = (mls_level_t *) arg, *newlevel;
00828
00829 if (levdatum->level == level) {
00830 levdatum->defined = 1;
00831 if (!levdatum->isalias)
00832 return 0;
00833 newlevel = (mls_level_t *) malloc(sizeof(mls_level_t));
00834 if (!newlevel)
00835 return -1;
00836 if (mls_level_cpy(newlevel, level)) {
00837 free(newlevel);
00838 return -1;
00839 }
00840 levdatum->level = newlevel;
00841 }
00842 return 0;
00843 }
00844
00845 int define_level(void)
00846 {
00847 char *id;
00848 level_datum_t *levdatum;
00849
00850 if (!mlspol) {
00851 yyerror("level definition in non-MLS configuration");
00852 return -1;
00853 }
00854
00855 if (pass == 2) {
00856 while ((id = queue_remove(id_queue)))
00857 free(id);
00858 return 0;
00859 }
00860
00861 id = (char *)queue_remove(id_queue);
00862 if (!id) {
00863 yyerror("no level name for level definition?");
00864 return -1;
00865 }
00866 levdatum = (level_datum_t *) hashtab_search(policydbp->p_levels.table, (hashtab_key_t) id);
00867 if (!levdatum) {
00868 yyerror2("unknown sensitivity %s used in level definition", id);
00869 free(id);
00870 return -1;
00871 }
00872 if (ebitmap_length(&levdatum->level->cat)) {
00873 yyerror2("sensitivity %s used in multiple level definitions", id);
00874 free(id);
00875 return -1;
00876 }
00877 free(id);
00878
00879 levdatum->defined = 1;
00880
00881 while ((id = queue_remove(id_queue))) {
00882 cat_datum_t *cdatum;
00883 int range_start, range_end, i;
00884
00885 if (id_has_dot(id)) {
00886 char *id_start = id;
00887 char *id_end = strchr(id, '.');
00888
00889 *(id_end++) = '\0';
00890
00891 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, (hashtab_key_t)
00892 id_start);
00893 if (!cdatum) {
00894 yyerror2("unknown category %s", id_start);
00895 free(id);
00896 return -1;
00897 }
00898 range_start = cdatum->s.value - 1;
00899 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, (hashtab_key_t)
00900 id_end);
00901 if (!cdatum) {
00902 yyerror2("unknown category %s", id_end);
00903 free(id);
00904 return -1;
00905 }
00906 range_end = cdatum->s.value - 1;
00907
00908 if (range_end < range_start) {
00909 yyerror2("category range is invalid");
00910 free(id);
00911 return -1;
00912 }
00913 } else {
00914 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, (hashtab_key_t) id);
00915 range_start = range_end = cdatum->s.value - 1;
00916 }
00917
00918 for (i = range_start; i <= range_end; i++) {
00919 if (ebitmap_set_bit(&levdatum->level->cat, i, TRUE)) {
00920 yyerror("out of memory");
00921 free(id);
00922 return -1;
00923 }
00924 }
00925
00926 free(id);
00927 }
00928
00929 if (hashtab_map(policydbp->p_levels.table, clone_level, levdatum->level)) {
00930 yyerror("out of memory");
00931 return -1;
00932 }
00933
00934 return 0;
00935 }
00936
00937 int define_attrib(void)
00938 {
00939 if (pass == 2) {
00940 free(queue_remove(id_queue));
00941 return 0;
00942 }
00943
00944 if (declare_type(TRUE, TRUE) == NULL) {
00945 return -1;
00946 }
00947 return 0;
00948 }
00949
00950 static int add_aliases_to_type(type_datum_t * type)
00951 {
00952 char *id;
00953 type_datum_t *aliasdatum = NULL;
00954 int ret;
00955 while ((id = queue_remove(id_queue))) {
00956 if (id_has_dot(id)) {
00957 free(id);
00958 yyerror("type alias identifiers may not contain periods");
00959 return -1;
00960 }
00961 aliasdatum = (type_datum_t *) malloc(sizeof(type_datum_t));
00962 if (!aliasdatum) {
00963 free(id);
00964 yyerror("Out of memory!");
00965 return -1;
00966 }
00967 memset(aliasdatum, 0, sizeof(type_datum_t));
00968 aliasdatum->s.value = type->s.value;
00969
00970 ret = declare_symbol(SYM_TYPES, id, aliasdatum, NULL, &aliasdatum->s.value);
00971 switch (ret) {
00972 case -3:{
00973 yyerror("Out of memory!");
00974 goto cleanup;
00975 }
00976 case -2:{
00977 yyerror2("duplicate declaration of alias %s", id);
00978 goto cleanup;
00979 }
00980 case -1:{
00981 yyerror("could not declare alias here");
00982 goto cleanup;
00983 }
00984 case 0:
00985 case 1:{
00986 break;
00987 }
00988 default:{
00989 assert(0);
00990 }
00991 }
00992 }
00993 return 0;
00994 cleanup:
00995 free(id);
00996 type_datum_destroy(aliasdatum);
00997 free(aliasdatum);
00998 return -1;
00999 }
01000
01001 int define_typealias(void)
01002 {
01003 char *id;
01004 type_datum_t *t;
01005
01006 if (pass == 2) {
01007 while ((id = queue_remove(id_queue)))
01008 free(id);
01009 return 0;
01010 }
01011
01012 id = (char *)queue_remove(id_queue);
01013 if (!id) {
01014 yyerror("no type name for typealias definition?");
01015 return -1;
01016 }
01017
01018 if (!is_id_in_scope(SYM_TYPES, id)) {
01019 yyerror2("type %s is not within scope", id);
01020 free(id);
01021 return -1;
01022 }
01023 t = hashtab_search(policydbp->p_types.table, id);
01024 if (!t || t->flavor == TYPE_ATTRIB) {
01025 yyerror2("unknown type %s, or it was already declared as an " "attribute", id);
01026 free(id);
01027 return -1;
01028 }
01029 free(id);
01030 return add_aliases_to_type(t);
01031 }
01032
01033 int define_typeattribute(void)
01034 {
01035 char *id;
01036 type_datum_t *t, *attr;
01037
01038 if (pass == 2) {
01039 while ((id = queue_remove(id_queue)))
01040 free(id);
01041 return 0;
01042 }
01043
01044 id = (char *)queue_remove(id_queue);
01045 if (!id) {
01046 yyerror("no type name for typeattribute definition?");
01047 return -1;
01048 }
01049
01050 if (!is_id_in_scope(SYM_TYPES, id)) {
01051 yyerror2("type %s is not within scope", id);
01052 free(id);
01053 return -1;
01054 }
01055 t = hashtab_search(policydbp->p_types.table, id);
01056 if (!t || t->flavor == TYPE_ATTRIB) {
01057 yyerror2("unknown type %s", id);
01058 free(id);
01059 return -1;
01060 }
01061 free(id);
01062
01063 while ((id = queue_remove(id_queue))) {
01064 if (!is_id_in_scope(SYM_TYPES, id)) {
01065 yyerror2("attribute %s is not within scope", id);
01066 free(id);
01067 return -1;
01068 }
01069 attr = hashtab_search(policydbp->p_types.table, id);
01070 if (!attr) {
01071
01072 yyerror2("attribute %s is not declared", id);
01073 free(id);
01074 return -1;
01075 }
01076
01077 if (attr->flavor != TYPE_ATTRIB) {
01078 yyerror2("%s is a type, not an attribute", id);
01079 free(id);
01080 return -1;
01081 }
01082
01083 if ((attr = get_local_type(id, attr->s.value, 1)) == NULL) {
01084 yyerror("Out of memory!");
01085 return -1;
01086 }
01087
01088 if (ebitmap_set_bit(&attr->types, (t->s.value - 1), TRUE)) {
01089 yyerror("out of memory");
01090 return -1;
01091 }
01092 }
01093
01094 return 0;
01095 }
01096
01097 int define_type(int alias)
01098 {
01099 char *id;
01100 type_datum_t *datum, *attr;
01101 int newattr = 0;
01102
01103 if (pass == 2) {
01104 while ((id = queue_remove(id_queue)))
01105 free(id);
01106 if (alias) {
01107 while ((id = queue_remove(id_queue)))
01108 free(id);
01109 }
01110 return 0;
01111 }
01112
01113 if ((datum = declare_type(TRUE, FALSE)) == NULL) {
01114 return -1;
01115 }
01116
01117 if (alias) {
01118 if (add_aliases_to_type(datum) == -1) {
01119 return -1;
01120 }
01121 }
01122
01123 while ((id = queue_remove(id_queue))) {
01124 if (!is_id_in_scope(SYM_TYPES, id)) {
01125 yyerror2("attribute %s is not within scope", id);
01126 free(id);
01127 return -1;
01128 }
01129 attr = hashtab_search(policydbp->p_types.table, id);
01130 if (!attr) {
01131
01132 yyerror2("attribute %s is not declared", id);
01133 return -1;
01134 } else {
01135 newattr = 0;
01136 }
01137
01138 if (attr->flavor != TYPE_ATTRIB) {
01139 yyerror2("%s is a type, not an attribute", id);
01140 return -1;
01141 }
01142
01143 if ((attr = get_local_type(id, attr->s.value, 1)) == NULL) {
01144 yyerror("Out of memory!");
01145 return -1;
01146 }
01147
01148 if (ebitmap_set_bit(&attr->types, datum->s.value - 1, TRUE)) {
01149 yyerror("Out of memory");
01150 return -1;
01151 }
01152 }
01153
01154 return 0;
01155 }
01156
01157 struct val_to_name
01158 {
01159 unsigned int val;
01160 char *name;
01161 };
01162
01163
01164
01165
01166 static int set_types(type_set_t * set, char *id, int *add, char starallowed)
01167 {
01168 type_datum_t *t;
01169
01170 if (strcmp(id, "*") == 0) {
01171 if (!starallowed) {
01172 yyerror("* not allowed in this type of rule");
01173 return -1;
01174 }
01175
01176 set->flags = TYPE_STAR;
01177 free(id);
01178 *add = 1;
01179 return 0;
01180 }
01181
01182 if (strcmp(id, "~") == 0) {
01183 if (!starallowed) {
01184 yyerror("~ not allowed in this type of rule");
01185 return -1;
01186 }
01187
01188 set->flags = TYPE_COMP;
01189 free(id);
01190 *add = 1;
01191 return 0;
01192 }
01193
01194 if (strcmp(id, "-") == 0) {
01195 *add = 0;
01196 free(id);
01197 return 0;
01198 }
01199
01200 if (!is_id_in_scope(SYM_TYPES, id)) {
01201 yyerror2("type %s is not within scope", id);
01202 free(id);
01203 return -1;
01204 }
01205 t = hashtab_search(policydbp->p_types.table, id);
01206 if (!t) {
01207 yyerror2("unknown type %s", id);
01208 free(id);
01209 return -1;
01210 }
01211
01212 if (*add == 0) {
01213 if (ebitmap_set_bit(&set->negset, t->s.value - 1, TRUE))
01214 goto oom;
01215 } else {
01216 if (ebitmap_set_bit(&set->types, t->s.value - 1, TRUE))
01217 goto oom;
01218 }
01219 free(id);
01220 *add = 1;
01221 return 0;
01222 oom:
01223 yyerror("Out of memory");
01224 free(id);
01225 return -1;
01226 }
01227
01228 int define_compute_type_helper(int which, avrule_t ** rule)
01229 {
01230 char *id;
01231 type_datum_t *datum;
01232 class_datum_t *cladatum;
01233 ebitmap_t tclasses;
01234 ebitmap_node_t *node;
01235 avrule_t *avrule;
01236 class_perm_node_t *perm;
01237 int i, add = 1;
01238
01239 avrule = malloc(sizeof(avrule_t));
01240 if (!avrule) {
01241 yyerror("out of memory");
01242 return -1;
01243 }
01244 avrule_init(avrule);
01245 avrule->specified = which;
01246 avrule->line = policydb_lineno;
01247
01248 while ((id = queue_remove(id_queue))) {
01249 if (set_types(&avrule->stypes, id, &add, 0))
01250 return -1;
01251 }
01252 add = 1;
01253 while ((id = queue_remove(id_queue))) {
01254 if (set_types(&avrule->ttypes, id, &add, 0))
01255 return -1;
01256 }
01257
01258 ebitmap_init(&tclasses);
01259 while ((id = queue_remove(id_queue))) {
01260 if (!is_id_in_scope(SYM_CLASSES, id)) {
01261 yyerror2("class %s is not within scope", id);
01262 free(id);
01263 goto bad;
01264 }
01265 cladatum = hashtab_search(policydbp->p_classes.table, id);
01266 if (!cladatum) {
01267 yyerror2("unknown class %s", id);
01268 goto bad;
01269 }
01270 if (ebitmap_set_bit(&tclasses, cladatum->s.value - 1, TRUE)) {
01271 yyerror("Out of memory");
01272 goto bad;
01273 }
01274 free(id);
01275 }
01276
01277 id = (char *)queue_remove(id_queue);
01278 if (!id) {
01279 yyerror("no newtype?");
01280 goto bad;
01281 }
01282 if (!is_id_in_scope(SYM_TYPES, id)) {
01283 yyerror2("type %s is not within scope", id);
01284 free(id);
01285 goto bad;
01286 }
01287 datum = (type_datum_t *) hashtab_search(policydbp->p_types.table, (hashtab_key_t) id);
01288 if (!datum || datum->flavor == TYPE_ATTRIB) {
01289 yyerror2("unknown type %s", id);
01290 goto bad;
01291 }
01292 free(id);
01293
01294 ebitmap_for_each_bit(&tclasses, node, i) {
01295 if (ebitmap_node_get_bit(node, i)) {
01296 perm = malloc(sizeof(class_perm_node_t));
01297 if (!perm) {
01298 yyerror("out of memory");
01299 return -1;
01300 }
01301 class_perm_node_init(perm);
01302 perm->class = i + 1;
01303 perm->data = datum->s.value;
01304 perm->next = avrule->perms;
01305 avrule->perms = perm;
01306 }
01307 }
01308 ebitmap_destroy(&tclasses);
01309
01310 *rule = avrule;
01311 return 0;
01312
01313 bad:
01314 avrule_destroy(avrule);
01315 free(avrule);
01316 return -1;
01317 }
01318
01319 int define_compute_type(int which)
01320 {
01321 char *id;
01322 avrule_t *avrule;
01323 int retval;
01324
01325 if (pass == 1 || (num_rules && !load_rules)) {
01326 while ((id = queue_remove(id_queue)))
01327 free(id);
01328 while ((id = queue_remove(id_queue)))
01329 free(id);
01330 while ((id = queue_remove(id_queue)))
01331 free(id);
01332 id = queue_remove(id_queue);
01333 free(id);
01334 return 0;
01335 }
01336
01337 num_rules++;
01338
01339 if (define_compute_type_helper(which, &avrule))
01340 return -1;
01341
01342 retval = insert_check_type_rule(avrule, &policydbp->te_avtab, NULL, NULL);
01343 switch (retval) {
01344 case 1:{
01345
01346 append_avrule(avrule);
01347 return 0;
01348 }
01349 case 2:
01350 case 0:{
01351
01352 avrule_destroy(avrule);
01353 free(avrule);
01354 return 0;
01355 }
01356 case -1:{
01357 avrule_destroy(avrule);
01358 free(avrule);
01359 return -1;
01360 }
01361 default:{
01362 assert(0);
01363 }
01364 }
01365 }
01366
01367 avrule_t *define_cond_compute_type(int which)
01368 {
01369 char *id;
01370 avrule_t *avrule;
01371
01372 if (pass == 1 || (num_rules && !load_rules)) {
01373 while ((id = queue_remove(id_queue)))
01374 free(id);
01375 while ((id = queue_remove(id_queue)))
01376 free(id);
01377 while ((id = queue_remove(id_queue)))
01378 free(id);
01379 id = queue_remove(id_queue);
01380 free(id);
01381 return (avrule_t *) 1;
01382 }
01383
01384 num_rules++;
01385
01386 if (define_compute_type_helper(which, &avrule))
01387 return COND_ERR;
01388
01389 return avrule;
01390 }
01391
01392 int define_bool(void)
01393 {
01394 char *id, *bool_value;
01395 cond_bool_datum_t *datum;
01396 int ret;
01397 uint32_t value;
01398
01399 if (pass == 2) {
01400 while ((id = queue_remove(id_queue)))
01401 free(id);
01402 return 0;
01403 }
01404
01405 id = (char *)queue_remove(id_queue);
01406 if (!id) {
01407 yyerror("no identifier for bool definition?");
01408 return -1;
01409 }
01410 if (id_has_dot(id)) {
01411 free(id);
01412 yyerror("boolean identifiers may not contain periods");
01413 return -1;
01414 }
01415 datum = (cond_bool_datum_t *) malloc(sizeof(cond_bool_datum_t));
01416 if (!datum) {
01417 yyerror("out of memory");
01418 free(id);
01419 return -1;
01420 }
01421 memset(datum, 0, sizeof(cond_bool_datum_t));
01422 ret = declare_symbol(SYM_BOOLS, id, datum, &value, &value);
01423 switch (ret) {
01424 case -3:{
01425 yyerror("Out of memory!");
01426 goto cleanup;
01427 }
01428 case -2:{
01429 yyerror2("duplicate declaration of boolean %s", id);
01430 goto cleanup;
01431 }
01432 case -1:{
01433 yyerror("could not declare boolean here");
01434 goto cleanup;
01435 }
01436 case 0:
01437 case 1:{
01438 break;
01439 }
01440 default:{
01441 assert(0);
01442 }
01443 }
01444 datum->s.value = value;
01445
01446 bool_value = (char *)queue_remove(id_queue);
01447 if (!bool_value) {
01448 yyerror("no default value for bool definition?");
01449 free(id);
01450 return -1;
01451 }
01452
01453 datum->state = (int)(bool_value[0] == 'T') ? 1 : 0;
01454 free(bool_value);
01455 return 0;
01456 cleanup:
01457 cond_destroy_bool(id, datum, NULL);
01458 return -1;
01459 }
01460
01461 avrule_t *define_cond_pol_list(avrule_t * avlist, avrule_t * sl)
01462 {
01463 if (pass == 1 || (num_rules && !load_rules)) {
01464
01465 return (avrule_t *) 1;
01466 }
01467
01468 if (sl == NULL) {
01469
01470 return avlist;
01471 }
01472
01473
01474 sl->next = avlist;
01475 return sl;
01476 }
01477
01478 int define_te_avtab_helper(int which, avrule_t ** rule)
01479 {
01480 char *id;
01481 class_datum_t *cladatum;
01482 perm_datum_t *perdatum = NULL;
01483 class_perm_node_t *perms, *tail = NULL, *cur_perms = NULL;
01484 ebitmap_t tclasses;
01485 ebitmap_node_t *node;
01486 avrule_t *avrule;
01487 unsigned int i;
01488 int add = 1, ret = 0;
01489 int suppress = 0;
01490
01491 avrule = (avrule_t *) malloc(sizeof(avrule_t));
01492 if (!avrule) {
01493 yyerror("memory error");
01494 ret = -1;
01495 goto out;
01496 }
01497 avrule_init(avrule);
01498 avrule->specified = which;
01499 avrule->line = policydb_lineno;
01500
01501 while ((id = queue_remove(id_queue))) {
01502 if (set_types(&avrule->stypes, id, &add, which == AVRULE_NEVERALLOW ? 1 : 0)) {
01503 ret = -1;
01504 goto out;
01505 }
01506 }
01507 add = 1;
01508 while ((id = queue_remove(id_queue))) {
01509 if (strcmp(id, "self") == 0) {
01510 free(id);
01511 avrule->flags |= RULE_SELF;
01512 continue;
01513 }
01514 if (set_types(&avrule->ttypes, id, &add, which == AVRULE_NEVERALLOW ? 1 : 0)) {
01515 ret = -1;
01516 goto out;
01517 }
01518 }
01519
01520 ebitmap_init(&tclasses);
01521 while ((id = queue_remove(id_queue))) {
01522 if (!is_id_in_scope(SYM_CLASSES, id)) {
01523 yyerror2("class %s is not within scope", id);
01524 ret = -1;
01525 goto out;
01526 }
01527 cladatum = hashtab_search(policydbp->p_classes.table, id);
01528 if (!cladatum) {
01529 yyerror2("unknown class %s used in rule", id);
01530 ret = -1;
01531 goto out;
01532 }
01533 if (ebitmap_set_bit(&tclasses, cladatum->s.value - 1, TRUE)) {
01534 yyerror("Out of memory");
01535 ret = -1;
01536 goto out;
01537 }
01538 free(id);
01539 }
01540
01541 perms = NULL;
01542 ebitmap_for_each_bit(&tclasses, node, i) {
01543 if (!ebitmap_node_get_bit(node, i))
01544 continue;
01545 cur_perms = (class_perm_node_t *) malloc(sizeof(class_perm_node_t));
01546 if (!cur_perms) {
01547 yyerror("out of memory");
01548 ret = -1;
01549 goto out;
01550 }
01551 class_perm_node_init(cur_perms);
01552 cur_perms->class = i + 1;
01553 if (!perms)
01554 perms = cur_perms;
01555 if (tail)
01556 tail->next = cur_perms;
01557 tail = cur_perms;
01558 }
01559
01560 while ((id = queue_remove(id_queue))) {
01561 cur_perms = perms;
01562 ebitmap_for_each_bit(&tclasses, node, i) {
01563 if (!ebitmap_node_get_bit(node, i))
01564 continue;
01565 cladatum = policydbp->class_val_to_struct[i];
01566
01567 if (strcmp(id, "*") == 0) {
01568
01569 cur_perms->data = ~0U;
01570 goto next;
01571 }
01572
01573 if (strcmp(id, "~") == 0) {
01574
01575 if (which == AVRULE_DONTAUDIT)
01576 yywarn("dontaudit rule with a ~?");
01577 cur_perms->data = ~cur_perms->data;
01578 goto next;
01579 }
01580
01581 perdatum = hashtab_search(cladatum->permissions.table, id);
01582 if (!perdatum) {
01583 if (cladatum->comdatum) {
01584 perdatum = hashtab_search(cladatum->comdatum->permissions.table, id);
01585 }
01586 }
01587 if (!perdatum) {
01588 if (!suppress)
01589 yyerror2("permission %s is not defined"
01590 " for class %s", id, policydbp->p_class_val_to_name[i]);
01591 continue;
01592 } else if (!is_perm_in_scope(id, policydbp->p_class_val_to_name[i])) {
01593 if (!suppress) {
01594 yyerror2("permission %s of class %s is"
01595 " not within scope", id, policydbp->p_class_val_to_name[i]);
01596 }
01597 continue;
01598 } else {
01599 cur_perms->data |= 1U << (perdatum->s.value - 1);
01600 }
01601 next:
01602 cur_perms = cur_perms->next;
01603 }
01604
01605 free(id);
01606 }
01607
01608 ebitmap_destroy(&tclasses);
01609
01610 avrule->perms = perms;
01611 *rule = avrule;
01612
01613 out:
01614 return ret;
01615
01616 }
01617
01618 avrule_t *define_cond_te_avtab(int which)
01619 {
01620 char *id;
01621 avrule_t *avrule;
01622 int i;
01623
01624 if (pass == 1 || (num_rules && !load_rules)) {
01625 for (i = 0; i < 4; i++) {
01626 while ((id = queue_remove(id_queue)))
01627 free(id);
01628 }
01629 return (avrule_t *) 1;
01630 }
01631
01632 num_rules++;
01633
01634 if (define_te_avtab_helper(which, &avrule))
01635 return COND_ERR;
01636
01637 return avrule;
01638 }
01639
01640 int define_te_avtab(int which)
01641 {
01642 char *id;
01643 avrule_t *avrule;
01644 int i;
01645
01646 if (pass == 1 || (num_rules && !load_rules)) {
01647 for (i = 0; i < 4; i++) {
01648 while ((id = queue_remove(id_queue)))
01649 free(id);
01650 }
01651 return 0;
01652 }
01653
01654 num_rules++;
01655
01656 if (define_te_avtab_helper(which, &avrule))
01657 return -1;
01658
01659
01660 append_avrule(avrule);
01661 return 0;
01662 }
01663
01664 int define_role_types(void)
01665 {
01666 role_datum_t *role;
01667 char *id;
01668 int add = 1;
01669
01670 if (pass == 1) {
01671 while ((id = queue_remove(id_queue)))
01672 free(id);
01673 return 0;
01674 }
01675
01676 if ((role = declare_role()) == NULL) {
01677 return -1;
01678 }
01679 while ((id = queue_remove(id_queue))) {
01680 if (set_types(&role->types, id, &add, 0))
01681 return -1;
01682 }
01683
01684 return 0;
01685 }
01686
01687 role_datum_t *merge_roles_dom(role_datum_t * r1, role_datum_t * r2)
01688 {
01689 role_datum_t *new;
01690
01691 if (pass == 1) {
01692 return (role_datum_t *) 1;
01693 }
01694
01695 new = malloc(sizeof(role_datum_t));
01696 if (!new) {
01697 yyerror("out of memory");
01698 return NULL;
01699 }
01700 memset(new, 0, sizeof(role_datum_t));
01701 new->s.value = 0;
01702 if (ebitmap_or(&new->dominates, &r1->dominates, &r2->dominates)) {
01703 yyerror("out of memory");
01704 return NULL;
01705 }
01706 if (ebitmap_or(&new->types.types, &r1->types.types, &r2->types.types)) {
01707 yyerror("out of memory");
01708 return NULL;
01709 }
01710 if (!r1->s.value) {
01711
01712 type_set_destroy(&r1->types);
01713 ebitmap_destroy(&r1->dominates);
01714 free(r1);
01715 }
01716 if (!r2->s.value) {
01717
01718 yyerror("right hand role is temporary?");
01719 type_set_destroy(&r2->types);
01720 ebitmap_destroy(&r2->dominates);
01721 free(r2);
01722 }
01723 return new;
01724 }
01725
01726
01727 static int dominate_role_recheck(hashtab_key_t key, hashtab_datum_t datum, void *arg)
01728 {
01729 role_datum_t *rdp = (role_datum_t *) arg;
01730 role_datum_t *rdatum = (role_datum_t *) datum;
01731 ebitmap_node_t *node;
01732 int i;
01733
01734
01735 if (rdatum->s.value == rdp->s.value)
01736 return 0;
01737
01738
01739 if (ebitmap_get_bit(&(rdatum->dominates), rdp->s.value - 1)) {
01740 ebitmap_t types;
01741 ebitmap_init(&types);
01742 if (type_set_expand(&rdp->types, &types, policydbp, 1)) {
01743 ebitmap_destroy(&types);
01744 return -1;
01745 }
01746
01747 ebitmap_for_each_bit(&rdp->dominates, node, i) {
01748 if (ebitmap_node_get_bit(node, i))
01749 if (ebitmap_set_bit(&rdatum->dominates, i, TRUE))
01750 goto oom;
01751 }
01752 ebitmap_for_each_bit(&types, node, i) {
01753 if (ebitmap_node_get_bit(node, i))
01754 if (ebitmap_set_bit(&rdatum->types.types, i, TRUE))
01755 goto oom;
01756 }
01757 ebitmap_destroy(&types);
01758 }
01759
01760
01761 return 0;
01762 oom:
01763 yyerror("Out of memory");
01764 return -1;
01765 }
01766
01767 role_datum_t *define_role_dom(role_datum_t * r)
01768 {
01769 role_datum_t *role;
01770 char *role_id;
01771 ebitmap_node_t *node;
01772 unsigned int i;
01773 int ret;
01774
01775 if (pass == 1) {
01776 role_id = queue_remove(id_queue);
01777 free(role_id);
01778 return (role_datum_t *) 1;
01779 }
01780
01781 yywarn("Role dominance has been deprecated");
01782
01783 role_id = queue_remove(id_queue);
01784 if (!is_id_in_scope(SYM_ROLES, role_id)) {
01785 yyerror2("role %s is not within scope", role_id);
01786 free(role_id);
01787 return NULL;
01788 }
01789 role = (role_datum_t *) hashtab_search(policydbp->p_roles.table, role_id);
01790 if (!role) {
01791 role = (role_datum_t *) malloc(sizeof(role_datum_t));
01792 if (!role) {
01793 yyerror("out of memory");
01794 free(role_id);
01795 return NULL;
01796 }
01797 memset(role, 0, sizeof(role_datum_t));
01798 ret = declare_symbol(SYM_ROLES, (hashtab_key_t) role_id, (hashtab_datum_t) role, &role->s.value, &role->s.value);
01799 switch (ret) {
01800 case -3:{
01801 yyerror("Out of memory!");
01802 goto cleanup;
01803 }
01804 case -2:{
01805 yyerror2("duplicate declaration of role %s", role_id);
01806 goto cleanup;
01807 }
01808 case -1:{
01809 yyerror("could not declare role here");
01810 goto cleanup;
01811 }
01812 case 0:
01813 case 1:{
01814 break;
01815 }
01816 default:{
01817 assert(0);
01818 }
01819 }
01820 if (ebitmap_set_bit(&role->dominates, role->s.value - 1, TRUE)) {
01821 yyerror("Out of memory!");
01822 goto cleanup;
01823 }
01824 }
01825 if (r) {
01826 ebitmap_t types;
01827 ebitmap_init(&types);
01828 ebitmap_for_each_bit(&r->dominates, node, i) {
01829 if (ebitmap_node_get_bit(node, i))
01830 if (ebitmap_set_bit(&role->dominates, i, TRUE))
01831 goto oom;
01832 }
01833 if (type_set_expand(&r->types, &types, policydbp, 1)) {
01834 ebitmap_destroy(&types);
01835 return NULL;
01836 }
01837 ebitmap_for_each_bit(&types, node, i) {
01838 if (ebitmap_node_get_bit(node, i))
01839 if (ebitmap_set_bit(&role->types.types, i, TRUE))
01840 goto oom;
01841 }
01842 ebitmap_destroy(&types);
01843 if (!r->s.value) {
01844
01845 type_set_destroy(&r->types);
01846 ebitmap_destroy(&r->dominates);
01847 free(r);
01848 }
01849
01850
01851
01852
01853 hashtab_map(policydbp->p_roles.table, dominate_role_recheck, role);
01854 }
01855 return role;
01856 cleanup:
01857 free(role_id);
01858 role_datum_destroy(role);
01859 free(role);
01860 return NULL;
01861 oom:
01862 yyerror("Out of memory");
01863 goto cleanup;
01864 }
01865
01866 static int role_val_to_name_helper(hashtab_key_t key, hashtab_datum_t datum, void *p)
01867 {
01868 struct val_to_name *v = p;
01869 role_datum_t *roldatum;
01870
01871 roldatum = (role_datum_t *) datum;
01872
01873 if (v->val == roldatum->s.value) {
01874 v->name = key;
01875 return 1;
01876 }
01877
01878 return 0;
01879 }
01880
01881 static char *role_val_to_name(unsigned int val)
01882 {
01883 struct val_to_name v;
01884 int rc;
01885
01886 v.val = val;
01887 rc = hashtab_map(policydbp->p_roles.table, role_val_to_name_helper, &v);
01888 if (rc)
01889 return v.name;
01890 return NULL;
01891 }
01892
01893 static int set_roles(role_set_t * set, char *id)
01894 {
01895 role_datum_t *r;
01896
01897 if (strcmp(id, "*") == 0) {
01898 free(id);
01899 yyerror("* is not allowed for role sets");
01900 return -1;
01901 }
01902
01903 if (strcmp(id, "~") == 0) {
01904 free(id);
01905 yyerror("~ is not allowed for role sets");
01906 return -1;
01907 }
01908 if (!is_id_in_scope(SYM_ROLES, id)) {
01909 yyerror2("role %s is not within scope", id);
01910 free(id);
01911 return -1;
01912 }
01913 r = hashtab_search(policydbp->p_roles.table, id);
01914 if (!r) {
01915 yyerror2("unknown role %s", id);
01916 free(id);
01917 return -1;
01918 }
01919
01920 if (ebitmap_set_bit(&set->roles, r->s.value - 1, TRUE)) {
01921 yyerror("out of memory");
01922 free(id);
01923 return -1;
01924 }
01925 free(id);
01926 return 0;
01927 }
01928
01929 int define_role_trans(void)
01930 {
01931 char *id;
01932 role_datum_t *role;
01933 role_set_t roles;
01934 type_set_t types;
01935 ebitmap_t e_types, e_roles;
01936 ebitmap_node_t *tnode, *rnode;
01937 struct role_trans *tr = NULL;
01938 struct role_trans_rule *rule = NULL;
01939 unsigned int i, j;
01940 int add = 1;
01941
01942 if (pass == 1) {
01943 while ((id = queue_remove(id_queue)))
01944 free(id);
01945 while ((id = queue_remove(id_queue)))
01946 free(id);
01947 id = queue_remove(id_queue);
01948 free(id);
01949 return 0;
01950 }
01951
01952 role_set_init(&roles);
01953 ebitmap_init(&e_roles);
01954 type_set_init(&types);
01955 ebitmap_init(&e_types);
01956
01957 while ((id = queue_remove(id_queue))) {
01958 if (set_roles(&roles, id))
01959 return -1;
01960 }
01961 add = 1;
01962 while ((id = queue_remove(id_queue))) {
01963 if (set_types(&types, id, &add, 0))
01964 return -1;
01965 }
01966
01967 id = (char *)queue_remove(id_queue);
01968 if (!id) {
01969 yyerror("no new role in transition definition?");
01970 goto bad;
01971 }
01972 if (!is_id_in_scope(SYM_ROLES, id)) {
01973 yyerror2("role %s is not within scope", id);
01974 free(id);
01975 goto bad;
01976 }
01977 role = hashtab_search(policydbp->p_roles.table, id);
01978 if (!role) {
01979 yyerror2("unknown role %s used in transition definition", id);
01980 goto bad;
01981 }
01982 free(id);
01983
01984
01985 if (role_set_expand(&roles, &e_roles, policydbp))
01986 goto bad;
01987
01988 if (type_set_expand(&types, &e_types, policydbp, 1))
01989 goto bad;
01990
01991 ebitmap_for_each_bit(&e_roles, rnode, i) {
01992 if (!ebitmap_node_get_bit(rnode, i))
01993 continue;
01994 ebitmap_for_each_bit(&e_types, tnode, j) {
01995 if (!ebitmap_node_get_bit(tnode, j))
01996 continue;
01997
01998 for (tr = policydbp->role_tr; tr; tr = tr->next) {
01999 if (tr->role == (i + 1) && tr->type == (j + 1)) {
02000 yyerror2("duplicate role transition for (%s,%s)",
02001 role_val_to_name(i + 1), policydbp->p_type_val_to_name[j]);
02002 goto bad;
02003 }
02004 }
02005
02006 tr = malloc(sizeof(struct role_trans));
02007 if (!tr) {
02008 yyerror("out of memory");
02009 return -1;
02010 }
02011 memset(tr, 0, sizeof(struct role_trans));
02012 tr->role = i + 1;
02013 tr->type = j + 1;
02014 tr->new_role = role->s.value;
02015 tr->next = policydbp->role_tr;
02016 policydbp->role_tr = tr;
02017 }
02018 }
02019
02020 rule = malloc(sizeof(struct role_trans_rule));
02021 if (!rule) {
02022 yyerror("out of memory");
02023 return -1;
02024 }
02025 memset(rule, 0, sizeof(struct role_trans_rule));
02026 rule->roles = roles;
02027 rule->types = types;
02028 rule->new_role = role->s.value;
02029
02030 append_role_trans(rule);
02031
02032 ebitmap_destroy(&e_roles);
02033 ebitmap_destroy(&e_types);
02034
02035 return 0;
02036
02037 bad:
02038 return -1;
02039 }
02040
02041 int define_role_allow(void)
02042 {
02043 char *id;
02044 struct role_allow_rule *ra = 0;
02045
02046 if (pass == 1) {
02047 while ((id = queue_remove(id_queue)))
02048 free(id);
02049 while ((id = queue_remove(id_queue)))
02050 free(id);
02051 return 0;
02052 }
02053
02054 ra = malloc(sizeof(role_allow_rule_t));
02055 if (!ra) {
02056 yyerror("out of memory");
02057 return -1;
02058 }
02059 role_allow_rule_init(ra);
02060
02061 while ((id = queue_remove(id_queue))) {
02062 if (set_roles(&ra->roles, id))
02063 return -1;
02064 }
02065
02066 while ((id = queue_remove(id_queue))) {
02067 if (set_roles(&ra->new_roles, id))
02068 return -1;
02069 }
02070
02071 append_role_allow(ra);
02072 return 0;
02073 }
02074
02075 static constraint_expr_t *constraint_expr_clone(constraint_expr_t * expr)
02076 {
02077 constraint_expr_t *h = NULL, *l = NULL, *e, *newe;
02078 for (e = expr; e; e = e->next) {
02079 newe = malloc(sizeof(*newe));
02080 if (!newe)
02081 goto oom;
02082 if (constraint_expr_init(newe) == -1) {
02083 free(newe);
02084 goto oom;
02085 }
02086 if (l)
02087 l->next = newe;
02088 else
02089 h = newe;
02090 l = newe;
02091 newe->expr_type = e->expr_type;
02092 newe->attr = e->attr;
02093 newe->op = e->op;
02094 if (newe->expr_type == CEXPR_NAMES) {
02095 if (newe->attr & CEXPR_TYPE) {
02096 if (type_set_cpy(newe->type_names, e->type_names))
02097 goto oom;
02098 } else {
02099 if (ebitmap_cpy(&newe->names, &e->names))
02100 goto oom;
02101 }
02102 }
02103 }
02104
02105 return h;
02106 oom:
02107 e = h;
02108 while (e) {
02109 l = e;
02110 e = e->next;
02111 constraint_expr_destroy(l);
02112 }
02113 return NULL;
02114 }
02115
02116 int define_constraint(constraint_expr_t * expr)
02117 {
02118 struct constraint_node *node;
02119 char *id;
02120 class_datum_t *cladatum;
02121 perm_datum_t *perdatum;
02122 ebitmap_t classmap;
02123 ebitmap_node_t *enode;
02124 constraint_expr_t *e;
02125 unsigned int i;
02126 int depth;
02127 unsigned char useexpr = 1;
02128
02129 if (pass == 1) {
02130 while ((id = queue_remove(id_queue)))
02131 free(id);
02132 while ((id = queue_remove(id_queue)))
02133 free(id);
02134 return 0;
02135 }
02136
02137 depth = -1;
02138 for (e = expr; e; e = e->next) {
02139 switch (e->expr_type) {
02140 case CEXPR_NOT:
02141 if (depth < 0) {
02142 yyerror("illegal constraint expression");
02143 return -1;
02144 }
02145 break;
02146 case CEXPR_AND:
02147 case CEXPR_OR:
02148 if (depth < 1) {
02149 yyerror("illegal constraint expression");
02150 return -1;
02151 }
02152 depth--;
02153 break;
02154 case CEXPR_ATTR:
02155 case CEXPR_NAMES:
02156 if (e->attr & CEXPR_XTARGET) {
02157 yyerror("illegal constraint expression");
02158 return -1;
02159 }
02160 if (depth == (CEXPR_MAXDEPTH - 1)) {
02161 yyerror("constraint expression is too deep");
02162 return -1;
02163 }
02164 depth++;
02165 break;
02166 default:
02167 yyerror("illegal constraint expression");
02168 return -1;
02169 }
02170 }
02171 if (depth != 0) {
02172 yyerror("illegal constraint expression");
02173 return -1;
02174 }
02175
02176 ebitmap_init(&classmap);
02177 while ((id = queue_remove(id_queue))) {
02178 if (!is_id_in_scope(SYM_CLASSES, id)) {
02179 yyerror2("class %s is not within scope", id);
02180 free(id);
02181 return -1;
02182 }
02183 cladatum = (class_datum_t *) hashtab_search(policydbp->p_classes.table, (hashtab_key_t) id);
02184 if (!cladatum) {
02185 yyerror2("class %s is not defined", id);
02186 ebitmap_destroy(&classmap);
02187 free(id);
02188 return -1;
02189 }
02190 if (ebitmap_set_bit(&classmap, cladatum->s.value - 1, TRUE)) {
02191 yyerror("out of memory");
02192 ebitmap_destroy(&classmap);
02193 free(id);
02194 return -1;
02195 }
02196 node = malloc(sizeof(struct constraint_node));
02197 if (!node) {
02198 yyerror("out of memory");
02199 return -1;
02200 }
02201 memset(node, 0, sizeof(constraint_node_t));
02202 if (useexpr) {
02203 node->expr = expr;
02204 useexpr = 0;
02205 } else {
02206 node->expr = constraint_expr_clone(expr);
02207 }
02208 if (!node->expr) {
02209 yyerror("out of memory");
02210 return -1;
02211 }
02212 node->permissions = 0;
02213
02214 node->next = cladatum->constraints;
02215 cladatum->constraints = node;
02216
02217 free(id);
02218 }
02219
02220 while ((id = queue_remove(id_queue))) {
02221 ebitmap_for_each_bit(&classmap, enode, i) {
02222 if (ebitmap_node_get_bit(enode, i)) {
02223 cladatum = policydbp->class_val_to_struct[i];
02224 node = cladatum->constraints;
02225
02226 perdatum = (perm_datum_t *) hashtab_search(cladatum->permissions.table, (hashtab_key_t)
02227 id);
02228 if (!perdatum) {
02229 if (cladatum->comdatum) {
02230 perdatum = (perm_datum_t *)
02231 hashtab_search(cladatum->comdatum->permissions.table, (hashtab_key_t)
02232 id);
02233 }
02234 if (!perdatum) {
02235 yyerror2("permission %s is not" " defined", id);
02236 free(id);
02237 ebitmap_destroy(&classmap);
02238 return -1;
02239 }
02240 }
02241 node->permissions |= (1 << (perdatum->s.value - 1));
02242 }
02243 }
02244 free(id);
02245 }
02246
02247 ebitmap_destroy(&classmap);
02248
02249 return 0;
02250 }
02251
02252 int define_validatetrans(constraint_expr_t * expr)
02253 {
02254 struct constraint_node *node;
02255 char *id;
02256 class_datum_t *cladatum;
02257 ebitmap_t classmap;
02258 constraint_expr_t *e;
02259 int depth;
02260 unsigned char useexpr = 1;
02261
02262 if (pass == 1) {
02263 while ((id = queue_remove(id_queue)))
02264 free(id);
02265 return 0;
02266 }
02267
02268 depth = -1;
02269 for (e = expr; e; e = e->next) {
02270 switch (e->expr_type) {
02271 case CEXPR_NOT:
02272 if (depth < 0) {
02273 yyerror("illegal validatetrans expression");
02274 return -1;
02275 }
02276 break;
02277 case CEXPR_AND:
02278 case CEXPR_OR:
02279 if (depth < 1) {
02280 yyerror("illegal validatetrans expression");
02281 return -1;
02282 }
02283 depth--;
02284 break;
02285 case CEXPR_ATTR:
02286 case CEXPR_NAMES:
02287 if (depth == (CEXPR_MAXDEPTH - 1)) {
02288 yyerror("validatetrans expression is too deep");
02289 return -1;
02290 }
02291 depth++;
02292 break;
02293 default:
02294 yyerror("illegal validatetrans expression");
02295 return -1;
02296 }
02297 }
02298 if (depth != 0) {
02299 yyerror("illegal validatetrans expression");
02300 return -1;
02301 }
02302
02303 ebitmap_init(&classmap);
02304 while ((id = queue_remove(id_queue))) {
02305 if (!is_id_in_scope(SYM_CLASSES, id)) {
02306 yyerror2("class %s is not within scope", id);
02307 free(id);
02308 return -1;
02309 }
02310 cladatum = (class_datum_t *) hashtab_search(policydbp->p_classes.table, (hashtab_key_t) id);
02311 if (!cladatum) {
02312 yyerror2("class %s is not defined", id);
02313 ebitmap_destroy(&classmap);
02314 free(id);
02315 return -1;
02316 }
02317 if (ebitmap_set_bit(&classmap, (cladatum->s.value - 1), TRUE)) {
02318 yyerror("out of memory");
02319 ebitmap_destroy(&classmap);
02320 free(id);
02321 return -1;
02322 }
02323
02324 node = malloc(sizeof(struct constraint_node));
02325 if (!node) {
02326 yyerror("out of memory");
02327 return -1;
02328 }
02329 memset(node, 0, sizeof(constraint_node_t));
02330 if (useexpr) {
02331 node->expr = expr;
02332 useexpr = 0;
02333 } else {
02334 node->expr = constraint_expr_clone(expr);
02335 }
02336 node->permissions = 0;
02337
02338 node->next = cladatum->validatetrans;
02339 cladatum->validatetrans = node;
02340
02341 free(id);
02342 }
02343
02344 ebitmap_destroy(&classmap);
02345
02346 return 0;
02347 }
02348
02349 uintptr_t define_cexpr(uint32_t expr_type, uintptr_t arg1, uintptr_t arg2)
02350 {
02351 struct constraint_expr *expr, *e1 = NULL, *e2;
02352 user_datum_t *user;
02353 role_datum_t *role;
02354 ebitmap_t negset;
02355 char *id;
02356 uint32_t val;
02357 int add = 1;
02358
02359 if (pass == 1) {
02360 if (expr_type == CEXPR_NAMES) {
02361 while ((id = queue_remove(id_queue)))
02362 free(id);
02363 }
02364 return 1;
02365 }
02366
02367 if ((expr = malloc(sizeof(*expr))) == NULL || constraint_expr_init(expr) == -1) {
02368 yyerror("out of memory");
02369 free(expr);
02370 return 0;
02371 }
02372 expr->expr_type = expr_type;
02373
02374 switch (expr_type) {
02375 case CEXPR_NOT:
02376 e1 = NULL;
02377 e2 = (struct constraint_expr *)arg1;
02378 while (e2) {
02379 e1 = e2;
02380 e2 = e2->next;
02381 }
02382 if (!e1 || e1->next) {
02383 yyerror("illegal constraint expression");
02384 constraint_expr_destroy(expr);
02385 return 0;
02386 }
02387 e1->next = expr;
02388 return arg1;
02389 case CEXPR_AND:
02390 case CEXPR_OR:
02391 e1 = NULL;
02392 e2 = (struct constraint_expr *)arg1;
02393 while (e2) {
02394 e1 = e2;
02395 e2 = e2->next;
02396 }
02397 if (!e1 || e1->next) {
02398 yyerror("illegal constraint expression");
02399 constraint_expr_destroy(expr);
02400 return 0;
02401 }
02402 e1->next = (struct constraint_expr *)arg2;
02403
02404 e1 = NULL;
02405 e2 = (struct constraint_expr *)arg2;
02406 while (e2) {
02407 e1 = e2;
02408 e2 = e2->next;
02409 }
02410 if (!e1 || e1->next) {
02411 yyerror("illegal constraint expression");
02412 constraint_expr_destroy(expr);
02413 return 0;
02414 }
02415 e1->next = expr;
02416 return arg1;
02417 case CEXPR_ATTR:
02418 expr->attr = arg1;
02419 expr->op = arg2;
02420 return (uintptr_t) expr;
02421 case CEXPR_NAMES:
02422 add = 1;
02423 expr->attr = arg1;
02424 expr->op = arg2;
02425 ebitmap_init(&negset);
02426 while ((id = (char *)queue_remove(id_queue))) {
02427 if (expr->attr & CEXPR_USER) {
02428 if (!is_id_in_scope(SYM_USERS, id)) {
02429 yyerror2("user %s is not within scope", id);
02430 constraint_expr_destroy(expr);
02431 return 0;
02432 }
02433 user = (user_datum_t *) hashtab_search(policydbp->p_users.table, (hashtab_key_t)
02434 id);
02435 if (!user) {
02436 yyerror2("unknown user %s", id);
02437 constraint_expr_destroy(expr);
02438 return 0;
02439 }
02440 val = user->s.value;
02441 } else if (expr->attr & CEXPR_ROLE) {
02442 if (!is_id_in_scope(SYM_ROLES, id)) {
02443 yyerror2("role %s is not within scope", id);
02444 constraint_expr_destroy(expr);
02445 return 0;
02446 }
02447 role = (role_datum_t *) hashtab_search(policydbp->p_roles.table, (hashtab_key_t)
02448 id);
02449 if (!role) {
02450 yyerror2("unknown role %s", id);
02451 constraint_expr_destroy(expr);
02452 return 0;
02453 }
02454 val = role->s.value;
02455 } else if (expr->attr & CEXPR_TYPE) {
02456 if (set_types(expr->type_names, id, &add, 0)) {
02457 constraint_expr_destroy(expr);
02458 return 0;
02459 }
02460 continue;
02461 } else {
02462 yyerror("invalid constraint expression");
02463 constraint_expr_destroy(expr);
02464 return 0;
02465 }
02466 if (ebitmap_set_bit(&expr->names, val - 1, TRUE)) {
02467 yyerror("out of memory");
02468 ebitmap_destroy(&expr->names);
02469 constraint_expr_destroy(expr);
02470 return 0;
02471 }
02472 free(id);
02473 }
02474 ebitmap_destroy(&negset);
02475 return (uintptr_t) expr;
02476 default:
02477 yyerror("invalid constraint expression");
02478 constraint_expr_destroy(expr);
02479 return 0;
02480 }
02481
02482 yyerror("invalid constraint expression");
02483 free(expr);
02484 return 0;
02485 }
02486
02487 int define_conditional(cond_expr_t * expr, avrule_t * t, avrule_t * f)
02488 {
02489 cond_expr_t *e;
02490 int depth, retval;
02491 cond_node_t cn, *cn_old;
02492 avrule_t *tmp, *last_tmp;
02493
02494
02495 if (!expr) {
02496 yyerror("illegal conditional expression");
02497 return -1;
02498 }
02499 if (!t) {
02500 if (!f) {
02501
02502 cond_expr_destroy(expr);
02503 return 0;
02504 }
02505
02506 t = f;
02507 f = 0;
02508 expr = define_cond_expr(COND_NOT, expr, 0);
02509 if (!expr) {
02510 yyerror("unable to invert");
02511 return -1;
02512 }
02513 }
02514
02515
02516 depth = -1;
02517 for (e = expr; e; e = e->next) {
02518 switch (e->expr_type) {
02519 case COND_NOT:
02520 if (depth < 0) {
02521 yyerror("illegal conditional expression; Bad NOT");
02522 return -1;
02523 }
02524 break;
02525 case COND_AND:
02526 case COND_OR:
02527 case COND_XOR:
02528 case COND_EQ:
02529 case COND_NEQ:
02530 if (depth < 1) {
02531 yyerror("illegal conditional expression; Bad binary op");
02532 return -1;
02533 }
02534 depth--;
02535 break;
02536 case COND_BOOL:
02537 if (depth == (COND_EXPR_MAXDEPTH - 1)) {
02538 yyerror("conditional expression is like totally too deep");
02539 return -1;
02540 }
02541 depth++;
02542 break;
02543 default:
02544 yyerror("illegal conditional expression");
02545 return -1;
02546 }
02547 }
02548 if (depth != 0) {
02549 yyerror("illegal conditional expression");
02550 return -1;
02551 }
02552
02553
02554 memset(&cn, 0, sizeof(cn));
02555 cn.expr = expr;
02556 cn.avtrue_list = t;
02557 cn.avfalse_list = f;
02558
02559
02560 if (cond_normalize_expr(policydbp, &cn) < 0) {
02561 yyerror("problem normalizing conditional expression");
02562 return -1;
02563 }
02564
02565
02566 cn_old = get_current_cond_list(&cn);
02567 if (!cn_old) {
02568 return -1;
02569 }
02570
02571
02572 tmp = cn.avtrue_list;
02573 last_tmp = NULL;
02574 while (tmp) {
02575 if (!tmp->specified & AVRULE_TRANSITION)
02576 continue;
02577 retval = insert_check_type_rule(tmp, &policydbp->te_cond_avtab, &cn_old->true_list, &cn_old->false_list);
02578 switch (retval) {
02579 case 1:{
02580 last_tmp = tmp;
02581 tmp = tmp->next;
02582 break;
02583 }
02584 case 0:{
02585
02586 if (last_tmp == NULL) {
02587 cn.avtrue_list = cn.avtrue_list->next;
02588 avrule_destroy(tmp);
02589 free(tmp);
02590 tmp = cn.avtrue_list;
02591 } else {
02592 last_tmp->next = tmp->next;
02593 avrule_destroy(tmp);
02594 free(tmp);
02595 tmp = last_tmp->next;
02596 }
02597 break;
02598 }
02599 case -1:{
02600 return -1;
02601 }
02602 case 2:{
02603 return 0;
02604 }
02605 default:{
02606 assert(0);
02607 }
02608 }
02609 }
02610
02611 tmp = cn.avfalse_list;
02612 last_tmp = NULL;
02613 while (tmp) {
02614 if (!tmp->specified & AVRULE_TRANSITION)
02615 continue;
02616 retval = insert_check_type_rule(tmp, &policydbp->te_cond_avtab, &cn_old->false_list, &cn_old->true_list);
02617 switch (retval) {
02618 case 1:{
02619 last_tmp = tmp;
02620 tmp = tmp->next;
02621 break;
02622 }
02623 case 0:{
02624
02625 if (last_tmp == NULL) {
02626 cn.avfalse_list = cn.avfalse_list->next;
02627 avrule_destroy(tmp);
02628 free(tmp);
02629 tmp = cn.avfalse_list;
02630 } else {
02631 last_tmp->next = tmp->next;
02632 avrule_destroy(tmp);
02633 free(tmp);
02634 tmp = last_tmp->next;
02635 }
02636 break;
02637 }
02638 case -1:{
02639 return -1;
02640 }
02641 case 2:{
02642 return 0;
02643 }
02644 default:{
02645 assert(0);
02646 }
02647 }
02648 }
02649
02650 append_cond_list(&cn);
02651
02652
02653
02654
02655
02656 cn.avtrue_list = NULL;
02657 cn.avfalse_list = NULL;
02658 cond_node_destroy(&cn);
02659
02660 return 0;
02661 }
02662
02663 cond_expr_t *define_cond_expr(uint32_t expr_type, void *arg1, void *arg2)
02664 {
02665 struct cond_expr *expr, *e1 = NULL, *e2;
02666 cond_bool_datum_t *bool_var;
02667 char *id;
02668
02669
02670 if (pass == 1) {
02671 if (expr_type == COND_BOOL) {
02672 while ((id = queue_remove(id_queue))) {
02673 free(id);
02674 }
02675 }
02676 return (cond_expr_t *) 1;
02677 }
02678
02679
02680 expr = malloc(sizeof(struct cond_expr));
02681 if (!expr) {
02682 yyerror("out of memory");
02683 return NULL;
02684 }
02685 memset(expr, 0, sizeof(cond_expr_t));
02686 expr->expr_type = expr_type;
02687
02688
02689 switch (expr_type) {
02690 case COND_NOT:
02691 e1 = NULL;
02692 e2 = (struct cond_expr *)arg1;
02693 while (e2) {
02694 e1 = e2;
02695 e2 = e2->next;
02696 }
02697 if (!e1 || e1->next) {
02698 yyerror("illegal conditional NOT expression");
02699 free(expr);
02700 return NULL;
02701 }
02702 e1->next = expr;
02703 return (struct cond_expr *)arg1;
02704 case COND_AND:
02705 case COND_OR:
02706 case COND_XOR:
02707 case COND_EQ:
02708 case COND_NEQ:
02709 e1 = NULL;
02710 e2 = (struct cond_expr *)arg1;
02711 while (e2) {
02712 e1 = e2;
02713 e2 = e2->next;
02714 }
02715 if (!e1 || e1->next) {
02716 yyerror("illegal left side of conditional binary op expression");
02717 free(expr);
02718 return NULL;
02719 }
02720 e1->next = (struct cond_expr *)arg2;
02721
02722 e1 = NULL;
02723 e2 = (struct cond_expr *)arg2;
02724 while (e2) {
02725 e1 = e2;
02726 e2 = e2->next;
02727 }
02728 if (!e1 || e1->next) {
02729 yyerror("illegal right side of conditional binary op expression");
02730 free(expr);
02731 return NULL;
02732 }
02733 e1->next = expr;
02734 return (struct cond_expr *)arg1;
02735 case COND_BOOL:
02736 id = (char *)queue_remove(id_queue);
02737 if (!id) {
02738 yyerror("bad conditional; expected boolean id");
02739 free(id);
02740 free(expr);
02741 return NULL;
02742 }
02743 if (!is_id_in_scope(SYM_BOOLS, id)) {
02744 yyerror2("boolean %s is not within scope", id);
02745 free(id);
02746 free(expr);
02747 return NULL;
02748 }
02749 bool_var = (cond_bool_datum_t *) hashtab_search(policydbp->p_bools.table, (hashtab_key_t) id);
02750 if (!bool_var) {
02751 yyerror2("unknown boolean %s in conditional expression", id);
02752 free(expr);
02753 free(id);
02754 return NULL;
02755 }
02756 expr->bool = bool_var->s.value;
02757 free(id);
02758 return expr;
02759 default:
02760 yyerror("illegal conditional expression");
02761 return NULL;
02762 }
02763 }
02764
02765 static int set_user_roles(role_set_t * set, char *id)
02766 {
02767 role_datum_t *r;
02768 unsigned int i;
02769 ebitmap_node_t *node;
02770
02771 if (strcmp(id, "*") == 0) {
02772 free(id);
02773 yyerror("* is not allowed in user declarations");
02774 return -1;
02775 }
02776
02777 if (strcmp(id, "~") == 0) {
02778 free(id);
02779 yyerror("~ is not allowed in user declarations");
02780 return -1;
02781 }
02782
02783 if (!is_id_in_scope(SYM_ROLES, id)) {
02784 yyerror2("role %s is not within scope", id);
02785 free(id);
02786 return -1;
02787 }
02788 r = hashtab_search(policydbp->p_roles.table, id);
02789 if (!r) {
02790 yyerror2("unknown role %s", id);
02791 free(id);
02792 return -1;
02793 }
02794
02795
02796 ebitmap_for_each_bit(&r->dominates, node, i) {
02797 if (ebitmap_node_get_bit(node, i))
02798 if (ebitmap_set_bit(&set->roles, i, TRUE))
02799 goto oom;
02800 }
02801 free(id);
02802 return 0;
02803 oom:
02804 yyerror("out of memory");
02805 return -1;
02806 }
02807
02808 static int parse_categories(char *id, level_datum_t * levdatum, ebitmap_t * cats)
02809 {
02810 cat_datum_t *cdatum;
02811 int range_start, range_end, i;
02812
02813 if (id_has_dot(id)) {
02814 char *id_start = id;
02815 char *id_end = strchr(id, '.');
02816
02817 *(id_end++) = '\0';
02818
02819 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, (hashtab_key_t)
02820 id_start);
02821 if (!cdatum) {
02822 yyerror2("unknown category %s", id_start);
02823 return -1;
02824 }
02825 range_start = cdatum->s.value - 1;
02826 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, (hashtab_key_t) id_end);
02827 if (!cdatum) {
02828 yyerror2("unknown category %s", id_end);
02829 return -1;
02830 }
02831 range_end = cdatum->s.value - 1;
02832
02833 if (range_end < range_start) {
02834 yyerror2("category range is invalid");
02835 return -1;
02836 }
02837 } else {
02838 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, (hashtab_key_t) id);
02839 if (!cdatum) {
02840 yyerror2("unknown category %s", id);
02841 return -1;
02842 }
02843 range_start = range_end = cdatum->s.value - 1;
02844 }
02845
02846 for (i = range_start; i <= range_end; i++) {
02847 if (!ebitmap_get_bit(&levdatum->level->cat, i)) {
02848 uint32_t level_value = levdatum->level->sens - 1;
02849 policydb_index_others(NULL, policydbp, 0);
02850 yyerror2("category %s can not be associated "
02851 "with level %s", policydbp->p_cat_val_to_name[i], policydbp->p_sens_val_to_name[level_value]);
02852 return -1;
02853 }
02854 if (ebitmap_set_bit(cats, i, TRUE)) {
02855 yyerror("out of memory");
02856 return -1;
02857 }
02858 }
02859
02860 return 0;
02861 }
02862
02863 static int parse_semantic_categories(char *id, level_datum_t * levdatum, mls_semantic_cat_t ** cats)
02864 {
02865 cat_datum_t *cdatum;
02866 mls_semantic_cat_t *newcat;
02867 unsigned int range_start, range_end;
02868
02869 if (id_has_dot(id)) {
02870 char *id_start = id;
02871 char *id_end = strchr(id, '.');
02872
02873 *(id_end++) = '\0';
02874
02875 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, (hashtab_key_t)
02876 id_start);
02877 if (!cdatum) {
02878 yyerror2("unknown category %s", id_start);
02879 return -1;
02880 }
02881 range_start = cdatum->s.value;
02882
02883 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, (hashtab_key_t) id_end);
02884 if (!cdatum) {
02885 yyerror2("unknown category %s", id_end);
02886 return -1;
02887 }
02888 range_end = cdatum->s.value;
02889 } else {
02890 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, (hashtab_key_t) id);
02891 if (!cdatum) {
02892 yyerror2("unknown category %s", id);
02893 return -1;
02894 }
02895 range_start = range_end = cdatum->s.value;
02896 }
02897
02898 newcat = (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t));
02899 if (!newcat) {
02900 yyerror("out of memory");
02901 return -1;
02902 }
02903
02904 mls_semantic_cat_init(newcat);
02905 newcat->next = *cats;
02906 newcat->low = range_start;
02907 newcat->high = range_end;
02908
02909 *cats = newcat;
02910
02911 return 0;
02912 }
02913
02914 int define_user(void)
02915 {
02916 char *id;
02917 user_datum_t *usrdatum;
02918 level_datum_t *levdatum;
02919 int l;
02920
02921 if (pass == 1) {
02922 while ((id = queue_remove(id_queue)))
02923 free(id);
02924 if (mlspol) {
02925 while ((id = queue_remove(id_queue)))
02926 free(id);
02927 id = queue_remove(id_queue);
02928 free(id);
02929 for (l = 0; l < 2; l++) {
02930 while ((id = queue_remove(id_queue))) {
02931 free(id);
02932 }
02933 id = queue_remove(id_queue);
02934 if (!id)
02935 break;
02936 free(id);
02937 }
02938 }
02939 return 0;
02940 }
02941
02942 if ((usrdatum = declare_user()) == NULL) {
02943 return -1;
02944 }
02945
02946 while ((id = queue_remove(id_queue))) {
02947 if (set_user_roles(&usrdatum->roles, id))
02948 continue;
02949 }
02950
02951 if (mlspol) {
02952 id = queue_remove(id_queue);
02953 if (!id) {
02954 yyerror("no default level specified for user");
02955 return -1;
02956 }
02957
02958 levdatum = (level_datum_t *)
02959 hashtab_search(policydbp->p_levels.table, (hashtab_key_t) id);
02960 if (!levdatum) {
02961 yyerror2("unknown sensitivity %s used in user" " level definition", id);
02962 free(id);
02963 return -1;
02964 }
02965 free(id);
02966
02967 usrdatum->dfltlevel.sens = levdatum->level->sens;
02968
02969 while ((id = queue_remove(id_queue))) {
02970 if (parse_semantic_categories(id, levdatum, &usrdatum->dfltlevel.cat)) {
02971 free(id);
02972 return -1;
02973 }
02974 free(id);
02975 }
02976
02977 id = queue_remove(id_queue);
02978
02979 for (l = 0; l < 2; l++) {
02980 levdatum = (level_datum_t *)
02981 hashtab_search(policydbp->p_levels.table, (hashtab_key_t) id);
02982 if (!levdatum) {
02983 yyerror2("unknown sensitivity %s used in user" " range definition", id);
02984 free(id);
02985 return -1;
02986 }
02987 free(id);
02988
02989 usrdatum->range.level[l].sens = levdatum->level->sens;
02990
02991 while ((id = queue_remove(id_queue))) {
02992 if (parse_semantic_categories(id, levdatum, &usrdatum->range.level[l].cat)) {
02993 free(id);
02994 return -1;
02995 }
02996 free(id);
02997 }
02998
02999 id = queue_remove(id_queue);
03000 if (!id)
03001 break;
03002 }
03003
03004 if (l == 0) {
03005 if (mls_semantic_level_cpy(&usrdatum->range.level[1], &usrdatum->range.level[0])) {
03006 yyerror("out of memory");
03007 return -1;
03008 }
03009 }
03010 }
03011 return 0;
03012 }
03013
03014 static int parse_security_context(context_struct_t * c)
03015 {
03016 char *id;
03017 role_datum_t *role;
03018 type_datum_t *typdatum;
03019 user_datum_t *usrdatum;
03020 level_datum_t *levdatum;
03021 int l;
03022
03023 if (pass == 1) {
03024 id = queue_remove(id_queue);
03025 free(id);
03026 id = queue_remove(id_queue);
03027 free(id);
03028 id = queue_remove(id_queue);
03029 free(id);
03030 if (mlspol) {
03031 id = queue_remove(id_queue);
03032 free(id);
03033 for (l = 0; l < 2; l++) {
03034 while ((id = queue_remove(id_queue))) {
03035 free(id);
03036 }
03037 id = queue_remove(id_queue);
03038 if (!id)
03039 break;
03040 free(id);
03041 }
03042 }
03043 return 0;
03044 }
03045
03046 context_init(c);
03047
03048
03049 id = queue_remove(id_queue);
03050 if (!id) {
03051 yyerror("no effective user?");
03052 goto bad;
03053 }
03054 if (!is_id_in_scope(SYM_USERS, id)) {
03055 yyerror2("user %s is not within scope", id);
03056 free(id);
03057 goto bad;
03058 }
03059 usrdatum = (user_datum_t *) hashtab_search(policydbp->p_users.table, (hashtab_key_t) id);
03060 if (!usrdatum) {
03061 yyerror2("user %s is not defined", id);
03062 free(id);
03063 goto bad;
03064 }
03065 c->user = usrdatum->s.value;
03066
03067
03068 free(id);
03069
03070
03071 id = (char *)queue_remove(id_queue);
03072 if (!id) {
03073 yyerror("no role name for sid context definition?");
03074 return -1;
03075 }
03076 if (!is_id_in_scope(SYM_ROLES, id)) {
03077 yyerror2("role %s is not within scope", id);
03078 free(id);
03079 return -1;
03080 }
03081 role = (role_datum_t *) hashtab_search(policydbp->p_roles.table, (hashtab_key_t) id);
03082 if (!role) {
03083 yyerror2("role %s is not defined", id);
03084 free(id);
03085 return -1;
03086 }
03087 c->role = role->s.value;
03088
03089
03090 free(id);
03091
03092
03093 id = (char *)queue_remove(id_queue);
03094 if (!id) {
03095 yyerror("no type name for sid context definition?");
03096 return -1;
03097 }
03098 if (!is_id_in_scope(SYM_TYPES, id)) {
03099 yyerror2("type %s is not within scope", id);
03100 free(id);
03101 return -1;
03102 }
03103 typdatum = (type_datum_t *) hashtab_search(policydbp->p_types.table, (hashtab_key_t) id);
03104 if (!typdatum || typdatum->flavor == TYPE_ATTRIB) {
03105 yyerror2("type %s is not defined or is an attribute", id);
03106 free(id);
03107 return -1;
03108 }
03109 c->type = typdatum->s.value;
03110
03111
03112 free(id);
03113
03114 if (mlspol) {
03115
03116 id = (char *)queue_head(id_queue);
03117 if (!id) {
03118 yyerror("no sensitivity name for sid context" " definition?");
03119 return -1;
03120 }
03121
03122 id = (char *)queue_remove(id_queue);
03123 for (l = 0; l < 2; l++) {
03124 levdatum = (level_datum_t *)
03125 hashtab_search(policydbp->p_levels.table, (hashtab_key_t) id);
03126 if (!levdatum) {
03127 yyerror2("Sensitivity %s is not defined", id);
03128 free(id);
03129 return -1;
03130 }
03131 free(id);
03132 c->range.level[l].sens = levdatum->level->sens;
03133
03134
03135 while ((id = queue_remove(id_queue))) {
03136 if (parse_categories(id, levdatum, &c->range.level[l].cat)) {
03137 free(id);
03138 return -1;
03139 }
03140 free(id);
03141 }
03142
03143
03144 id = (char *)queue_remove(id_queue);
03145 if (!id)
03146 break;
03147 }
03148
03149 if (l == 0) {
03150 c->range.level[1].sens = c->range.level[0].sens;
03151 if (ebitmap_cpy(&c->range.level[1].cat, &c->range.level[0].cat)) {
03152
03153 yyerror("out of memory");
03154 goto bad;
03155 }
03156 }
03157 }
03158
03159 if (!policydb_context_isvalid(policydbp, c)) {
03160 yyerror("invalid security context");
03161 goto bad;
03162 }
03163 return 0;
03164
03165 bad:
03166 context_destroy(c);
03167
03168 return -1;
03169 }
03170
03171 int define_initial_sid_context(void)
03172 {
03173 char *id;
03174 ocontext_t *c, *head;
03175
03176 if (pass == 1) {
03177 id = (char *)queue_remove(id_queue);
03178 free(id);
03179 parse_security_context(NULL);
03180 return 0;
03181 }
03182
03183 id = (char *)queue_remove(id_queue);
03184 if (!id) {
03185 yyerror("no sid name for SID context definition?");
03186 return -1;
03187 }
03188 head = policydbp->ocontexts[OCON_ISID];
03189 for (c = head; c; c = c->next) {
03190 if (!strcmp(id, c->u.name))
03191 break;
03192 }
03193
03194 if (!c) {
03195 yyerror2("SID %s is not defined", id);
03196 free(id);
03197 return -1;
03198 }
03199 if (c->context[0].user) {
03200 yyerror2("The context for SID %s is multiply defined", id);
03201 free(id);
03202 return -1;
03203 }
03204
03205 free(id);
03206
03207 if (parse_security_context(&c->context[0]))
03208 return -1;
03209
03210 return 0;
03211 }
03212
03213 int define_fs_context(unsigned int major, unsigned int minor)
03214 {
03215 ocontext_t *newc, *c, *head;
03216
03217 if (pass == 1) {
03218 parse_security_context(NULL);
03219 parse_security_context(NULL);
03220 return 0;
03221 }
03222
03223 newc = (ocontext_t *) malloc(sizeof(ocontext_t));
03224 if (!newc) {
03225 yyerror("out of memory");
03226 return -1;
03227 }
03228 memset(newc, 0, sizeof(ocontext_t));
03229
03230 newc->u.name = (char *)malloc(6);
03231 if (!newc->u.name) {
03232 yyerror("out of memory");
03233 free(newc);
03234 return -1;
03235 }
03236 sprintf(newc->u.name, "%02x:%02x", major, minor);
03237
03238 if (parse_security_context(&newc->context[0])) {
03239 free(newc->u.name);
03240 free(newc);
03241 return -1;
03242 }
03243 if (parse_security_context(&newc->context[1])) {
03244 context_destroy(&newc->context[0]);
03245 free(newc->u.name);
03246 free(newc);
03247 return -1;
03248 }
03249 head = policydbp->ocontexts[OCON_FS];
03250
03251 for (c = head; c; c = c->next) {
03252 if (!strcmp(newc->u.name, c->u.name)) {
03253 yyerror2("duplicate entry for file system %s", newc->u.name);
03254 context_destroy(&newc->context[0]);
03255 context_destroy(&newc->context[1]);
03256 free(newc->u.name);
03257 free(newc);
03258 return -1;
03259 }
03260 }
03261
03262 newc->next = head;
03263 policydbp->ocontexts[OCON_FS] = newc;
03264
03265 return 0;
03266 }
03267
03268 int define_port_context(unsigned int low, unsigned int high)
03269 {
03270 ocontext_t *newc, *c, *l, *head;
03271 unsigned int protocol;
03272 char *id;
03273
03274 if (pass == 1) {
03275 id = (char *)queue_remove(id_queue);
03276 free(id);
03277 parse_security_context(NULL);
03278 return 0;
03279 }
03280
03281 newc = malloc(sizeof(ocontext_t));
03282 if (!newc) {
03283 yyerror("out of memory");
03284 return -1;
03285 }
03286 memset(newc, 0, sizeof(ocontext_t));
03287
03288 id = (char *)queue_remove(id_queue);
03289 if (!id) {
03290 free(newc);
03291 return -1;
03292 }
03293 if ((strcmp(id, "tcp") == 0) || (strcmp(id, "TCP") == 0)) {
03294 protocol = IPPROTO_TCP;
03295 } else if ((strcmp(id, "udp") == 0) || (strcmp(id, "UDP") == 0)) {
03296 protocol = IPPROTO_UDP;
03297 } else {
03298 yyerror2("unrecognized protocol %s", id);
03299 free(newc);
03300 return -1;
03301 }
03302
03303 newc->u.port.protocol = protocol;
03304 newc->u.port.low_port = low;
03305 newc->u.port.high_port = high;
03306
03307 if (low > high) {
03308 yyerror2("low port %d exceeds high port %d", low, high);
03309 free(newc);
03310 return -1;
03311 }
03312
03313 if (parse_security_context(&newc->context[0])) {
03314 free(newc);
03315 return -1;
03316 }
03317
03318
03319 head = policydbp->ocontexts[OCON_PORT];
03320 for (l = NULL, c = head; c; l = c, c = c->next) {
03321 unsigned int prot2, low2, high2;
03322
03323 prot2 = c->u.port.protocol;
03324 low2 = c->u.port.low_port;
03325 high2 = c->u.port.high_port;
03326 if (protocol != prot2)
03327 continue;
03328 if (low == low2 && high == high2) {
03329 yyerror2("duplicate portcon entry for %s %d-%d ", id, low, high);
03330 goto bad;
03331 }
03332 if (low2 <= low && high2 >= high) {
03333 yyerror2("portcon entry for %s %d-%d hidden by earlier " "entry for %d-%d", id, low, high, low2, high2);
03334 goto bad;
03335 }
03336 }
03337 free(id);
03338
03339 if (l)
03340 l->next = newc;
03341 else
03342 policydbp->ocontexts[OCON_PORT] = newc;
03343
03344 return 0;
03345
03346 bad:
03347 free(newc);
03348 return -1;
03349 }
03350
03351 int define_netif_context(void)
03352 {
03353 ocontext_t *newc, *c, *head;
03354
03355 if (pass == 1) {
03356 free(queue_remove(id_queue));
03357 parse_security_context(NULL);
03358 parse_security_context(NULL);
03359 return 0;
03360 }
03361
03362 newc = (ocontext_t *) malloc(sizeof(ocontext_t));
03363 if (!newc) {
03364 yyerror("out of memory");
03365 return -1;
03366 }
03367 memset(newc, 0, sizeof(ocontext_t));
03368
03369 newc->u.name = (char *)queue_remove(id_queue);
03370 if (!newc->u.name) {
03371 free(newc);
03372 return -1;
03373 }
03374 if (parse_security_context(&newc->context[0])) {
03375 free(newc->u.name);
03376 free(newc);
03377 return -1;
03378 }
03379 if (parse_security_context(&newc->context[1])) {
03380 context_destroy(&newc->context[0]);
03381 free(newc->u.name);
03382 free(newc);
03383 return -1;
03384 }
03385 head = policydbp->ocontexts[OCON_NETIF];
03386
03387 for (c = head; c; c = c->next) {
03388 if (!strcmp(newc->u.name, c->u.name)) {
03389 yyerror2("duplicate entry for network interface %s", newc->u.name);
03390 context_destroy(&newc->context[0]);
03391 context_destroy(&newc->context[1]);
03392 free(newc->u.name);
03393 free(newc);
03394 return -1;
03395 }
03396 }
03397
03398 newc->next = head;
03399 policydbp->ocontexts[OCON_NETIF] = newc;
03400 return 0;
03401 }
03402
03403 int define_ipv4_node_context()
03404 {
03405 char *id;
03406 int rc = 0;
03407 struct in_addr addr, mask;
03408 ocontext_t *newc, *c, *l, *head;
03409
03410 if (pass == 1) {
03411 free(queue_remove(id_queue));
03412 free(queue_remove(id_queue));
03413 parse_security_context(NULL);
03414 goto out;
03415 }
03416
03417 id = queue_remove(id_queue);
03418 if (!id) {
03419 yyerror("failed to read ipv4 address");
03420 rc = -1;
03421 goto out;
03422 }
03423
03424 rc = inet_pton(AF_INET, id, &addr);
03425 free(id);
03426 if (rc < 1) {
03427 yyerror("failed to parse ipv4 address");
03428 if (rc == 0)
03429 rc = -1;
03430 goto out;
03431 }
03432
03433 id = queue_remove(id_queue);
03434 if (!id) {
03435 yyerror("failed to read ipv4 address");
03436 rc = -1;
03437 goto out;
03438 }
03439
03440 rc = inet_pton(AF_INET, id, &mask);
03441 free(id);
03442 if (rc < 1) {
03443 yyerror("failed to parse ipv4 mask");
03444 if (rc == 0)
03445 rc = -1;
03446 goto out;
03447 }
03448
03449 newc = malloc(sizeof(ocontext_t));
03450 if (!newc) {
03451 yyerror("out of memory");
03452 rc = -1;
03453 goto out;
03454 }
03455
03456 memset(newc, 0, sizeof(ocontext_t));
03457 newc->u.node.addr = addr.s_addr;
03458 newc->u.node.mask = mask.s_addr;
03459
03460 if (parse_security_context(&newc->context[0])) {
03461 free(newc);
03462 return -1;
03463 }
03464
03465
03466
03467 head = policydbp->ocontexts[OCON_NODE];
03468 for (l = NULL, c = head; c; l = c, c = c->next) {
03469 if (newc->u.node.mask > c->u.node.mask)
03470 break;
03471 }
03472
03473 newc->next = c;
03474
03475 if (l)
03476 l->next = newc;
03477 else
03478 policydbp->ocontexts[OCON_NODE] = newc;
03479 rc = 0;
03480 out:
03481 return rc;
03482 }
03483
03484 int define_ipv6_node_context(void)
03485 {
03486 char *id;
03487 int rc = 0;
03488 struct in6_addr addr, mask;
03489 ocontext_t *newc, *c, *l, *head;
03490
03491 if (pass == 1) {
03492 free(queue_remove(id_queue));
03493 free(queue_remove(id_queue));
03494 parse_security_context(NULL);
03495 goto out;
03496 }
03497
03498 id = queue_remove(id_queue);
03499 if (!id) {
03500 yyerror("failed to read ipv6 address");
03501 rc = -1;
03502 goto out;
03503 }
03504
03505 rc = inet_pton(AF_INET6, id, &addr);
03506 free(id);
03507 if (rc < 1) {
03508 yyerror("failed to parse ipv6 address");
03509 if (rc == 0)
03510 rc = -1;
03511 goto out;
03512 }
03513
03514 id = queue_remove(id_queue);
03515 if (!id) {
03516 yyerror("failed to read ipv6 address");
03517 rc = -1;
03518 goto out;
03519 }
03520
03521 rc = inet_pton(AF_INET6, id, &mask);
03522 free(id);
03523 if (rc < 1) {
03524 yyerror("failed to parse ipv6 mask");
03525 if (rc == 0)
03526 rc = -1;
03527 goto out;
03528 }
03529
03530 newc = malloc(sizeof(ocontext_t));
03531 if (!newc) {
03532 yyerror("out of memory");
03533 rc = -1;
03534 goto out;
03535 }
03536
03537 memset(newc, 0, sizeof(ocontext_t));
03538 memcpy(&newc->u.node6.addr[0], &addr.s6_addr32[0], 16);
03539 memcpy(&newc->u.node6.mask[0], &mask.s6_addr32[0], 16);
03540
03541 if (parse_security_context(&newc->context[0])) {
03542 free(newc);
03543 rc = -1;
03544 goto out;
03545 }
03546
03547
03548
03549 head = policydbp->ocontexts[OCON_NODE6];
03550 for (l = NULL, c = head; c; l = c, c = c->next) {
03551 if (memcmp(&newc->u.node6.mask, &c->u.node6.mask, 16) > 0)
03552 break;
03553 }
03554
03555 newc->next = c;
03556
03557 if (l)
03558 l->next = newc;
03559 else
03560 policydbp->ocontexts[OCON_NODE6] = newc;
03561
03562 rc = 0;
03563 out:
03564 return rc;
03565 }
03566
03567 int define_fs_use(int behavior)
03568 {
03569 ocontext_t *newc, *c, *head;
03570
03571 if (pass == 1) {
03572 free(queue_remove(id_queue));
03573 if (behavior != SECURITY_FS_USE_PSIDS)
03574 parse_security_context(NULL);
03575 return 0;
03576 }
03577
03578 newc = (ocontext_t *) malloc(sizeof(ocontext_t));
03579 if (!newc) {
03580 yyerror("out of memory");
03581 return -1;
03582 }
03583 memset(newc, 0, sizeof(ocontext_t));
03584
03585 newc->u.name = (char *)queue_remove(id_queue);
03586 if (!newc->u.name) {
03587 free(newc);
03588 return -1;
03589 }
03590 newc->v.behavior = behavior;
03591 if (newc->v.behavior != SECURITY_FS_USE_PSIDS) {
03592 if (parse_security_context(&newc->context[0])) {
03593 free(newc->u.name);
03594 free(newc);
03595 return -1;
03596 }
03597 } else
03598 memset(&newc->context[0], 0, sizeof(context_struct_t) * 2);
03599
03600 head = policydbp->ocontexts[OCON_FSUSE];
03601
03602 for (c = head; c; c = c->next) {
03603 if (!strcmp(newc->u.name, c->u.name)) {
03604 yyerror2("duplicate fs_use entry for filesystem type %s", newc->u.name);
03605 context_destroy(&newc->context[0]);
03606 free(newc->u.name);
03607 free(newc);
03608 return -1;
03609 }
03610 }
03611
03612 newc->next = head;
03613 policydbp->ocontexts[OCON_FSUSE] = newc;
03614 return 0;
03615 }
03616
03617 int define_genfs_context_helper(char *fstype, int has_type)
03618 {
03619 struct genfs *genfs_p, *genfs, *newgenfs;
03620 ocontext_t *newc, *c, *head, *p;
03621 char *type = NULL;
03622 int len, len2;
03623
03624 if (pass == 1) {
03625 free(fstype);
03626 free(queue_remove(id_queue));
03627 if (has_type)
03628 free(queue_remove(id_queue));
03629 parse_security_context(NULL);
03630 return 0;
03631 }
03632
03633 for (genfs_p = NULL, genfs = policydbp->genfs; genfs; genfs_p = genfs, genfs = genfs->next) {
03634 if (strcmp(fstype, genfs->fstype) <= 0)
03635 break;
03636 }
03637
03638 if (!genfs || strcmp(fstype, genfs->fstype)) {
03639 newgenfs = malloc(sizeof(struct genfs));
03640 if (!newgenfs) {
03641 yyerror("out of memory");
03642 return -1;
03643 }
03644 memset(newgenfs, 0, sizeof(struct genfs));
03645 newgenfs->fstype = fstype;
03646 newgenfs->next = genfs;
03647 if (genfs_p)
03648 genfs_p->next = newgenfs;
03649 else
03650 policydbp->genfs = newgenfs;
03651 genfs = newgenfs;
03652 } else {
03653 free(fstype);
03654 }
03655
03656 newc = (ocontext_t *) malloc(sizeof(ocontext_t));
03657 if (!newc) {
03658 yyerror("out of memory");
03659 return -1;
03660 }
03661 memset(newc, 0, sizeof(ocontext_t));
03662
03663 newc->u.name = (char *)queue_remove(id_queue);
03664 if (!newc->u.name)
03665 goto fail;
03666 if (has_type) {
03667 type = (char *)queue_remove(id_queue);
03668 if (!type)
03669 goto fail;
03670 if (type[1] != 0) {
03671 yyerror2("invalid type %s", type);
03672 goto fail;
03673 }
03674 switch (type[0]) {
03675 case 'b':
03676 newc->v.sclass = SECCLASS_BLK_FILE;
03677 break;
03678 case 'c':
03679 newc->v.sclass = SECCLASS_CHR_FILE;
03680 break;
03681 case 'd':
03682 newc->v.sclass = SECCLASS_DIR;
03683 break;
03684 case 'p':
03685 newc->v.sclass = SECCLASS_FIFO_FILE;
03686 break;
03687 case 'l':
03688 newc->v.sclass = SECCLASS_LNK_FILE;
03689 break;
03690 case 's':
03691 newc->v.sclass = SECCLASS_SOCK_FILE;
03692 break;
03693 case '-':
03694 newc->v.sclass = SECCLASS_FILE;
03695 break;
03696 default:
03697 yyerror2("invalid type %s", type);
03698 goto fail;
03699 }
03700 }
03701 free(type);
03702 type = NULL;
03703 if (parse_security_context(&newc->context[0]))
03704 goto fail;
03705
03706 head = genfs->head;
03707
03708 for (p = NULL, c = head; c; p = c, c = c->next) {
03709 if (!strcmp(newc->u.name, c->u.name) && (!newc->v.sclass || !c->v.sclass || newc->v.sclass == c->v.sclass)) {
03710 yyerror2("duplicate entry for genfs entry (%s, %s)", fstype, newc->u.name);
03711 goto fail;
03712 }
03713 len = strlen(newc->u.name);
03714 len2 = strlen(c->u.name);
03715 if (len > len2)
03716 break;
03717 }
03718
03719 newc->next = c;
03720 if (p)
03721 p->next = newc;
03722 else
03723 genfs->head = newc;
03724 return 0;
03725 fail:
03726 if (type)
03727 free(type);
03728 context_destroy(&newc->context[0]);
03729 if (fstype)
03730 free(fstype);
03731 if (newc->u.name)
03732 free(newc->u.name);
03733 free(newc);
03734 return -1;
03735 }
03736
03737 int define_genfs_context(int has_type)
03738 {
03739 return define_genfs_context_helper(queue_remove(id_queue), has_type);
03740 }
03741
03742 int define_range_trans(int class_specified)
03743 {
03744 char *id;
03745 level_datum_t *levdatum = 0;
03746 class_datum_t *cladatum;
03747 range_trans_rule_t *rule;
03748 int l, add = 1;
03749
03750 if (!mlspol) {
03751 yyerror("range_transition rule in non-MLS configuration");
03752 return -1;
03753 }
03754
03755 if (pass == 1) {
03756 while ((id = queue_remove(id_queue)))
03757 free(id);
03758 while ((id = queue_remove(id_queue)))
03759 free(id);
03760 if (class_specified)
03761 while ((id = queue_remove(id_queue)))
03762 free(id);
03763 id = queue_remove(id_queue);
03764 free(id);
03765 for (l = 0; l < 2; l++) {
03766 while ((id = queue_remove(id_queue))) {
03767 free(id);
03768 }
03769 id = queue_remove(id_queue);
03770 if (!id)
03771 break;
03772 free(id);
03773 }
03774 return 0;
03775 }
03776
03777 rule = malloc(sizeof(struct range_trans_rule));
03778 if (!rule) {
03779 yyerror("out of memory");
03780 return -1;
03781 }
03782 range_trans_rule_init(rule);
03783
03784 while ((id = queue_remove(id_queue))) {
03785 if (set_types(&rule->stypes, id, &add, 0))
03786 goto out;
03787 }
03788 add = 1;
03789 while ((id = queue_remove(id_queue))) {
03790 if (set_types(&rule->ttypes, id, &add, 0))
03791 goto out;
03792 }
03793
03794 if (class_specified) {
03795 while ((id = queue_remove(id_queue))) {
03796 if (!is_id_in_scope(SYM_CLASSES, id)) {
03797 yyerror2("class %s is not within scope", id);
03798 free(id);
03799 goto out;
03800 }
03801 cladatum = hashtab_search(policydbp->p_classes.table, id);
03802 if (!cladatum) {
03803 yyerror2("unknown class %s", id);
03804 goto out;
03805 }
03806
03807 ebitmap_set_bit(&rule->tclasses, cladatum->s.value - 1, TRUE);
03808 free(id);
03809 }
03810 } else {
03811 cladatum = hashtab_search(policydbp->p_classes.table, "process");
03812 if (!cladatum) {
03813 yyerror2("could not find process class for " "legacy range_transition statement");
03814 goto out;
03815 }
03816
03817 ebitmap_set_bit(&rule->tclasses, cladatum->s.value - 1, TRUE);
03818 }
03819
03820 id = (char *)queue_remove(id_queue);
03821 if (!id) {
03822 yyerror("no range in range_transition definition?");
03823 goto out;
03824 }
03825 for (l = 0; l < 2; l++) {
03826 levdatum = hashtab_search(policydbp->p_levels.table, id);
03827 if (!levdatum) {
03828 yyerror2("unknown level %s used in range_transition " "definition", id);
03829 free(id);
03830 goto out;
03831 }
03832 free(id);
03833
03834 rule->trange.level[l].sens = levdatum->level->sens;
03835
03836 while ((id = queue_remove(id_queue))) {
03837 if (parse_semantic_categories(id, levdatum, &rule->trange.level[l].cat)) {
03838 free(id);
03839 goto out;
03840 }
03841 free(id);
03842 }
03843
03844 id = (char *)queue_remove(id_queue);
03845 if (!id)
03846 break;
03847 }
03848 if (l == 0) {
03849 if (mls_semantic_level_cpy(&rule->trange.level[1], &rule->trange.level[0])) {
03850 yyerror("out of memory");
03851 goto out;
03852 }
03853 }
03854
03855 append_range_trans(rule);
03856 return 0;
03857
03858 out:
03859 range_trans_rule_destroy(rule);
03860 return -1;
03861 }
03862
03863