1 /* 2 * Author : Stephen Smalley, <sds (at) epoch.ncsc.mil> 3 */ 4 5 /* 6 * Updated: Trusted Computer Solutions, Inc. <dgoeddel (at) trustedcs.com> 7 * 8 * Support for enhanced MLS infrastructure. 9 * 10 * Updated: David Caplan, <dac (at) tresys.com> 11 * 12 * Added conditional policy language extensions 13 * 14 * Updated: Joshua Brindle <jbrindle (at) tresys.com> 15 * Karl MacMillan <kmacmillan (at) mentalrootkit.com> 16 * Jason Tang <jtang (at) tresys.com> 17 * 18 * Added support for binary policy modules 19 * 20 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. 21 * Copyright (C) 2003 - 2008 Tresys Technology, LLC 22 * Copyright (C) 2007 Red Hat Inc. 23 * This program is free software; you can redistribute it and/or modify 24 * it under the terms of the GNU General Public License as published by 25 * the Free Software Foundation, version 2. 26 */ 27 28 /* FLASK */ 29 30 #include <sys/types.h> 31 #include <assert.h> 32 #include <stdarg.h> 33 #include <stdint.h> 34 #include <stdio.h> 35 #include <stdlib.h> 36 #include <string.h> 37 #include <sys/socket.h> 38 #include <netinet/in.h> 39 #include <arpa/inet.h> 40 #include <stdlib.h> 41 42 #include <sepol/policydb/expand.h> 43 #include <sepol/policydb/policydb.h> 44 #include <sepol/policydb/services.h> 45 #include <sepol/policydb/conditional.h> 46 #include <sepol/policydb/flask.h> 47 #include <sepol/policydb/hierarchy.h> 48 #include <sepol/policydb/polcaps.h> 49 #include "queue.h" 50 #include "checkpolicy.h" 51 #include "module_compiler.h" 52 #include "policy_define.h" 53 54 policydb_t *policydbp; 55 queue_t id_queue = 0; 56 unsigned int pass; 57 char *curfile = 0; 58 int mlspol = 0; 59 60 extern unsigned long policydb_lineno; 61 extern unsigned long source_lineno; 62 extern unsigned int policydb_errors; 63 64 extern int yywarn(char *msg); 65 extern int yyerror(char *msg); 66 67 #define ERRORMSG_LEN 255 68 static char errormsg[ERRORMSG_LEN + 1] = {0}; 69 70 static int id_has_dot(char *id); 71 static int parse_security_context(context_struct_t *c); 72 73 /* initialize all of the state variables for the scanner/parser */ 74 void init_parser(int pass_number) 75 { 76 policydb_lineno = 1; 77 source_lineno = 1; 78 policydb_errors = 0; 79 pass = pass_number; 80 } 81 82 void yyerror2(char *fmt, ...) 83 { 84 va_list ap; 85 va_start(ap, fmt); 86 vsnprintf(errormsg, ERRORMSG_LEN, fmt, ap); 87 yyerror(errormsg); 88 va_end(ap); 89 } 90 91 int insert_separator(int push) 92 { 93 int error; 94 95 if (push) 96 error = queue_push(id_queue, 0); 97 else 98 error = queue_insert(id_queue, 0); 99 100 if (error) { 101 yyerror("queue overflow"); 102 return -1; 103 } 104 return 0; 105 } 106 107 int insert_id(char *id, int push) 108 { 109 char *newid = 0; 110 int error; 111 112 newid = (char *)malloc(strlen(id) + 1); 113 if (!newid) { 114 yyerror("out of memory"); 115 return -1; 116 } 117 strcpy(newid, id); 118 if (push) 119 error = queue_push(id_queue, (queue_element_t) newid); 120 else 121 error = queue_insert(id_queue, (queue_element_t) newid); 122 123 if (error) { 124 yyerror("queue overflow"); 125 free(newid); 126 return -1; 127 } 128 return 0; 129 } 130 131 /* If the identifier has a dot within it and that its first character 132 is not a dot then return 1, else return 0. */ 133 static int id_has_dot(char *id) 134 { 135 if (strchr(id, '.') >= id + 1) { 136 return 1; 137 } 138 return 0; 139 } 140 141 int define_class(void) 142 { 143 char *id = 0; 144 class_datum_t *datum = 0; 145 int ret; 146 uint32_t value; 147 148 if (pass == 2) { 149 id = queue_remove(id_queue); 150 free(id); 151 return 0; 152 } 153 154 id = (char *)queue_remove(id_queue); 155 if (!id) { 156 yyerror("no class name for class definition?"); 157 return -1; 158 } 159 datum = (class_datum_t *) malloc(sizeof(class_datum_t)); 160 if (!datum) { 161 yyerror("out of memory"); 162 goto bad; 163 } 164 memset(datum, 0, sizeof(class_datum_t)); 165 ret = declare_symbol(SYM_CLASSES, id, datum, &value, &value); 166 switch (ret) { 167 case -3:{ 168 yyerror("Out of memory!"); 169 goto bad; 170 } 171 case -2:{ 172 yyerror2("duplicate declaration of class %s", id); 173 goto bad; 174 } 175 case -1:{ 176 yyerror("could not declare class here"); 177 goto bad; 178 } 179 case 0: 180 case 1:{ 181 break; 182 } 183 default:{ 184 assert(0); /* should never get here */ 185 } 186 } 187 datum->s.value = value; 188 return 0; 189 190 bad: 191 if (id) 192 free(id); 193 if (datum) 194 free(datum); 195 return -1; 196 } 197 198 int define_permissive(void) 199 { 200 char *type = NULL; 201 struct type_datum *t; 202 int rc = 0; 203 204 type = queue_remove(id_queue); 205 206 if (!type) { 207 yyerror2("forgot to include type in permissive definition?"); 208 rc = -1; 209 goto out; 210 } 211 212 if (pass == 1) 213 goto out; 214 215 if (!is_id_in_scope(SYM_TYPES, type)) { 216 yyerror2("type %s is not within scope", type); 217 rc = -1; 218 goto out; 219 } 220 221 t = hashtab_search(policydbp->p_types.table, type); 222 if (!t) { 223 yyerror2("type is not defined: %s", type); 224 rc = -1; 225 goto out; 226 } 227 228 if (t->flavor == TYPE_ATTRIB) { 229 yyerror2("attributes may not be permissive: %s\n", type); 230 rc = -1; 231 goto out; 232 } 233 234 t->flags |= TYPE_FLAGS_PERMISSIVE; 235 236 out: 237 free(type); 238 return rc; 239 } 240 241 int define_polcap(void) 242 { 243 char *id = 0; 244 int capnum; 245 246 if (pass == 2) { 247 id = queue_remove(id_queue); 248 free(id); 249 return 0; 250 } 251 252 id = (char *)queue_remove(id_queue); 253 if (!id) { 254 yyerror("no capability name for policycap definition?"); 255 goto bad; 256 } 257 258 /* Check for valid cap name -> number mapping */ 259 capnum = sepol_polcap_getnum(id); 260 if (capnum < 0) { 261 yyerror2("invalid policy capability name %s", id); 262 goto bad; 263 } 264 265 /* Store it */ 266 if (ebitmap_set_bit(&policydbp->policycaps, capnum, TRUE)) { 267 yyerror("out of memory"); 268 goto bad; 269 } 270 271 free(id); 272 return 0; 273 274 bad: 275 free(id); 276 return -1; 277 } 278 279 int define_initial_sid(void) 280 { 281 char *id = 0; 282 ocontext_t *newc = 0, *c, *head; 283 284 if (pass == 2) { 285 id = queue_remove(id_queue); 286 free(id); 287 return 0; 288 } 289 290 id = (char *)queue_remove(id_queue); 291 if (!id) { 292 yyerror("no sid name for SID definition?"); 293 return -1; 294 } 295 newc = (ocontext_t *) malloc(sizeof(ocontext_t)); 296 if (!newc) { 297 yyerror("out of memory"); 298 goto bad; 299 } 300 memset(newc, 0, sizeof(ocontext_t)); 301 newc->u.name = id; 302 context_init(&newc->context[0]); 303 head = policydbp->ocontexts[OCON_ISID]; 304 305 for (c = head; c; c = c->next) { 306 if (!strcmp(newc->u.name, c->u.name)) { 307 yyerror2("duplicate initial SID %s", id); 308 goto bad; 309 } 310 } 311 312 if (head) { 313 newc->sid[0] = head->sid[0] + 1; 314 } else { 315 newc->sid[0] = 1; 316 } 317 newc->next = head; 318 policydbp->ocontexts[OCON_ISID] = newc; 319 320 return 0; 321 322 bad: 323 if (id) 324 free(id); 325 if (newc) 326 free(newc); 327 return -1; 328 } 329 330 static int read_classes(ebitmap_t *e_classes) 331 { 332 char *id; 333 class_datum_t *cladatum; 334 335 while ((id = queue_remove(id_queue))) { 336 if (!is_id_in_scope(SYM_CLASSES, id)) { 337 yyerror2("class %s is not within scope", id); 338 return -1; 339 } 340 cladatum = hashtab_search(policydbp->p_classes.table, id); 341 if (!cladatum) { 342 yyerror2("unknown class %s", id); 343 return -1; 344 } 345 if (ebitmap_set_bit(e_classes, cladatum->s.value - 1, TRUE)) { 346 yyerror("Out of memory"); 347 return -1; 348 } 349 free(id); 350 } 351 return 0; 352 } 353 354 int define_common_perms(void) 355 { 356 char *id = 0, *perm = 0; 357 common_datum_t *comdatum = 0; 358 perm_datum_t *perdatum = 0; 359 int ret; 360 361 if (pass == 2) { 362 while ((id = queue_remove(id_queue))) 363 free(id); 364 return 0; 365 } 366 367 id = (char *)queue_remove(id_queue); 368 if (!id) { 369 yyerror("no common name for common perm definition?"); 370 return -1; 371 } 372 comdatum = hashtab_search(policydbp->p_commons.table, id); 373 if (comdatum) { 374 yyerror2("duplicate declaration for common %s\n", id); 375 return -1; 376 } 377 comdatum = (common_datum_t *) malloc(sizeof(common_datum_t)); 378 if (!comdatum) { 379 yyerror("out of memory"); 380 goto bad; 381 } 382 memset(comdatum, 0, sizeof(common_datum_t)); 383 ret = hashtab_insert(policydbp->p_commons.table, 384 (hashtab_key_t) id, (hashtab_datum_t) comdatum); 385 386 if (ret == SEPOL_EEXIST) { 387 yyerror("duplicate common definition"); 388 goto bad; 389 } 390 if (ret == SEPOL_ENOMEM) { 391 yyerror("hash table overflow"); 392 goto bad; 393 } 394 comdatum->s.value = policydbp->p_commons.nprim + 1; 395 if (symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE)) { 396 yyerror("out of memory"); 397 goto bad; 398 } 399 policydbp->p_commons.nprim++; 400 while ((perm = queue_remove(id_queue))) { 401 perdatum = (perm_datum_t *) malloc(sizeof(perm_datum_t)); 402 if (!perdatum) { 403 yyerror("out of memory"); 404 goto bad_perm; 405 } 406 memset(perdatum, 0, sizeof(perm_datum_t)); 407 perdatum->s.value = comdatum->permissions.nprim + 1; 408 409 if (perdatum->s.value > (sizeof(sepol_access_vector_t) * 8)) { 410 yyerror 411 ("too many permissions to fit in an access vector"); 412 goto bad_perm; 413 } 414 ret = hashtab_insert(comdatum->permissions.table, 415 (hashtab_key_t) perm, 416 (hashtab_datum_t) perdatum); 417 418 if (ret == SEPOL_EEXIST) { 419 yyerror2("duplicate permission %s in common %s", perm, 420 id); 421 goto bad_perm; 422 } 423 if (ret == SEPOL_ENOMEM) { 424 yyerror("hash table overflow"); 425 goto bad_perm; 426 } 427 comdatum->permissions.nprim++; 428 } 429 430 return 0; 431 432 bad: 433 if (id) 434 free(id); 435 if (comdatum) 436 free(comdatum); 437 return -1; 438 439 bad_perm: 440 if (perm) 441 free(perm); 442 if (perdatum) 443 free(perdatum); 444 return -1; 445 } 446 447 int define_av_perms(int inherits) 448 { 449 char *id; 450 class_datum_t *cladatum; 451 common_datum_t *comdatum; 452 perm_datum_t *perdatum = 0, *perdatum2 = 0; 453 int ret; 454 455 if (pass == 2) { 456 while ((id = queue_remove(id_queue))) 457 free(id); 458 return 0; 459 } 460 461 id = (char *)queue_remove(id_queue); 462 if (!id) { 463 yyerror("no tclass name for av perm definition?"); 464 return -1; 465 } 466 cladatum = (class_datum_t *) hashtab_search(policydbp->p_classes.table, 467 (hashtab_key_t) id); 468 if (!cladatum) { 469 yyerror2("class %s is not defined", id); 470 goto bad; 471 } 472 free(id); 473 474 if (cladatum->comdatum || cladatum->permissions.nprim) { 475 yyerror("duplicate access vector definition"); 476 return -1; 477 } 478 if (symtab_init(&cladatum->permissions, PERM_SYMTAB_SIZE)) { 479 yyerror("out of memory"); 480 return -1; 481 } 482 if (inherits) { 483 id = (char *)queue_remove(id_queue); 484 if (!id) { 485 yyerror 486 ("no inherits name for access vector definition?"); 487 return -1; 488 } 489 comdatum = 490 (common_datum_t *) hashtab_search(policydbp->p_commons. 491 table, 492 (hashtab_key_t) id); 493 494 if (!comdatum) { 495 yyerror2("common %s is not defined", id); 496 goto bad; 497 } 498 cladatum->comkey = id; 499 cladatum->comdatum = comdatum; 500 501 /* 502 * Class-specific permissions start with values 503 * after the last common permission. 504 */ 505 cladatum->permissions.nprim += comdatum->permissions.nprim; 506 } 507 while ((id = queue_remove(id_queue))) { 508 perdatum = (perm_datum_t *) malloc(sizeof(perm_datum_t)); 509 if (!perdatum) { 510 yyerror("out of memory"); 511 goto bad; 512 } 513 memset(perdatum, 0, sizeof(perm_datum_t)); 514 perdatum->s.value = ++cladatum->permissions.nprim; 515 516 if (perdatum->s.value > (sizeof(sepol_access_vector_t) * 8)) { 517 yyerror 518 ("too many permissions to fit in an access vector"); 519 goto bad; 520 } 521 if (inherits) { 522 /* 523 * Class-specific permissions and 524 * common permissions exist in the same 525 * name space. 526 */ 527 perdatum2 = 528 (perm_datum_t *) hashtab_search(cladatum->comdatum-> 529 permissions.table, 530 (hashtab_key_t) id); 531 if (perdatum2) { 532 yyerror2("permission %s conflicts with an " 533 "inherited permission", id); 534 goto bad; 535 } 536 } 537 ret = hashtab_insert(cladatum->permissions.table, 538 (hashtab_key_t) id, 539 (hashtab_datum_t) perdatum); 540 541 if (ret == SEPOL_EEXIST) { 542 yyerror2("duplicate permission %s", id); 543 goto bad; 544 } 545 if (ret == SEPOL_ENOMEM) { 546 yyerror("hash table overflow"); 547 goto bad; 548 } 549 if (add_perm_to_class(perdatum->s.value, cladatum->s.value)) { 550 yyerror("out of memory"); 551 goto bad; 552 } 553 } 554 555 return 0; 556 557 bad: 558 if (id) 559 free(id); 560 if (perdatum) 561 free(perdatum); 562 return -1; 563 } 564 565 int define_sens(void) 566 { 567 char *id; 568 mls_level_t *level = 0; 569 level_datum_t *datum = 0, *aliasdatum = 0; 570 int ret; 571 uint32_t value; /* dummy variable -- its value is never used */ 572 573 if (!mlspol) { 574 yyerror("sensitivity definition in non-MLS configuration"); 575 return -1; 576 } 577 578 if (pass == 2) { 579 while ((id = queue_remove(id_queue))) 580 free(id); 581 return 0; 582 } 583 584 id = (char *)queue_remove(id_queue); 585 if (!id) { 586 yyerror("no sensitivity name for sensitivity definition?"); 587 return -1; 588 } 589 if (id_has_dot(id)) { 590 yyerror("sensitivity identifiers may not contain periods"); 591 goto bad; 592 } 593 level = (mls_level_t *) malloc(sizeof(mls_level_t)); 594 if (!level) { 595 yyerror("out of memory"); 596 goto bad; 597 } 598 mls_level_init(level); 599 level->sens = 0; /* actual value set in define_dominance */ 600 ebitmap_init(&level->cat); /* actual value set in define_level */ 601 602 datum = (level_datum_t *) malloc(sizeof(level_datum_t)); 603 if (!datum) { 604 yyerror("out of memory"); 605 goto bad; 606 } 607 level_datum_init(datum); 608 datum->isalias = FALSE; 609 datum->level = level; 610 611 ret = declare_symbol(SYM_LEVELS, id, datum, &value, &value); 612 switch (ret) { 613 case -3:{ 614 yyerror("Out of memory!"); 615 goto bad; 616 } 617 case -2:{ 618 yyerror("duplicate declaration of sensitivity level"); 619 goto bad; 620 } 621 case -1:{ 622 yyerror("could not declare sensitivity level here"); 623 goto bad; 624 } 625 case 0: 626 case 1:{ 627 break; 628 } 629 default:{ 630 assert(0); /* should never get here */ 631 } 632 } 633 634 while ((id = queue_remove(id_queue))) { 635 if (id_has_dot(id)) { 636 yyerror("sensitivity aliases may not contain periods"); 637 goto bad_alias; 638 } 639 aliasdatum = (level_datum_t *) malloc(sizeof(level_datum_t)); 640 if (!aliasdatum) { 641 yyerror("out of memory"); 642 goto bad_alias; 643 } 644 level_datum_init(aliasdatum); 645 aliasdatum->isalias = TRUE; 646 aliasdatum->level = level; 647 648 ret = declare_symbol(SYM_LEVELS, id, aliasdatum, NULL, &value); 649 switch (ret) { 650 case -3:{ 651 yyerror("Out of memory!"); 652 goto bad_alias; 653 } 654 case -2:{ 655 yyerror 656 ("duplicate declaration of sensitivity alias"); 657 goto bad_alias; 658 } 659 case -1:{ 660 yyerror 661 ("could not declare sensitivity alias here"); 662 goto bad_alias; 663 } 664 case 0: 665 case 1:{ 666 break; 667 } 668 default:{ 669 assert(0); /* should never get here */ 670 } 671 } 672 } 673 674 return 0; 675 676 bad: 677 if (id) 678 free(id); 679 if (level) 680 free(level); 681 if (datum) { 682 level_datum_destroy(datum); 683 free(datum); 684 } 685 return -1; 686 687 bad_alias: 688 if (id) 689 free(id); 690 if (aliasdatum) { 691 level_datum_destroy(aliasdatum); 692 free(aliasdatum); 693 } 694 return -1; 695 } 696 697 int define_dominance(void) 698 { 699 level_datum_t *datum; 700 int order; 701 char *id; 702 703 if (!mlspol) { 704 yyerror("dominance definition in non-MLS configuration"); 705 return -1; 706 } 707 708 if (pass == 2) { 709 while ((id = queue_remove(id_queue))) 710 free(id); 711 return 0; 712 } 713 714 order = 0; 715 while ((id = (char *)queue_remove(id_queue))) { 716 datum = 717 (level_datum_t *) hashtab_search(policydbp->p_levels.table, 718 (hashtab_key_t) id); 719 if (!datum) { 720 yyerror2("unknown sensitivity %s used in dominance " 721 "definition", id); 722 free(id); 723 return -1; 724 } 725 if (datum->level->sens != 0) { 726 yyerror2("sensitivity %s occurs multiply in dominance " 727 "definition", id); 728 free(id); 729 return -1; 730 } 731 datum->level->sens = ++order; 732 733 /* no need to keep sensitivity name */ 734 free(id); 735 } 736 737 if (order != policydbp->p_levels.nprim) { 738 yyerror 739 ("all sensitivities must be specified in dominance definition"); 740 return -1; 741 } 742 return 0; 743 } 744 745 int define_category(void) 746 { 747 char *id; 748 cat_datum_t *datum = 0, *aliasdatum = 0; 749 int ret; 750 uint32_t value; 751 752 if (!mlspol) { 753 yyerror("category definition in non-MLS configuration"); 754 return -1; 755 } 756 757 if (pass == 2) { 758 while ((id = queue_remove(id_queue))) 759 free(id); 760 return 0; 761 } 762 763 id = (char *)queue_remove(id_queue); 764 if (!id) { 765 yyerror("no category name for category definition?"); 766 return -1; 767 } 768 if (id_has_dot(id)) { 769 yyerror("category identifiers may not contain periods"); 770 goto bad; 771 } 772 datum = (cat_datum_t *) malloc(sizeof(cat_datum_t)); 773 if (!datum) { 774 yyerror("out of memory"); 775 goto bad; 776 } 777 cat_datum_init(datum); 778 datum->isalias = FALSE; 779 780 ret = declare_symbol(SYM_CATS, id, datum, &value, &value); 781 switch (ret) { 782 case -3:{ 783 yyerror("Out of memory!"); 784 goto bad; 785 } 786 case -2:{ 787 yyerror("duplicate declaration of category"); 788 goto bad; 789 } 790 case -1:{ 791 yyerror("could not declare category here"); 792 goto bad; 793 } 794 case 0: 795 case 1:{ 796 break; 797 } 798 default:{ 799 assert(0); /* should never get here */ 800 } 801 } 802 datum->s.value = value; 803 804 while ((id = queue_remove(id_queue))) { 805 if (id_has_dot(id)) { 806 yyerror("category aliases may not contain periods"); 807 goto bad_alias; 808 } 809 aliasdatum = (cat_datum_t *) malloc(sizeof(cat_datum_t)); 810 if (!aliasdatum) { 811 yyerror("out of memory"); 812 goto bad_alias; 813 } 814 cat_datum_init(aliasdatum); 815 aliasdatum->isalias = TRUE; 816 aliasdatum->s.value = datum->s.value; 817 818 ret = 819 declare_symbol(SYM_CATS, id, aliasdatum, NULL, 820 &datum->s.value); 821 switch (ret) { 822 case -3:{ 823 yyerror("Out of memory!"); 824 goto bad_alias; 825 } 826 case -2:{ 827 yyerror 828 ("duplicate declaration of category aliases"); 829 goto bad_alias; 830 } 831 case -1:{ 832 yyerror 833 ("could not declare category aliases here"); 834 goto bad_alias; 835 } 836 case 0: 837 case 1:{ 838 break; 839 } 840 default:{ 841 assert(0); /* should never get here */ 842 } 843 } 844 } 845 846 return 0; 847 848 bad: 849 if (id) 850 free(id); 851 if (datum) { 852 cat_datum_destroy(datum); 853 free(datum); 854 } 855 return -1; 856 857 bad_alias: 858 if (id) 859 free(id); 860 if (aliasdatum) { 861 cat_datum_destroy(aliasdatum); 862 free(aliasdatum); 863 } 864 return -1; 865 } 866 867 static int clone_level(hashtab_key_t key, hashtab_datum_t datum, void *arg) 868 { 869 level_datum_t *levdatum = (level_datum_t *) datum; 870 mls_level_t *level = (mls_level_t *) arg, *newlevel; 871 872 if (levdatum->level == level) { 873 levdatum->defined = 1; 874 if (!levdatum->isalias) 875 return 0; 876 newlevel = (mls_level_t *) malloc(sizeof(mls_level_t)); 877 if (!newlevel) 878 return -1; 879 if (mls_level_cpy(newlevel, level)) { 880 free(newlevel); 881 return -1; 882 } 883 levdatum->level = newlevel; 884 } 885 return 0; 886 } 887 888 int define_level(void) 889 { 890 char *id; 891 level_datum_t *levdatum; 892 893 if (!mlspol) { 894 yyerror("level definition in non-MLS configuration"); 895 return -1; 896 } 897 898 if (pass == 2) { 899 while ((id = queue_remove(id_queue))) 900 free(id); 901 return 0; 902 } 903 904 id = (char *)queue_remove(id_queue); 905 if (!id) { 906 yyerror("no level name for level definition?"); 907 return -1; 908 } 909 levdatum = (level_datum_t *) hashtab_search(policydbp->p_levels.table, 910 (hashtab_key_t) id); 911 if (!levdatum) { 912 yyerror2("unknown sensitivity %s used in level definition", id); 913 free(id); 914 return -1; 915 } 916 if (ebitmap_length(&levdatum->level->cat)) { 917 yyerror2("sensitivity %s used in multiple level definitions", 918 id); 919 free(id); 920 return -1; 921 } 922 free(id); 923 924 levdatum->defined = 1; 925 926 while ((id = queue_remove(id_queue))) { 927 cat_datum_t *cdatum; 928 int range_start, range_end, i; 929 930 if (id_has_dot(id)) { 931 char *id_start = id; 932 char *id_end = strchr(id, '.'); 933 934 *(id_end++) = '\0'; 935 936 cdatum = 937 (cat_datum_t *) hashtab_search(policydbp->p_cats. 938 table, 939 (hashtab_key_t) 940 id_start); 941 if (!cdatum) { 942 yyerror2("unknown category %s", id_start); 943 free(id); 944 return -1; 945 } 946 range_start = cdatum->s.value - 1; 947 cdatum = 948 (cat_datum_t *) hashtab_search(policydbp->p_cats. 949 table, 950 (hashtab_key_t) 951 id_end); 952 if (!cdatum) { 953 yyerror2("unknown category %s", id_end); 954 free(id); 955 return -1; 956 } 957 range_end = cdatum->s.value - 1; 958 959 if (range_end < range_start) { 960 yyerror2("category range is invalid"); 961 free(id); 962 return -1; 963 } 964 } else { 965 cdatum = 966 (cat_datum_t *) hashtab_search(policydbp->p_cats. 967 table, 968 (hashtab_key_t) id); 969 range_start = range_end = cdatum->s.value - 1; 970 } 971 972 for (i = range_start; i <= range_end; i++) { 973 if (ebitmap_set_bit(&levdatum->level->cat, i, TRUE)) { 974 yyerror("out of memory"); 975 free(id); 976 return -1; 977 } 978 } 979 980 free(id); 981 } 982 983 if (hashtab_map 984 (policydbp->p_levels.table, clone_level, levdatum->level)) { 985 yyerror("out of memory"); 986 return -1; 987 } 988 989 return 0; 990 } 991 992 int define_attrib(void) 993 { 994 if (pass == 2) { 995 free(queue_remove(id_queue)); 996 return 0; 997 } 998 999 if (declare_type(TRUE, TRUE) == NULL) { 1000 return -1; 1001 } 1002 return 0; 1003 } 1004 1005 static int add_aliases_to_type(type_datum_t * type) 1006 { 1007 char *id; 1008 type_datum_t *aliasdatum = NULL; 1009 int ret; 1010 while ((id = queue_remove(id_queue))) { 1011 if (id_has_dot(id)) { 1012 free(id); 1013 yyerror 1014 ("type alias identifiers may not contain periods"); 1015 return -1; 1016 } 1017 aliasdatum = (type_datum_t *) malloc(sizeof(type_datum_t)); 1018 if (!aliasdatum) { 1019 free(id); 1020 yyerror("Out of memory!"); 1021 return -1; 1022 } 1023 memset(aliasdatum, 0, sizeof(type_datum_t)); 1024 aliasdatum->s.value = type->s.value; 1025 1026 ret = declare_symbol(SYM_TYPES, id, aliasdatum, 1027 NULL, &aliasdatum->s.value); 1028 switch (ret) { 1029 case -3:{ 1030 yyerror("Out of memory!"); 1031 goto cleanup; 1032 } 1033 case -2:{ 1034 yyerror2("duplicate declaration of alias %s", 1035 id); 1036 goto cleanup; 1037 } 1038 case -1:{ 1039 yyerror("could not declare alias here"); 1040 goto cleanup; 1041 } 1042 case 0: break; 1043 case 1:{ 1044 /* ret == 1 means the alias was required and therefore already 1045 * has a value. Set it up as an alias with a different primary. */ 1046 type_datum_destroy(aliasdatum); 1047 free(aliasdatum); 1048 1049 aliasdatum = hashtab_search(policydbp->symtab[SYM_TYPES].table, id); 1050 assert(aliasdatum); 1051 1052 aliasdatum->primary = type->s.value; 1053 aliasdatum->flavor = TYPE_ALIAS; 1054 1055 break; 1056 } 1057 default:{ 1058 assert(0); /* should never get here */ 1059 } 1060 } 1061 } 1062 return 0; 1063 cleanup: 1064 free(id); 1065 type_datum_destroy(aliasdatum); 1066 free(aliasdatum); 1067 return -1; 1068 } 1069 1070 int define_typealias(void) 1071 { 1072 char *id; 1073 type_datum_t *t; 1074 1075 if (pass == 2) { 1076 while ((id = queue_remove(id_queue))) 1077 free(id); 1078 return 0; 1079 } 1080 1081 id = (char *)queue_remove(id_queue); 1082 if (!id) { 1083 yyerror("no type name for typealias definition?"); 1084 return -1; 1085 } 1086 1087 if (!is_id_in_scope(SYM_TYPES, id)) { 1088 yyerror2("type %s is not within scope", id); 1089 free(id); 1090 return -1; 1091 } 1092 t = hashtab_search(policydbp->p_types.table, id); 1093 if (!t || t->flavor == TYPE_ATTRIB) { 1094 yyerror2("unknown type %s, or it was already declared as an " 1095 "attribute", id); 1096 free(id); 1097 return -1; 1098 } 1099 return add_aliases_to_type(t); 1100 } 1101 1102 int define_typeattribute(void) 1103 { 1104 char *id; 1105 type_datum_t *t, *attr; 1106 1107 if (pass == 2) { 1108 while ((id = queue_remove(id_queue))) 1109 free(id); 1110 return 0; 1111 } 1112 1113 id = (char *)queue_remove(id_queue); 1114 if (!id) { 1115 yyerror("no type name for typeattribute definition?"); 1116 return -1; 1117 } 1118 1119 if (!is_id_in_scope(SYM_TYPES, id)) { 1120 yyerror2("type %s is not within scope", id); 1121 free(id); 1122 return -1; 1123 } 1124 t = hashtab_search(policydbp->p_types.table, id); 1125 if (!t || t->flavor == TYPE_ATTRIB) { 1126 yyerror2("unknown type %s", id); 1127 free(id); 1128 return -1; 1129 } 1130 1131 while ((id = queue_remove(id_queue))) { 1132 if (!is_id_in_scope(SYM_TYPES, id)) { 1133 yyerror2("attribute %s is not within scope", id); 1134 free(id); 1135 return -1; 1136 } 1137 attr = hashtab_search(policydbp->p_types.table, id); 1138 if (!attr) { 1139 /* treat it as a fatal error */ 1140 yyerror2("attribute %s is not declared", id); 1141 free(id); 1142 return -1; 1143 } 1144 1145 if (attr->flavor != TYPE_ATTRIB) { 1146 yyerror2("%s is a type, not an attribute", id); 1147 free(id); 1148 return -1; 1149 } 1150 1151 if ((attr = get_local_type(id, attr->s.value, 1)) == NULL) { 1152 yyerror("Out of memory!"); 1153 return -1; 1154 } 1155 1156 if (ebitmap_set_bit(&attr->types, (t->s.value - 1), TRUE)) { 1157 yyerror("out of memory"); 1158 return -1; 1159 } 1160 } 1161 1162 return 0; 1163 } 1164 1165 static int define_typebounds_helper(char *bounds_id, char *type_id) 1166 { 1167 type_datum_t *bounds, *type; 1168 1169 if (!is_id_in_scope(SYM_TYPES, bounds_id)) { 1170 yyerror2("type %s is not within scope", bounds_id); 1171 return -1; 1172 } 1173 1174 bounds = hashtab_search(policydbp->p_types.table, bounds_id); 1175 if (!bounds || bounds->flavor == TYPE_ATTRIB) { 1176 yyerror2("hoge unknown type %s", bounds_id); 1177 return -1; 1178 } 1179 1180 if (!is_id_in_scope(SYM_TYPES, type_id)) { 1181 yyerror2("type %s is not within scope", type_id); 1182 return -1; 1183 } 1184 1185 type = hashtab_search(policydbp->p_types.table, type_id); 1186 if (!type || type->flavor == TYPE_ATTRIB) { 1187 yyerror2("type %s is not declared", type_id); 1188 return -1; 1189 } 1190 1191 if (type->flavor == TYPE_TYPE && !type->primary) { 1192 type = policydbp->type_val_to_struct[type->s.value - 1]; 1193 } else if (type->flavor == TYPE_ALIAS) { 1194 type = policydbp->type_val_to_struct[type->primary - 1]; 1195 } 1196 1197 if (!type->bounds) 1198 type->bounds = bounds->s.value; 1199 else if (type->bounds != bounds->s.value) { 1200 yyerror2("type %s has inconsistent master {%s,%s}", 1201 type_id, 1202 policydbp->p_type_val_to_name[type->bounds - 1], 1203 policydbp->p_type_val_to_name[bounds->s.value - 1]); 1204 return -1; 1205 } 1206 1207 return 0; 1208 } 1209 1210 int define_typebounds(void) 1211 { 1212 char *bounds, *id; 1213 1214 if (pass == 1) { 1215 while ((id = queue_remove(id_queue))) 1216 free(id); 1217 return 0; 1218 } 1219 1220 bounds = (char *) queue_remove(id_queue); 1221 if (!bounds) { 1222 yyerror("no type name for typebounds definition?"); 1223 return -1; 1224 } 1225 1226 while ((id = queue_remove(id_queue))) { 1227 if (define_typebounds_helper(bounds, id)) 1228 return -1; 1229 free(id); 1230 } 1231 free(bounds); 1232 1233 return 0; 1234 } 1235 1236 int define_type(int alias) 1237 { 1238 char *id; 1239 type_datum_t *datum, *attr; 1240 1241 if (pass == 2) { 1242 /* 1243 * If type name contains ".", we have to define boundary 1244 * relationship implicitly to keep compatibility with 1245 * old name based hierarchy. 1246 */ 1247 if ((id = queue_remove(id_queue))) { 1248 char *bounds, *delim; 1249 1250 if ((delim = strrchr(id, '.')) 1251 && (bounds = strdup(id))) { 1252 bounds[(size_t)(delim - id)] = '\0'; 1253 1254 if (define_typebounds_helper(bounds, id)) 1255 return -1; 1256 free(bounds); 1257 } 1258 free(id); 1259 } 1260 1261 if (alias) { 1262 while ((id = queue_remove(id_queue))) 1263 free(id); 1264 } 1265 1266 while ((id = queue_remove(id_queue))) 1267 free(id); 1268 return 0; 1269 } 1270 1271 if ((datum = declare_type(TRUE, FALSE)) == NULL) { 1272 return -1; 1273 } 1274 1275 if (alias) { 1276 if (add_aliases_to_type(datum) == -1) { 1277 return -1; 1278 } 1279 } 1280 1281 while ((id = queue_remove(id_queue))) { 1282 if (!is_id_in_scope(SYM_TYPES, id)) { 1283 yyerror2("attribute %s is not within scope", id); 1284 free(id); 1285 return -1; 1286 } 1287 attr = hashtab_search(policydbp->p_types.table, id); 1288 if (!attr) { 1289 /* treat it as a fatal error */ 1290 yyerror2("attribute %s is not declared", id); 1291 return -1; 1292 } 1293 1294 if (attr->flavor != TYPE_ATTRIB) { 1295 yyerror2("%s is a type, not an attribute", id); 1296 return -1; 1297 } 1298 1299 if ((attr = get_local_type(id, attr->s.value, 1)) == NULL) { 1300 yyerror("Out of memory!"); 1301 return -1; 1302 } 1303 1304 if (ebitmap_set_bit(&attr->types, datum->s.value - 1, TRUE)) { 1305 yyerror("Out of memory"); 1306 return -1; 1307 } 1308 } 1309 1310 return 0; 1311 } 1312 1313 struct val_to_name { 1314 unsigned int val; 1315 char *name; 1316 }; 1317 1318 /* Adds a type, given by its textual name, to a typeset. If *add is 1319 0, then add the type to the negative set; otherwise if *add is 1 1320 then add it to the positive side. */ 1321 static int set_types(type_set_t * set, char *id, int *add, char starallowed) 1322 { 1323 type_datum_t *t; 1324 1325 if (strcmp(id, "*") == 0) { 1326 if (!starallowed) { 1327 yyerror("* not allowed in this type of rule"); 1328 return -1; 1329 } 1330 /* set TYPE_STAR flag */ 1331 set->flags = TYPE_STAR; 1332 free(id); 1333 *add = 1; 1334 return 0; 1335 } 1336 1337 if (strcmp(id, "~") == 0) { 1338 if (!starallowed) { 1339 yyerror("~ not allowed in this type of rule"); 1340 return -1; 1341 } 1342 /* complement the set */ 1343 set->flags = TYPE_COMP; 1344 free(id); 1345 *add = 1; 1346 return 0; 1347 } 1348 1349 if (strcmp(id, "-") == 0) { 1350 *add = 0; 1351 free(id); 1352 return 0; 1353 } 1354 1355 if (!is_id_in_scope(SYM_TYPES, id)) { 1356 yyerror2("type %s is not within scope", id); 1357 free(id); 1358 return -1; 1359 } 1360 t = hashtab_search(policydbp->p_types.table, id); 1361 if (!t) { 1362 yyerror2("unknown type %s", id); 1363 free(id); 1364 return -1; 1365 } 1366 1367 if (*add == 0) { 1368 if (ebitmap_set_bit(&set->negset, t->s.value - 1, TRUE)) 1369 goto oom; 1370 } else { 1371 if (ebitmap_set_bit(&set->types, t->s.value - 1, TRUE)) 1372 goto oom; 1373 } 1374 free(id); 1375 *add = 1; 1376 return 0; 1377 oom: 1378 yyerror("Out of memory"); 1379 free(id); 1380 return -1; 1381 } 1382 1383 int define_compute_type_helper(int which, avrule_t ** rule) 1384 { 1385 char *id; 1386 type_datum_t *datum; 1387 ebitmap_t tclasses; 1388 ebitmap_node_t *node; 1389 avrule_t *avrule; 1390 class_perm_node_t *perm; 1391 int i, add = 1; 1392 1393 avrule = malloc(sizeof(avrule_t)); 1394 if (!avrule) { 1395 yyerror("out of memory"); 1396 return -1; 1397 } 1398 avrule_init(avrule); 1399 avrule->specified = which; 1400 avrule->line = policydb_lineno; 1401 1402 while ((id = queue_remove(id_queue))) { 1403 if (set_types(&avrule->stypes, id, &add, 0)) 1404 return -1; 1405 } 1406 add = 1; 1407 while ((id = queue_remove(id_queue))) { 1408 if (set_types(&avrule->ttypes, id, &add, 0)) 1409 return -1; 1410 } 1411 1412 ebitmap_init(&tclasses); 1413 if (read_classes(&tclasses)) 1414 goto bad; 1415 1416 id = (char *)queue_remove(id_queue); 1417 if (!id) { 1418 yyerror("no newtype?"); 1419 goto bad; 1420 } 1421 if (!is_id_in_scope(SYM_TYPES, id)) { 1422 yyerror2("type %s is not within scope", id); 1423 free(id); 1424 goto bad; 1425 } 1426 datum = (type_datum_t *) hashtab_search(policydbp->p_types.table, 1427 (hashtab_key_t) id); 1428 if (!datum || datum->flavor == TYPE_ATTRIB) { 1429 yyerror2("unknown type %s", id); 1430 goto bad; 1431 } 1432 1433 ebitmap_for_each_bit(&tclasses, node, i) { 1434 if (ebitmap_node_get_bit(node, i)) { 1435 perm = malloc(sizeof(class_perm_node_t)); 1436 if (!perm) { 1437 yyerror("out of memory"); 1438 return -1; 1439 } 1440 class_perm_node_init(perm); 1441 perm->class = i + 1; 1442 perm->data = datum->s.value; 1443 perm->next = avrule->perms; 1444 avrule->perms = perm; 1445 } 1446 } 1447 ebitmap_destroy(&tclasses); 1448 1449 *rule = avrule; 1450 return 0; 1451 1452 bad: 1453 avrule_destroy(avrule); 1454 free(avrule); 1455 return -1; 1456 } 1457 1458 int define_compute_type(int which) 1459 { 1460 char *id; 1461 avrule_t *avrule; 1462 1463 if (pass == 1) { 1464 while ((id = queue_remove(id_queue))) 1465 free(id); 1466 while ((id = queue_remove(id_queue))) 1467 free(id); 1468 while ((id = queue_remove(id_queue))) 1469 free(id); 1470 id = queue_remove(id_queue); 1471 free(id); 1472 return 0; 1473 } 1474 1475 if (define_compute_type_helper(which, &avrule)) 1476 return -1; 1477 1478 append_avrule(avrule); 1479 return 0; 1480 } 1481 1482 avrule_t *define_cond_compute_type(int which) 1483 { 1484 char *id; 1485 avrule_t *avrule; 1486 1487 if (pass == 1) { 1488 while ((id = queue_remove(id_queue))) 1489 free(id); 1490 while ((id = queue_remove(id_queue))) 1491 free(id); 1492 while ((id = queue_remove(id_queue))) 1493 free(id); 1494 id = queue_remove(id_queue); 1495 free(id); 1496 return (avrule_t *) 1; 1497 } 1498 1499 if (define_compute_type_helper(which, &avrule)) 1500 return COND_ERR; 1501 1502 return avrule; 1503 } 1504 1505 int define_bool_tunable(int is_tunable) 1506 { 1507 char *id, *bool_value; 1508 cond_bool_datum_t *datum; 1509 int ret; 1510 uint32_t value; 1511 1512 if (pass == 2) { 1513 while ((id = queue_remove(id_queue))) 1514 free(id); 1515 return 0; 1516 } 1517 1518 id = (char *)queue_remove(id_queue); 1519 if (!id) { 1520 yyerror("no identifier for bool definition?"); 1521 return -1; 1522 } 1523 if (id_has_dot(id)) { 1524 free(id); 1525 yyerror("boolean identifiers may not contain periods"); 1526 return -1; 1527 } 1528 datum = (cond_bool_datum_t *) malloc(sizeof(cond_bool_datum_t)); 1529 if (!datum) { 1530 yyerror("out of memory"); 1531 free(id); 1532 return -1; 1533 } 1534 memset(datum, 0, sizeof(cond_bool_datum_t)); 1535 if (is_tunable) 1536 datum->flags |= COND_BOOL_FLAGS_TUNABLE; 1537 ret = declare_symbol(SYM_BOOLS, id, datum, &value, &value); 1538 switch (ret) { 1539 case -3:{ 1540 yyerror("Out of memory!"); 1541 goto cleanup; 1542 } 1543 case -2:{ 1544 yyerror2("duplicate declaration of boolean %s", id); 1545 goto cleanup; 1546 } 1547 case -1:{ 1548 yyerror("could not declare boolean here"); 1549 goto cleanup; 1550 } 1551 case 0: 1552 case 1:{ 1553 break; 1554 } 1555 default:{ 1556 assert(0); /* should never get here */ 1557 } 1558 } 1559 datum->s.value = value; 1560 1561 bool_value = (char *)queue_remove(id_queue); 1562 if (!bool_value) { 1563 yyerror("no default value for bool definition?"); 1564 free(id); 1565 return -1; 1566 } 1567 1568 datum->state = (int)(bool_value[0] == 'T') ? 1 : 0; 1569 return 0; 1570 cleanup: 1571 cond_destroy_bool(id, datum, NULL); 1572 return -1; 1573 } 1574 1575 avrule_t *define_cond_pol_list(avrule_t * avlist, avrule_t * sl) 1576 { 1577 if (pass == 1) { 1578 /* return something so we get through pass 1 */ 1579 return (avrule_t *) 1; 1580 } 1581 1582 if (sl == NULL) { 1583 /* This is a require block, return previous list */ 1584 return avlist; 1585 } 1586 1587 /* prepend the new avlist to the pre-existing one */ 1588 sl->next = avlist; 1589 return sl; 1590 } 1591 1592 int define_te_avtab_helper(int which, avrule_t ** rule) 1593 { 1594 char *id; 1595 class_datum_t *cladatum; 1596 perm_datum_t *perdatum = NULL; 1597 class_perm_node_t *perms, *tail = NULL, *cur_perms = NULL; 1598 ebitmap_t tclasses; 1599 ebitmap_node_t *node; 1600 avrule_t *avrule; 1601 unsigned int i; 1602 int add = 1, ret = 0; 1603 int suppress = 0; 1604 1605 avrule = (avrule_t *) malloc(sizeof(avrule_t)); 1606 if (!avrule) { 1607 yyerror("memory error"); 1608 ret = -1; 1609 goto out; 1610 } 1611 avrule_init(avrule); 1612 avrule->specified = which; 1613 avrule->line = policydb_lineno; 1614 1615 while ((id = queue_remove(id_queue))) { 1616 if (set_types 1617 (&avrule->stypes, id, &add, 1618 which == AVRULE_NEVERALLOW ? 1 : 0)) { 1619 ret = -1; 1620 goto out; 1621 } 1622 } 1623 add = 1; 1624 while ((id = queue_remove(id_queue))) { 1625 if (strcmp(id, "self") == 0) { 1626 free(id); 1627 avrule->flags |= RULE_SELF; 1628 continue; 1629 } 1630 if (set_types 1631 (&avrule->ttypes, id, &add, 1632 which == AVRULE_NEVERALLOW ? 1 : 0)) { 1633 ret = -1; 1634 goto out; 1635 } 1636 } 1637 1638 ebitmap_init(&tclasses); 1639 ret = read_classes(&tclasses); 1640 if (ret) 1641 goto out; 1642 1643 perms = NULL; 1644 ebitmap_for_each_bit(&tclasses, node, i) { 1645 if (!ebitmap_node_get_bit(node, i)) 1646 continue; 1647 cur_perms = 1648 (class_perm_node_t *) malloc(sizeof(class_perm_node_t)); 1649 if (!cur_perms) { 1650 yyerror("out of memory"); 1651 ret = -1; 1652 goto out; 1653 } 1654 class_perm_node_init(cur_perms); 1655 cur_perms->class = i + 1; 1656 if (!perms) 1657 perms = cur_perms; 1658 if (tail) 1659 tail->next = cur_perms; 1660 tail = cur_perms; 1661 } 1662 1663 while ((id = queue_remove(id_queue))) { 1664 cur_perms = perms; 1665 ebitmap_for_each_bit(&tclasses, node, i) { 1666 if (!ebitmap_node_get_bit(node, i)) 1667 continue; 1668 cladatum = policydbp->class_val_to_struct[i]; 1669 1670 if (strcmp(id, "*") == 0) { 1671 /* set all permissions in the class */ 1672 cur_perms->data = ~0U; 1673 goto next; 1674 } 1675 1676 if (strcmp(id, "~") == 0) { 1677 /* complement the set */ 1678 if (which == AVRULE_DONTAUDIT) 1679 yywarn("dontaudit rule with a ~?"); 1680 cur_perms->data = ~cur_perms->data; 1681 goto next; 1682 } 1683 1684 perdatum = 1685 hashtab_search(cladatum->permissions.table, id); 1686 if (!perdatum) { 1687 if (cladatum->comdatum) { 1688 perdatum = 1689 hashtab_search(cladatum->comdatum-> 1690 permissions.table, 1691 id); 1692 } 1693 } 1694 if (!perdatum) { 1695 if (!suppress) 1696 yyerror2("permission %s is not defined" 1697 " for class %s", id, 1698 policydbp->p_class_val_to_name[i]); 1699 continue; 1700 } else 1701 if (!is_perm_in_scope 1702 (id, policydbp->p_class_val_to_name[i])) { 1703 if (!suppress) { 1704 yyerror2("permission %s of class %s is" 1705 " not within scope", id, 1706 policydbp->p_class_val_to_name[i]); 1707 } 1708 continue; 1709 } else { 1710 cur_perms->data |= 1U << (perdatum->s.value - 1); 1711 } 1712 next: 1713 cur_perms = cur_perms->next; 1714 } 1715 1716 free(id); 1717 } 1718 1719 ebitmap_destroy(&tclasses); 1720 1721 avrule->perms = perms; 1722 *rule = avrule; 1723 1724 out: 1725 return ret; 1726 1727 } 1728 1729 avrule_t *define_cond_te_avtab(int which) 1730 { 1731 char *id; 1732 avrule_t *avrule; 1733 int i; 1734 1735 if (pass == 1) { 1736 for (i = 0; i < 4; i++) { 1737 while ((id = queue_remove(id_queue))) 1738 free(id); 1739 } 1740 return (avrule_t *) 1; /* any non-NULL value */ 1741 } 1742 1743 if (define_te_avtab_helper(which, &avrule)) 1744 return COND_ERR; 1745 1746 return avrule; 1747 } 1748 1749 int define_te_avtab(int which) 1750 { 1751 char *id; 1752 avrule_t *avrule; 1753 int i; 1754 1755 if (pass == 1) { 1756 for (i = 0; i < 4; i++) { 1757 while ((id = queue_remove(id_queue))) 1758 free(id); 1759 } 1760 return 0; 1761 } 1762 1763 if (define_te_avtab_helper(which, &avrule)) 1764 return -1; 1765 1766 /* append this avrule to the end of the current rules list */ 1767 append_avrule(avrule); 1768 return 0; 1769 } 1770 1771 /* The role-types rule is no longer used to declare regular role or 1772 * role attribute, but solely aimed for declaring role-types associations. 1773 */ 1774 int define_role_types(void) 1775 { 1776 role_datum_t *role; 1777 char *id; 1778 int add = 1; 1779 1780 if (pass == 1) { 1781 while ((id = queue_remove(id_queue))) 1782 free(id); 1783 return 0; 1784 } 1785 1786 id = (char *)queue_remove(id_queue); 1787 if (!id) { 1788 yyerror("no role name for role-types rule?"); 1789 return -1; 1790 } 1791 1792 if (!is_id_in_scope(SYM_ROLES, id)) { 1793 yyerror2("role %s is not within scope", id); 1794 free(id); 1795 return -1; 1796 } 1797 1798 role = hashtab_search(policydbp->p_roles.table, id); 1799 if (!role) { 1800 yyerror2("unknown role %s", id); 1801 free(id); 1802 return -1; 1803 } 1804 1805 while ((id = queue_remove(id_queue))) { 1806 if (set_types(&role->types, id, &add, 0)) 1807 return -1; 1808 } 1809 1810 return 0; 1811 } 1812 1813 int define_attrib_role(void) 1814 { 1815 if (pass == 2) { 1816 free(queue_remove(id_queue)); 1817 return 0; 1818 } 1819 1820 /* Declare a role attribute */ 1821 if (declare_role(TRUE) == NULL) 1822 return -1; 1823 1824 return 0; 1825 } 1826 1827 int define_role_attr(void) 1828 { 1829 char *id; 1830 role_datum_t *r, *attr; 1831 1832 if (pass == 2) { 1833 while ((id = queue_remove(id_queue))) 1834 free(id); 1835 return 0; 1836 } 1837 1838 /* Declare a regular role */ 1839 if ((r = declare_role(FALSE)) == NULL) 1840 return -1; 1841 1842 while ((id = queue_remove(id_queue))) { 1843 if (!is_id_in_scope(SYM_ROLES, id)) { 1844 yyerror2("attribute %s is not within scope", id); 1845 free(id); 1846 return -1; 1847 } 1848 attr = hashtab_search(policydbp->p_roles.table, id); 1849 if (!attr) { 1850 /* treat it as a fatal error */ 1851 yyerror2("role attribute %s is not declared", id); 1852 free(id); 1853 return -1; 1854 } 1855 1856 if (attr->flavor != ROLE_ATTRIB) { 1857 yyerror2("%s is a regular role, not an attribute", id); 1858 free(id); 1859 return -1; 1860 } 1861 1862 if ((attr = get_local_role(id, attr->s.value, 1)) == NULL) { 1863 yyerror("Out of memory!"); 1864 return -1; 1865 } 1866 1867 if (ebitmap_set_bit(&attr->roles, (r->s.value - 1), TRUE)) { 1868 yyerror("out of memory"); 1869 return -1; 1870 } 1871 } 1872 1873 return 0; 1874 } 1875 1876 int define_roleattribute(void) 1877 { 1878 char *id; 1879 role_datum_t *r, *attr; 1880 1881 if (pass == 2) { 1882 while ((id = queue_remove(id_queue))) 1883 free(id); 1884 return 0; 1885 } 1886 1887 id = (char *)queue_remove(id_queue); 1888 if (!id) { 1889 yyerror("no role name for roleattribute definition?"); 1890 return -1; 1891 } 1892 1893 if (!is_id_in_scope(SYM_ROLES, id)) { 1894 yyerror2("role %s is not within scope", id); 1895 free(id); 1896 return -1; 1897 } 1898 r = hashtab_search(policydbp->p_roles.table, id); 1899 /* We support adding one role attribute into another */ 1900 if (!r) { 1901 yyerror2("unknown role %s", id); 1902 free(id); 1903 return -1; 1904 } 1905 1906 while ((id = queue_remove(id_queue))) { 1907 if (!is_id_in_scope(SYM_ROLES, id)) { 1908 yyerror2("attribute %s is not within scope", id); 1909 free(id); 1910 return -1; 1911 } 1912 attr = hashtab_search(policydbp->p_roles.table, id); 1913 if (!attr) { 1914 /* treat it as a fatal error */ 1915 yyerror2("role attribute %s is not declared", id); 1916 free(id); 1917 return -1; 1918 } 1919 1920 if (attr->flavor != ROLE_ATTRIB) { 1921 yyerror2("%s is a regular role, not an attribute", id); 1922 free(id); 1923 return -1; 1924 } 1925 1926 if ((attr = get_local_role(id, attr->s.value, 1)) == NULL) { 1927 yyerror("Out of memory!"); 1928 return -1; 1929 } 1930 1931 if (ebitmap_set_bit(&attr->roles, (r->s.value - 1), TRUE)) { 1932 yyerror("out of memory"); 1933 return -1; 1934 } 1935 } 1936 1937 return 0; 1938 } 1939 1940 role_datum_t *merge_roles_dom(role_datum_t * r1, role_datum_t * r2) 1941 { 1942 role_datum_t *new; 1943 1944 if (pass == 1) { 1945 return (role_datum_t *) 1; /* any non-NULL value */ 1946 } 1947 1948 new = malloc(sizeof(role_datum_t)); 1949 if (!new) { 1950 yyerror("out of memory"); 1951 return NULL; 1952 } 1953 memset(new, 0, sizeof(role_datum_t)); 1954 new->s.value = 0; /* temporary role */ 1955 if (ebitmap_or(&new->dominates, &r1->dominates, &r2->dominates)) { 1956 yyerror("out of memory"); 1957 return NULL; 1958 } 1959 if (ebitmap_or(&new->types.types, &r1->types.types, &r2->types.types)) { 1960 yyerror("out of memory"); 1961 return NULL; 1962 } 1963 if (!r1->s.value) { 1964 /* free intermediate result */ 1965 type_set_destroy(&r1->types); 1966 ebitmap_destroy(&r1->dominates); 1967 free(r1); 1968 } 1969 if (!r2->s.value) { 1970 /* free intermediate result */ 1971 yyerror("right hand role is temporary?"); 1972 type_set_destroy(&r2->types); 1973 ebitmap_destroy(&r2->dominates); 1974 free(r2); 1975 } 1976 return new; 1977 } 1978 1979 /* This function eliminates the ordering dependency of role dominance rule */ 1980 static int dominate_role_recheck(hashtab_key_t key, hashtab_datum_t datum, 1981 void *arg) 1982 { 1983 role_datum_t *rdp = (role_datum_t *) arg; 1984 role_datum_t *rdatum = (role_datum_t *) datum; 1985 ebitmap_node_t *node; 1986 int i; 1987 1988 /* Don't bother to process against self role */ 1989 if (rdatum->s.value == rdp->s.value) 1990 return 0; 1991 1992 /* If a dominating role found */ 1993 if (ebitmap_get_bit(&(rdatum->dominates), rdp->s.value - 1)) { 1994 ebitmap_t types; 1995 ebitmap_init(&types); 1996 if (type_set_expand(&rdp->types, &types, policydbp, 1)) { 1997 ebitmap_destroy(&types); 1998 return -1; 1999 } 2000 /* raise types and dominates from dominated role */ 2001 ebitmap_for_each_bit(&rdp->dominates, node, i) { 2002 if (ebitmap_node_get_bit(node, i)) 2003 if (ebitmap_set_bit 2004 (&rdatum->dominates, i, TRUE)) 2005 goto oom; 2006 } 2007 ebitmap_for_each_bit(&types, node, i) { 2008 if (ebitmap_node_get_bit(node, i)) 2009 if (ebitmap_set_bit 2010 (&rdatum->types.types, i, TRUE)) 2011 goto oom; 2012 } 2013 ebitmap_destroy(&types); 2014 } 2015 2016 /* go through all the roles */ 2017 return 0; 2018 oom: 2019 yyerror("Out of memory"); 2020 return -1; 2021 } 2022 2023 role_datum_t *define_role_dom(role_datum_t * r) 2024 { 2025 role_datum_t *role; 2026 char *role_id; 2027 ebitmap_node_t *node; 2028 unsigned int i; 2029 int ret; 2030 2031 if (pass == 1) { 2032 role_id = queue_remove(id_queue); 2033 free(role_id); 2034 return (role_datum_t *) 1; /* any non-NULL value */ 2035 } 2036 2037 yywarn("Role dominance has been deprecated"); 2038 2039 role_id = queue_remove(id_queue); 2040 if (!is_id_in_scope(SYM_ROLES, role_id)) { 2041 yyerror2("role %s is not within scope", role_id); 2042 free(role_id); 2043 return NULL; 2044 } 2045 role = (role_datum_t *) hashtab_search(policydbp->p_roles.table, 2046 role_id); 2047 if (!role) { 2048 role = (role_datum_t *) malloc(sizeof(role_datum_t)); 2049 if (!role) { 2050 yyerror("out of memory"); 2051 free(role_id); 2052 return NULL; 2053 } 2054 memset(role, 0, sizeof(role_datum_t)); 2055 ret = 2056 declare_symbol(SYM_ROLES, (hashtab_key_t) role_id, 2057 (hashtab_datum_t) role, &role->s.value, 2058 &role->s.value); 2059 switch (ret) { 2060 case -3:{ 2061 yyerror("Out of memory!"); 2062 goto cleanup; 2063 } 2064 case -2:{ 2065 yyerror2("duplicate declaration of role %s", 2066 role_id); 2067 goto cleanup; 2068 } 2069 case -1:{ 2070 yyerror("could not declare role here"); 2071 goto cleanup; 2072 } 2073 case 0: 2074 case 1:{ 2075 break; 2076 } 2077 default:{ 2078 assert(0); /* should never get here */ 2079 } 2080 } 2081 if (ebitmap_set_bit(&role->dominates, role->s.value - 1, TRUE)) { 2082 yyerror("Out of memory!"); 2083 goto cleanup; 2084 } 2085 } 2086 if (r) { 2087 ebitmap_t types; 2088 ebitmap_init(&types); 2089 ebitmap_for_each_bit(&r->dominates, node, i) { 2090 if (ebitmap_node_get_bit(node, i)) 2091 if (ebitmap_set_bit(&role->dominates, i, TRUE)) 2092 goto oom; 2093 } 2094 if (type_set_expand(&r->types, &types, policydbp, 1)) { 2095 ebitmap_destroy(&types); 2096 return NULL; 2097 } 2098 ebitmap_for_each_bit(&types, node, i) { 2099 if (ebitmap_node_get_bit(node, i)) 2100 if (ebitmap_set_bit 2101 (&role->types.types, i, TRUE)) 2102 goto oom; 2103 } 2104 ebitmap_destroy(&types); 2105 if (!r->s.value) { 2106 /* free intermediate result */ 2107 type_set_destroy(&r->types); 2108 ebitmap_destroy(&r->dominates); 2109 free(r); 2110 } 2111 /* 2112 * Now go through all the roles and escalate this role's 2113 * dominates and types if a role dominates this role. 2114 */ 2115 hashtab_map(policydbp->p_roles.table, 2116 dominate_role_recheck, role); 2117 } 2118 return role; 2119 cleanup: 2120 free(role_id); 2121 role_datum_destroy(role); 2122 free(role); 2123 return NULL; 2124 oom: 2125 yyerror("Out of memory"); 2126 goto cleanup; 2127 } 2128 2129 static int role_val_to_name_helper(hashtab_key_t key, hashtab_datum_t datum, 2130 void *p) 2131 { 2132 struct val_to_name *v = p; 2133 role_datum_t *roldatum; 2134 2135 roldatum = (role_datum_t *) datum; 2136 2137 if (v->val == roldatum->s.value) { 2138 v->name = key; 2139 return 1; 2140 } 2141 2142 return 0; 2143 } 2144 2145 static char *role_val_to_name(unsigned int val) 2146 { 2147 struct val_to_name v; 2148 int rc; 2149 2150 v.val = val; 2151 rc = hashtab_map(policydbp->p_roles.table, role_val_to_name_helper, &v); 2152 if (rc) 2153 return v.name; 2154 return NULL; 2155 } 2156 2157 static int set_roles(role_set_t * set, char *id) 2158 { 2159 role_datum_t *r; 2160 2161 if (strcmp(id, "*") == 0) { 2162 free(id); 2163 yyerror("* is not allowed for role sets"); 2164 return -1; 2165 } 2166 2167 if (strcmp(id, "~") == 0) { 2168 free(id); 2169 yyerror("~ is not allowed for role sets"); 2170 return -1; 2171 } 2172 if (!is_id_in_scope(SYM_ROLES, id)) { 2173 yyerror2("role %s is not within scope", id); 2174 free(id); 2175 return -1; 2176 } 2177 r = hashtab_search(policydbp->p_roles.table, id); 2178 if (!r) { 2179 yyerror2("unknown role %s", id); 2180 free(id); 2181 return -1; 2182 } 2183 2184 if (ebitmap_set_bit(&set->roles, r->s.value - 1, TRUE)) { 2185 yyerror("out of memory"); 2186 free(id); 2187 return -1; 2188 } 2189 free(id); 2190 return 0; 2191 } 2192 2193 int define_role_trans(int class_specified) 2194 { 2195 char *id; 2196 role_datum_t *role; 2197 role_set_t roles; 2198 type_set_t types; 2199 class_datum_t *cladatum; 2200 ebitmap_t e_types, e_roles, e_classes; 2201 ebitmap_node_t *tnode, *rnode, *cnode; 2202 struct role_trans *tr = NULL; 2203 struct role_trans_rule *rule = NULL; 2204 unsigned int i, j, k; 2205 int add = 1; 2206 2207 if (pass == 1) { 2208 while ((id = queue_remove(id_queue))) 2209 free(id); 2210 while ((id = queue_remove(id_queue))) 2211 free(id); 2212 if (class_specified) 2213 while ((id = queue_remove(id_queue))) 2214 free(id); 2215 id = queue_remove(id_queue); 2216 free(id); 2217 return 0; 2218 } 2219 2220 role_set_init(&roles); 2221 ebitmap_init(&e_roles); 2222 type_set_init(&types); 2223 ebitmap_init(&e_types); 2224 ebitmap_init(&e_classes); 2225 2226 while ((id = queue_remove(id_queue))) { 2227 if (set_roles(&roles, id)) 2228 return -1; 2229 } 2230 add = 1; 2231 while ((id = queue_remove(id_queue))) { 2232 if (set_types(&types, id, &add, 0)) 2233 return -1; 2234 } 2235 2236 if (class_specified) { 2237 if (read_classes(&e_classes)) 2238 return -1; 2239 } else { 2240 cladatum = hashtab_search(policydbp->p_classes.table, 2241 "process"); 2242 if (!cladatum) { 2243 yyerror2("could not find process class for " 2244 "legacy role_transition statement"); 2245 return -1; 2246 } 2247 2248 ebitmap_set_bit(&e_classes, cladatum->s.value - 1, TRUE); 2249 } 2250 2251 id = (char *)queue_remove(id_queue); 2252 if (!id) { 2253 yyerror("no new role in transition definition?"); 2254 goto bad; 2255 } 2256 if (!is_id_in_scope(SYM_ROLES, id)) { 2257 yyerror2("role %s is not within scope", id); 2258 free(id); 2259 goto bad; 2260 } 2261 role = hashtab_search(policydbp->p_roles.table, id); 2262 if (!role) { 2263 yyerror2("unknown role %s used in transition definition", id); 2264 goto bad; 2265 } 2266 2267 if (role->flavor != ROLE_ROLE) { 2268 yyerror2("the new role %s must be a regular role", id); 2269 goto bad; 2270 } 2271 2272 /* This ebitmap business is just to ensure that there are not conflicting role_trans rules */ 2273 if (role_set_expand(&roles, &e_roles, policydbp, NULL, NULL)) 2274 goto bad; 2275 2276 if (type_set_expand(&types, &e_types, policydbp, 1)) 2277 goto bad; 2278 2279 ebitmap_for_each_bit(&e_roles, rnode, i) { 2280 if (!ebitmap_node_get_bit(rnode, i)) 2281 continue; 2282 ebitmap_for_each_bit(&e_types, tnode, j) { 2283 if (!ebitmap_node_get_bit(tnode, j)) 2284 continue; 2285 ebitmap_for_each_bit(&e_classes, cnode, k) { 2286 if (!ebitmap_node_get_bit(cnode, k)) 2287 continue; 2288 for (tr = policydbp->role_tr; tr; 2289 tr = tr->next) { 2290 if (tr->role == (i + 1) && 2291 tr->type == (j + 1) && 2292 tr->tclass == (k + 1)) { 2293 yyerror2("duplicate role " 2294 "transition for " 2295 "(%s,%s,%s)", 2296 role_val_to_name(i+1), 2297 policydbp->p_type_val_to_name[j], 2298 policydbp->p_class_val_to_name[k]); 2299 goto bad; 2300 } 2301 } 2302 2303 tr = malloc(sizeof(struct role_trans)); 2304 if (!tr) { 2305 yyerror("out of memory"); 2306 return -1; 2307 } 2308 memset(tr, 0, sizeof(struct role_trans)); 2309 tr->role = i + 1; 2310 tr->type = j + 1; 2311 tr->tclass = k + 1; 2312 tr->new_role = role->s.value; 2313 tr->next = policydbp->role_tr; 2314 policydbp->role_tr = tr; 2315 } 2316 } 2317 } 2318 /* Now add the real rule */ 2319 rule = malloc(sizeof(struct role_trans_rule)); 2320 if (!rule) { 2321 yyerror("out of memory"); 2322 return -1; 2323 } 2324 memset(rule, 0, sizeof(struct role_trans_rule)); 2325 rule->roles = roles; 2326 rule->types = types; 2327 rule->classes = e_classes; 2328 rule->new_role = role->s.value; 2329 2330 append_role_trans(rule); 2331 2332 ebitmap_destroy(&e_roles); 2333 ebitmap_destroy(&e_types); 2334 2335 return 0; 2336 2337 bad: 2338 return -1; 2339 } 2340 2341 int define_role_allow(void) 2342 { 2343 char *id; 2344 struct role_allow_rule *ra = 0; 2345 2346 if (pass == 1) { 2347 while ((id = queue_remove(id_queue))) 2348 free(id); 2349 while ((id = queue_remove(id_queue))) 2350 free(id); 2351 return 0; 2352 } 2353 2354 ra = malloc(sizeof(role_allow_rule_t)); 2355 if (!ra) { 2356 yyerror("out of memory"); 2357 return -1; 2358 } 2359 role_allow_rule_init(ra); 2360 2361 while ((id = queue_remove(id_queue))) { 2362 if (set_roles(&ra->roles, id)) 2363 return -1; 2364 } 2365 2366 while ((id = queue_remove(id_queue))) { 2367 if (set_roles(&ra->new_roles, id)) 2368 return -1; 2369 } 2370 2371 append_role_allow(ra); 2372 return 0; 2373 } 2374 2375 avrule_t *define_cond_filename_trans(void) 2376 { 2377 yyerror("type transitions with a filename not allowed inside " 2378 "conditionals\n"); 2379 return COND_ERR; 2380 } 2381 2382 int define_filename_trans(void) 2383 { 2384 char *id, *name = NULL; 2385 type_set_t stypes, ttypes; 2386 ebitmap_t e_stypes, e_ttypes; 2387 ebitmap_t e_tclasses; 2388 ebitmap_node_t *snode, *tnode, *cnode; 2389 filename_trans_t *ft; 2390 filename_trans_rule_t *ftr; 2391 type_datum_t *typdatum; 2392 uint32_t otype; 2393 unsigned int c, s, t; 2394 int add; 2395 2396 if (pass == 1) { 2397 /* stype */ 2398 while ((id = queue_remove(id_queue))) 2399 free(id); 2400 /* ttype */ 2401 while ((id = queue_remove(id_queue))) 2402 free(id); 2403 /* tclass */ 2404 while ((id = queue_remove(id_queue))) 2405 free(id); 2406 /* otype */ 2407 id = queue_remove(id_queue); 2408 free(id); 2409 /* name */ 2410 id = queue_remove(id_queue); 2411 free(id); 2412 return 0; 2413 } 2414 2415 2416 add = 1; 2417 type_set_init(&stypes); 2418 while ((id = queue_remove(id_queue))) { 2419 if (set_types(&stypes, id, &add, 0)) 2420 goto bad; 2421 } 2422 2423 add =1; 2424 type_set_init(&ttypes); 2425 while ((id = queue_remove(id_queue))) { 2426 if (set_types(&ttypes, id, &add, 0)) 2427 goto bad; 2428 } 2429 2430 ebitmap_init(&e_tclasses); 2431 if (read_classes(&e_tclasses)) 2432 goto bad; 2433 2434 id = (char *)queue_remove(id_queue); 2435 if (!id) { 2436 yyerror("no otype in transition definition?"); 2437 goto bad; 2438 } 2439 if (!is_id_in_scope(SYM_TYPES, id)) { 2440 yyerror2("type %s is not within scope", id); 2441 free(id); 2442 goto bad; 2443 } 2444 typdatum = hashtab_search(policydbp->p_types.table, id); 2445 if (!typdatum) { 2446 yyerror2("unknown type %s used in transition definition", id); 2447 goto bad; 2448 } 2449 free(id); 2450 otype = typdatum->s.value; 2451 2452 name = queue_remove(id_queue); 2453 if (!name) { 2454 yyerror("no pathname specified in filename_trans definition?"); 2455 goto bad; 2456 } 2457 2458 /* We expand the class set into seperate rules. We expand the types 2459 * just to make sure there are not duplicates. They will get turned 2460 * into seperate rules later */ 2461 ebitmap_init(&e_stypes); 2462 if (type_set_expand(&stypes, &e_stypes, policydbp, 1)) 2463 goto bad; 2464 2465 ebitmap_init(&e_ttypes); 2466 if (type_set_expand(&ttypes, &e_ttypes, policydbp, 1)) 2467 goto bad; 2468 2469 ebitmap_for_each_bit(&e_tclasses, cnode, c) { 2470 if (!ebitmap_node_get_bit(cnode, c)) 2471 continue; 2472 ebitmap_for_each_bit(&e_stypes, snode, s) { 2473 if (!ebitmap_node_get_bit(snode, s)) 2474 continue; 2475 ebitmap_for_each_bit(&e_ttypes, tnode, t) { 2476 if (!ebitmap_node_get_bit(tnode, t)) 2477 continue; 2478 2479 for (ft = policydbp->filename_trans; ft; ft = ft->next) { 2480 if (ft->stype == (s + 1) && 2481 ft->ttype == (t + 1) && 2482 ft->tclass == (c + 1) && 2483 !strcmp(ft->name, name)) { 2484 yyerror2("duplicate filename transition for: filename_trans %s %s %s:%s", 2485 name, 2486 policydbp->p_type_val_to_name[s], 2487 policydbp->p_type_val_to_name[t], 2488 policydbp->p_class_val_to_name[c]); 2489 goto bad; 2490 } 2491 } 2492 2493 ft = malloc(sizeof(*ft)); 2494 if (!ft) { 2495 yyerror("out of memory"); 2496 goto bad; 2497 } 2498 memset(ft, 0, sizeof(*ft)); 2499 2500 ft->next = policydbp->filename_trans; 2501 policydbp->filename_trans = ft; 2502 2503 ft->name = strdup(name); 2504 if (!ft->name) { 2505 yyerror("out of memory"); 2506 goto bad; 2507 } 2508 ft->stype = s + 1; 2509 ft->ttype = t + 1; 2510 ft->tclass = c + 1; 2511 ft->otype = otype; 2512 } 2513 } 2514 2515 /* Now add the real rule since we didn't find any duplicates */ 2516 ftr = malloc(sizeof(*ftr)); 2517 if (!ftr) { 2518 yyerror("out of memory"); 2519 goto bad; 2520 } 2521 filename_trans_rule_init(ftr); 2522 append_filename_trans(ftr); 2523 2524 ftr->name = strdup(name); 2525 ftr->stypes = stypes; 2526 ftr->ttypes = ttypes; 2527 ftr->tclass = c + 1; 2528 ftr->otype = otype; 2529 } 2530 2531 free(name); 2532 ebitmap_destroy(&e_stypes); 2533 ebitmap_destroy(&e_ttypes); 2534 ebitmap_destroy(&e_tclasses); 2535 2536 return 0; 2537 2538 bad: 2539 free(name); 2540 return -1; 2541 } 2542 2543 static constraint_expr_t *constraint_expr_clone(constraint_expr_t * expr) 2544 { 2545 constraint_expr_t *h = NULL, *l = NULL, *e, *newe; 2546 for (e = expr; e; e = e->next) { 2547 newe = malloc(sizeof(*newe)); 2548 if (!newe) 2549 goto oom; 2550 if (constraint_expr_init(newe) == -1) { 2551 free(newe); 2552 goto oom; 2553 } 2554 if (l) 2555 l->next = newe; 2556 else 2557 h = newe; 2558 l = newe; 2559 newe->expr_type = e->expr_type; 2560 newe->attr = e->attr; 2561 newe->op = e->op; 2562 if (newe->expr_type == CEXPR_NAMES) { 2563 if (newe->attr & CEXPR_TYPE) { 2564 if (type_set_cpy 2565 (newe->type_names, e->type_names)) 2566 goto oom; 2567 } else { 2568 if (ebitmap_cpy(&newe->names, &e->names)) 2569 goto oom; 2570 } 2571 } 2572 } 2573 2574 return h; 2575 oom: 2576 e = h; 2577 while (e) { 2578 l = e; 2579 e = e->next; 2580 constraint_expr_destroy(l); 2581 } 2582 return NULL; 2583 } 2584 2585 int define_constraint(constraint_expr_t * expr) 2586 { 2587 struct constraint_node *node; 2588 char *id; 2589 class_datum_t *cladatum; 2590 perm_datum_t *perdatum; 2591 ebitmap_t classmap; 2592 ebitmap_node_t *enode; 2593 constraint_expr_t *e; 2594 unsigned int i; 2595 int depth; 2596 unsigned char useexpr = 1; 2597 2598 if (pass == 1) { 2599 while ((id = queue_remove(id_queue))) 2600 free(id); 2601 while ((id = queue_remove(id_queue))) 2602 free(id); 2603 return 0; 2604 } 2605 2606 depth = -1; 2607 for (e = expr; e; e = e->next) { 2608 switch (e->expr_type) { 2609 case CEXPR_NOT: 2610 if (depth < 0) { 2611 yyerror("illegal constraint expression"); 2612 return -1; 2613 } 2614 break; 2615 case CEXPR_AND: 2616 case CEXPR_OR: 2617 if (depth < 1) { 2618 yyerror("illegal constraint expression"); 2619 return -1; 2620 } 2621 depth--; 2622 break; 2623 case CEXPR_ATTR: 2624 case CEXPR_NAMES: 2625 if (e->attr & CEXPR_XTARGET) { 2626 yyerror("illegal constraint expression"); 2627 return -1; /* only for validatetrans rules */ 2628 } 2629 if (depth == (CEXPR_MAXDEPTH - 1)) { 2630 yyerror("constraint expression is too deep"); 2631 return -1; 2632 } 2633 depth++; 2634 break; 2635 default: 2636 yyerror("illegal constraint expression"); 2637 return -1; 2638 } 2639 } 2640 if (depth != 0) { 2641 yyerror("illegal constraint expression"); 2642 return -1; 2643 } 2644 2645 ebitmap_init(&classmap); 2646 while ((id = queue_remove(id_queue))) { 2647 if (!is_id_in_scope(SYM_CLASSES, id)) { 2648 yyerror2("class %s is not within scope", id); 2649 free(id); 2650 return -1; 2651 } 2652 cladatum = 2653 (class_datum_t *) hashtab_search(policydbp->p_classes.table, 2654 (hashtab_key_t) id); 2655 if (!cladatum) { 2656 yyerror2("class %s is not defined", id); 2657 ebitmap_destroy(&classmap); 2658 free(id); 2659 return -1; 2660 } 2661 if (ebitmap_set_bit(&classmap, cladatum->s.value - 1, TRUE)) { 2662 yyerror("out of memory"); 2663 ebitmap_destroy(&classmap); 2664 free(id); 2665 return -1; 2666 } 2667 node = malloc(sizeof(struct constraint_node)); 2668 if (!node) { 2669 yyerror("out of memory"); 2670 return -1; 2671 } 2672 memset(node, 0, sizeof(constraint_node_t)); 2673 if (useexpr) { 2674 node->expr = expr; 2675 useexpr = 0; 2676 } else { 2677 node->expr = constraint_expr_clone(expr); 2678 } 2679 if (!node->expr) { 2680 yyerror("out of memory"); 2681 return -1; 2682 } 2683 node->permissions = 0; 2684 2685 node->next = cladatum->constraints; 2686 cladatum->constraints = node; 2687 2688 free(id); 2689 } 2690 2691 while ((id = queue_remove(id_queue))) { 2692 ebitmap_for_each_bit(&classmap, enode, i) { 2693 if (ebitmap_node_get_bit(enode, i)) { 2694 cladatum = policydbp->class_val_to_struct[i]; 2695 node = cladatum->constraints; 2696 2697 perdatum = 2698 (perm_datum_t *) hashtab_search(cladatum-> 2699 permissions. 2700 table, 2701 (hashtab_key_t) 2702 id); 2703 if (!perdatum) { 2704 if (cladatum->comdatum) { 2705 perdatum = 2706 (perm_datum_t *) 2707 hashtab_search(cladatum-> 2708 comdatum-> 2709 permissions. 2710 table, 2711 (hashtab_key_t) 2712 id); 2713 } 2714 if (!perdatum) { 2715 yyerror2("permission %s is not" 2716 " defined", id); 2717 free(id); 2718 ebitmap_destroy(&classmap); 2719 return -1; 2720 } 2721 } 2722 node->permissions |= 2723 (1 << (perdatum->s.value - 1)); 2724 } 2725 } 2726 free(id); 2727 } 2728 2729 ebitmap_destroy(&classmap); 2730 2731 return 0; 2732 } 2733 2734 int define_validatetrans(constraint_expr_t * expr) 2735 { 2736 struct constraint_node *node; 2737 char *id; 2738 class_datum_t *cladatum; 2739 ebitmap_t classmap; 2740 constraint_expr_t *e; 2741 int depth; 2742 unsigned char useexpr = 1; 2743 2744 if (pass == 1) { 2745 while ((id = queue_remove(id_queue))) 2746 free(id); 2747 return 0; 2748 } 2749 2750 depth = -1; 2751 for (e = expr; e; e = e->next) { 2752 switch (e->expr_type) { 2753 case CEXPR_NOT: 2754 if (depth < 0) { 2755 yyerror("illegal validatetrans expression"); 2756 return -1; 2757 } 2758 break; 2759 case CEXPR_AND: 2760 case CEXPR_OR: 2761 if (depth < 1) { 2762 yyerror("illegal validatetrans expression"); 2763 return -1; 2764 } 2765 depth--; 2766 break; 2767 case CEXPR_ATTR: 2768 case CEXPR_NAMES: 2769 if (depth == (CEXPR_MAXDEPTH - 1)) { 2770 yyerror("validatetrans expression is too deep"); 2771 return -1; 2772 } 2773 depth++; 2774 break; 2775 default: 2776 yyerror("illegal validatetrans expression"); 2777 return -1; 2778 } 2779 } 2780 if (depth != 0) { 2781 yyerror("illegal validatetrans expression"); 2782 return -1; 2783 } 2784 2785 ebitmap_init(&classmap); 2786 while ((id = queue_remove(id_queue))) { 2787 if (!is_id_in_scope(SYM_CLASSES, id)) { 2788 yyerror2("class %s is not within scope", id); 2789 free(id); 2790 return -1; 2791 } 2792 cladatum = 2793 (class_datum_t *) hashtab_search(policydbp->p_classes.table, 2794 (hashtab_key_t) id); 2795 if (!cladatum) { 2796 yyerror2("class %s is not defined", id); 2797 ebitmap_destroy(&classmap); 2798 free(id); 2799 return -1; 2800 } 2801 if (ebitmap_set_bit(&classmap, (cladatum->s.value - 1), TRUE)) { 2802 yyerror("out of memory"); 2803 ebitmap_destroy(&classmap); 2804 free(id); 2805 return -1; 2806 } 2807 2808 node = malloc(sizeof(struct constraint_node)); 2809 if (!node) { 2810 yyerror("out of memory"); 2811 return -1; 2812 } 2813 memset(node, 0, sizeof(constraint_node_t)); 2814 if (useexpr) { 2815 node->expr = expr; 2816 useexpr = 0; 2817 } else { 2818 node->expr = constraint_expr_clone(expr); 2819 } 2820 node->permissions = 0; 2821 2822 node->next = cladatum->validatetrans; 2823 cladatum->validatetrans = node; 2824 2825 free(id); 2826 } 2827 2828 ebitmap_destroy(&classmap); 2829 2830 return 0; 2831 } 2832 2833 uintptr_t define_cexpr(uint32_t expr_type, uintptr_t arg1, uintptr_t arg2) 2834 { 2835 struct constraint_expr *expr, *e1 = NULL, *e2; 2836 user_datum_t *user; 2837 role_datum_t *role; 2838 ebitmap_t negset; 2839 char *id; 2840 uint32_t val; 2841 int add = 1; 2842 2843 if (pass == 1) { 2844 if (expr_type == CEXPR_NAMES) { 2845 while ((id = queue_remove(id_queue))) 2846 free(id); 2847 } 2848 return 1; /* any non-NULL value */ 2849 } 2850 2851 if ((expr = malloc(sizeof(*expr))) == NULL || 2852 constraint_expr_init(expr) == -1) { 2853 yyerror("out of memory"); 2854 free(expr); 2855 return 0; 2856 } 2857 expr->expr_type = expr_type; 2858 2859 switch (expr_type) { 2860 case CEXPR_NOT: 2861 e1 = NULL; 2862 e2 = (struct constraint_expr *)arg1; 2863 while (e2) { 2864 e1 = e2; 2865 e2 = e2->next; 2866 } 2867 if (!e1 || e1->next) { 2868 yyerror("illegal constraint expression"); 2869 constraint_expr_destroy(expr); 2870 return 0; 2871 } 2872 e1->next = expr; 2873 return arg1; 2874 case CEXPR_AND: 2875 case CEXPR_OR: 2876 e1 = NULL; 2877 e2 = (struct constraint_expr *)arg1; 2878 while (e2) { 2879 e1 = e2; 2880 e2 = e2->next; 2881 } 2882 if (!e1 || e1->next) { 2883 yyerror("illegal constraint expression"); 2884 constraint_expr_destroy(expr); 2885 return 0; 2886 } 2887 e1->next = (struct constraint_expr *)arg2; 2888 2889 e1 = NULL; 2890 e2 = (struct constraint_expr *)arg2; 2891 while (e2) { 2892 e1 = e2; 2893 e2 = e2->next; 2894 } 2895 if (!e1 || e1->next) { 2896 yyerror("illegal constraint expression"); 2897 constraint_expr_destroy(expr); 2898 return 0; 2899 } 2900 e1->next = expr; 2901 return arg1; 2902 case CEXPR_ATTR: 2903 expr->attr = arg1; 2904 expr->op = arg2; 2905 return (uintptr_t) expr; 2906 case CEXPR_NAMES: 2907 add = 1; 2908 expr->attr = arg1; 2909 expr->op = arg2; 2910 ebitmap_init(&negset); 2911 while ((id = (char *)queue_remove(id_queue))) { 2912 if (expr->attr & CEXPR_USER) { 2913 if (!is_id_in_scope(SYM_USERS, id)) { 2914 yyerror2("user %s is not within scope", 2915 id); 2916 constraint_expr_destroy(expr); 2917 return 0; 2918 } 2919 user = 2920 (user_datum_t *) hashtab_search(policydbp-> 2921 p_users. 2922 table, 2923 (hashtab_key_t) 2924 id); 2925 if (!user) { 2926 yyerror2("unknown user %s", id); 2927 constraint_expr_destroy(expr); 2928 return 0; 2929 } 2930 val = user->s.value; 2931 } else if (expr->attr & CEXPR_ROLE) { 2932 if (!is_id_in_scope(SYM_ROLES, id)) { 2933 yyerror2("role %s is not within scope", 2934 id); 2935 constraint_expr_destroy(expr); 2936 return 0; 2937 } 2938 role = 2939 (role_datum_t *) hashtab_search(policydbp-> 2940 p_roles. 2941 table, 2942 (hashtab_key_t) 2943 id); 2944 if (!role) { 2945 yyerror2("unknown role %s", id); 2946 constraint_expr_destroy(expr); 2947 return 0; 2948 } 2949 val = role->s.value; 2950 } else if (expr->attr & CEXPR_TYPE) { 2951 if (set_types(expr->type_names, id, &add, 0)) { 2952 constraint_expr_destroy(expr); 2953 return 0; 2954 } 2955 continue; 2956 } else { 2957 yyerror("invalid constraint expression"); 2958 constraint_expr_destroy(expr); 2959 return 0; 2960 } 2961 if (ebitmap_set_bit(&expr->names, val - 1, TRUE)) { 2962 yyerror("out of memory"); 2963 ebitmap_destroy(&expr->names); 2964 constraint_expr_destroy(expr); 2965 return 0; 2966 } 2967 free(id); 2968 } 2969 ebitmap_destroy(&negset); 2970 return (uintptr_t) expr; 2971 default: 2972 yyerror("invalid constraint expression"); 2973 constraint_expr_destroy(expr); 2974 return 0; 2975 } 2976 2977 yyerror("invalid constraint expression"); 2978 free(expr); 2979 return 0; 2980 } 2981 2982 int define_conditional(cond_expr_t * expr, avrule_t * t, avrule_t * f) 2983 { 2984 cond_expr_t *e; 2985 int depth; 2986 cond_node_t cn, *cn_old; 2987 2988 /* expression cannot be NULL */ 2989 if (!expr) { 2990 yyerror("illegal conditional expression"); 2991 return -1; 2992 } 2993 if (!t) { 2994 if (!f) { 2995 /* empty is fine, destroy expression and return */ 2996 cond_expr_destroy(expr); 2997 return 0; 2998 } 2999 /* Invert */ 3000 t = f; 3001 f = 0; 3002 expr = define_cond_expr(COND_NOT, expr, 0); 3003 if (!expr) { 3004 yyerror("unable to invert"); 3005 return -1; 3006 } 3007 } 3008 3009 /* verify expression */ 3010 depth = -1; 3011 for (e = expr; e; e = e->next) { 3012 switch (e->expr_type) { 3013 case COND_NOT: 3014 if (depth < 0) { 3015 yyerror 3016 ("illegal conditional expression; Bad NOT"); 3017 return -1; 3018 } 3019 break; 3020 case COND_AND: 3021 case COND_OR: 3022 case COND_XOR: 3023 case COND_EQ: 3024 case COND_NEQ: 3025 if (depth < 1) { 3026 yyerror 3027 ("illegal conditional expression; Bad binary op"); 3028 return -1; 3029 } 3030 depth--; 3031 break; 3032 case COND_BOOL: 3033 if (depth == (COND_EXPR_MAXDEPTH - 1)) { 3034 yyerror 3035 ("conditional expression is like totally too deep"); 3036 return -1; 3037 } 3038 depth++; 3039 break; 3040 default: 3041 yyerror("illegal conditional expression"); 3042 return -1; 3043 } 3044 } 3045 if (depth != 0) { 3046 yyerror("illegal conditional expression"); 3047 return -1; 3048 } 3049 3050 /* use tmp conditional node to partially build new node */ 3051 memset(&cn, 0, sizeof(cn)); 3052 cn.expr = expr; 3053 cn.avtrue_list = t; 3054 cn.avfalse_list = f; 3055 3056 /* normalize/precompute expression */ 3057 if (cond_normalize_expr(policydbp, &cn) < 0) { 3058 yyerror("problem normalizing conditional expression"); 3059 return -1; 3060 } 3061 3062 /* get the existing conditional node, or create a new one */ 3063 cn_old = get_current_cond_list(&cn); 3064 if (!cn_old) { 3065 return -1; 3066 } 3067 3068 append_cond_list(&cn); 3069 3070 /* note that there is no check here for duplicate rules, nor 3071 * check that rule already exists in base -- that will be 3072 * handled during conditional expansion, in expand.c */ 3073 3074 cn.avtrue_list = NULL; 3075 cn.avfalse_list = NULL; 3076 cond_node_destroy(&cn); 3077 3078 return 0; 3079 } 3080 3081 cond_expr_t *define_cond_expr(uint32_t expr_type, void *arg1, void *arg2) 3082 { 3083 struct cond_expr *expr, *e1 = NULL, *e2; 3084 cond_bool_datum_t *bool_var; 3085 char *id; 3086 3087 /* expressions are handled in the second pass */ 3088 if (pass == 1) { 3089 if (expr_type == COND_BOOL) { 3090 while ((id = queue_remove(id_queue))) { 3091 free(id); 3092 } 3093 } 3094 return (cond_expr_t *) 1; /* any non-NULL value */ 3095 } 3096 3097 /* create a new expression struct */ 3098 expr = malloc(sizeof(struct cond_expr)); 3099 if (!expr) { 3100 yyerror("out of memory"); 3101 return NULL; 3102 } 3103 memset(expr, 0, sizeof(cond_expr_t)); 3104 expr->expr_type = expr_type; 3105 3106 /* create the type asked for */ 3107 switch (expr_type) { 3108 case COND_NOT: 3109 e1 = NULL; 3110 e2 = (struct cond_expr *)arg1; 3111 while (e2) { 3112 e1 = e2; 3113 e2 = e2->next; 3114 } 3115 if (!e1 || e1->next) { 3116 yyerror("illegal conditional NOT expression"); 3117 free(expr); 3118 return NULL; 3119 } 3120 e1->next = expr; 3121 return (struct cond_expr *)arg1; 3122 case COND_AND: 3123 case COND_OR: 3124 case COND_XOR: 3125 case COND_EQ: 3126 case COND_NEQ: 3127 e1 = NULL; 3128 e2 = (struct cond_expr *)arg1; 3129 while (e2) { 3130 e1 = e2; 3131 e2 = e2->next; 3132 } 3133 if (!e1 || e1->next) { 3134 yyerror 3135 ("illegal left side of conditional binary op expression"); 3136 free(expr); 3137 return NULL; 3138 } 3139 e1->next = (struct cond_expr *)arg2; 3140 3141 e1 = NULL; 3142 e2 = (struct cond_expr *)arg2; 3143 while (e2) { 3144 e1 = e2; 3145 e2 = e2->next; 3146 } 3147 if (!e1 || e1->next) { 3148 yyerror 3149 ("illegal right side of conditional binary op expression"); 3150 free(expr); 3151 return NULL; 3152 } 3153 e1->next = expr; 3154 return (struct cond_expr *)arg1; 3155 case COND_BOOL: 3156 id = (char *)queue_remove(id_queue); 3157 if (!id) { 3158 yyerror("bad conditional; expected boolean id"); 3159 free(id); 3160 free(expr); 3161 return NULL; 3162 } 3163 if (!is_id_in_scope(SYM_BOOLS, id)) { 3164 yyerror2("boolean %s is not within scope", id); 3165 free(id); 3166 free(expr); 3167 return NULL; 3168 } 3169 bool_var = 3170 (cond_bool_datum_t *) hashtab_search(policydbp->p_bools. 3171 table, 3172 (hashtab_key_t) id); 3173 if (!bool_var) { 3174 yyerror2("unknown boolean %s in conditional expression", 3175 id); 3176 free(expr); 3177 free(id); 3178 return NULL; 3179 } 3180 expr->bool = bool_var->s.value; 3181 free(id); 3182 return expr; 3183 default: 3184 yyerror("illegal conditional expression"); 3185 return NULL; 3186 } 3187 } 3188 3189 static int set_user_roles(role_set_t * set, char *id) 3190 { 3191 role_datum_t *r; 3192 unsigned int i; 3193 ebitmap_node_t *node; 3194 3195 if (strcmp(id, "*") == 0) { 3196 free(id); 3197 yyerror("* is not allowed in user declarations"); 3198 return -1; 3199 } 3200 3201 if (strcmp(id, "~") == 0) { 3202 free(id); 3203 yyerror("~ is not allowed in user declarations"); 3204 return -1; 3205 } 3206 3207 if (!is_id_in_scope(SYM_ROLES, id)) { 3208 yyerror2("role %s is not within scope", id); 3209 free(id); 3210 return -1; 3211 } 3212 r = hashtab_search(policydbp->p_roles.table, id); 3213 if (!r) { 3214 yyerror2("unknown role %s", id); 3215 free(id); 3216 return -1; 3217 } 3218 3219 /* set the role and every role it dominates */ 3220 ebitmap_for_each_bit(&r->dominates, node, i) { 3221 if (ebitmap_node_get_bit(node, i)) 3222 if (ebitmap_set_bit(&set->roles, i, TRUE)) 3223 goto oom; 3224 } 3225 free(id); 3226 return 0; 3227 oom: 3228 yyerror("out of memory"); 3229 return -1; 3230 } 3231 3232 static int parse_categories(char *id, level_datum_t * levdatum, ebitmap_t * cats) 3233 { 3234 cat_datum_t *cdatum; 3235 int range_start, range_end, i; 3236 3237 if (id_has_dot(id)) { 3238 char *id_start = id; 3239 char *id_end = strchr(id, '.'); 3240 3241 *(id_end++) = '\0'; 3242 3243 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 3244 (hashtab_key_t) 3245 id_start); 3246 if (!cdatum) { 3247 yyerror2("unknown category %s", id_start); 3248 return -1; 3249 } 3250 range_start = cdatum->s.value - 1; 3251 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 3252 (hashtab_key_t) id_end); 3253 if (!cdatum) { 3254 yyerror2("unknown category %s", id_end); 3255 return -1; 3256 } 3257 range_end = cdatum->s.value - 1; 3258 3259 if (range_end < range_start) { 3260 yyerror2("category range is invalid"); 3261 return -1; 3262 } 3263 } else { 3264 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 3265 (hashtab_key_t) id); 3266 if (!cdatum) { 3267 yyerror2("unknown category %s", id); 3268 return -1; 3269 } 3270 range_start = range_end = cdatum->s.value - 1; 3271 } 3272 3273 for (i = range_start; i <= range_end; i++) { 3274 if (!ebitmap_get_bit(&levdatum->level->cat, i)) { 3275 uint32_t level_value = levdatum->level->sens - 1; 3276 policydb_index_others(NULL, policydbp, 0); 3277 yyerror2("category %s can not be associated " 3278 "with level %s", 3279 policydbp->p_cat_val_to_name[i], 3280 policydbp->p_sens_val_to_name[level_value]); 3281 return -1; 3282 } 3283 if (ebitmap_set_bit(cats, i, TRUE)) { 3284 yyerror("out of memory"); 3285 return -1; 3286 } 3287 } 3288 3289 return 0; 3290 } 3291 3292 static int parse_semantic_categories(char *id, level_datum_t * levdatum, 3293 mls_semantic_cat_t ** cats) 3294 { 3295 cat_datum_t *cdatum; 3296 mls_semantic_cat_t *newcat; 3297 unsigned int range_start, range_end; 3298 3299 if (id_has_dot(id)) { 3300 char *id_start = id; 3301 char *id_end = strchr(id, '.'); 3302 3303 *(id_end++) = '\0'; 3304 3305 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 3306 (hashtab_key_t) 3307 id_start); 3308 if (!cdatum) { 3309 yyerror2("unknown category %s", id_start); 3310 return -1; 3311 } 3312 range_start = cdatum->s.value; 3313 3314 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 3315 (hashtab_key_t) id_end); 3316 if (!cdatum) { 3317 yyerror2("unknown category %s", id_end); 3318 return -1; 3319 } 3320 range_end = cdatum->s.value; 3321 } else { 3322 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 3323 (hashtab_key_t) id); 3324 if (!cdatum) { 3325 yyerror2("unknown category %s", id); 3326 return -1; 3327 } 3328 range_start = range_end = cdatum->s.value; 3329 } 3330 3331 newcat = (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t)); 3332 if (!newcat) { 3333 yyerror("out of memory"); 3334 return -1; 3335 } 3336 3337 mls_semantic_cat_init(newcat); 3338 newcat->next = *cats; 3339 newcat->low = range_start; 3340 newcat->high = range_end; 3341 3342 *cats = newcat; 3343 3344 return 0; 3345 } 3346 3347 int define_user(void) 3348 { 3349 char *id; 3350 user_datum_t *usrdatum; 3351 level_datum_t *levdatum; 3352 int l; 3353 3354 if (pass == 1) { 3355 while ((id = queue_remove(id_queue))) 3356 free(id); 3357 if (mlspol) { 3358 while ((id = queue_remove(id_queue))) 3359 free(id); 3360 id = queue_remove(id_queue); 3361 free(id); 3362 for (l = 0; l < 2; l++) { 3363 while ((id = queue_remove(id_queue))) { 3364 free(id); 3365 } 3366 id = queue_remove(id_queue); 3367 if (!id) 3368 break; 3369 free(id); 3370 } 3371 } 3372 return 0; 3373 } 3374 3375 if ((usrdatum = declare_user()) == NULL) { 3376 return -1; 3377 } 3378 3379 while ((id = queue_remove(id_queue))) { 3380 if (set_user_roles(&usrdatum->roles, id)) 3381 continue; 3382 } 3383 3384 if (mlspol) { 3385 id = queue_remove(id_queue); 3386 if (!id) { 3387 yyerror("no default level specified for user"); 3388 return -1; 3389 } 3390 3391 levdatum = (level_datum_t *) 3392 hashtab_search(policydbp->p_levels.table, 3393 (hashtab_key_t) id); 3394 if (!levdatum) { 3395 yyerror2("unknown sensitivity %s used in user" 3396 " level definition", id); 3397 free(id); 3398 return -1; 3399 } 3400 free(id); 3401 3402 usrdatum->dfltlevel.sens = levdatum->level->sens; 3403 3404 while ((id = queue_remove(id_queue))) { 3405 if (parse_semantic_categories(id, levdatum, 3406 &usrdatum->dfltlevel.cat)) { 3407 free(id); 3408 return -1; 3409 } 3410 free(id); 3411 } 3412 3413 id = queue_remove(id_queue); 3414 3415 for (l = 0; l < 2; l++) { 3416 levdatum = (level_datum_t *) 3417 hashtab_search(policydbp->p_levels.table, 3418 (hashtab_key_t) id); 3419 if (!levdatum) { 3420 yyerror2("unknown sensitivity %s used in user" 3421 " range definition", id); 3422 free(id); 3423 return -1; 3424 } 3425 free(id); 3426 3427 usrdatum->range.level[l].sens = levdatum->level->sens; 3428 3429 while ((id = queue_remove(id_queue))) { 3430 if (parse_semantic_categories(id, levdatum, 3431 &usrdatum->range.level[l].cat)) { 3432 free(id); 3433 return -1; 3434 } 3435 free(id); 3436 } 3437 3438 id = queue_remove(id_queue); 3439 if (!id) 3440 break; 3441 } 3442 3443 if (l == 0) { 3444 if (mls_semantic_level_cpy(&usrdatum->range.level[1], 3445 &usrdatum->range.level[0])) { 3446 yyerror("out of memory"); 3447 return -1; 3448 } 3449 } 3450 } 3451 return 0; 3452 } 3453 3454 static int parse_security_context(context_struct_t * c) 3455 { 3456 char *id; 3457 role_datum_t *role; 3458 type_datum_t *typdatum; 3459 user_datum_t *usrdatum; 3460 level_datum_t *levdatum; 3461 int l; 3462 3463 if (pass == 1) { 3464 id = queue_remove(id_queue); 3465 free(id); /* user */ 3466 id = queue_remove(id_queue); 3467 free(id); /* role */ 3468 id = queue_remove(id_queue); 3469 free(id); /* type */ 3470 if (mlspol) { 3471 id = queue_remove(id_queue); 3472 free(id); 3473 for (l = 0; l < 2; l++) { 3474 while ((id = queue_remove(id_queue))) { 3475 free(id); 3476 } 3477 id = queue_remove(id_queue); 3478 if (!id) 3479 break; 3480 free(id); 3481 } 3482 } 3483 return 0; 3484 } 3485 3486 context_init(c); 3487 3488 /* extract the user */ 3489 id = queue_remove(id_queue); 3490 if (!id) { 3491 yyerror("no effective user?"); 3492 goto bad; 3493 } 3494 if (!is_id_in_scope(SYM_USERS, id)) { 3495 yyerror2("user %s is not within scope", id); 3496 free(id); 3497 goto bad; 3498 } 3499 usrdatum = (user_datum_t *) hashtab_search(policydbp->p_users.table, 3500 (hashtab_key_t) id); 3501 if (!usrdatum) { 3502 yyerror2("user %s is not defined", id); 3503 free(id); 3504 goto bad; 3505 } 3506 c->user = usrdatum->s.value; 3507 3508 /* no need to keep the user name */ 3509 free(id); 3510 3511 /* extract the role */ 3512 id = (char *)queue_remove(id_queue); 3513 if (!id) { 3514 yyerror("no role name for sid context definition?"); 3515 return -1; 3516 } 3517 if (!is_id_in_scope(SYM_ROLES, id)) { 3518 yyerror2("role %s is not within scope", id); 3519 free(id); 3520 return -1; 3521 } 3522 role = (role_datum_t *) hashtab_search(policydbp->p_roles.table, 3523 (hashtab_key_t) id); 3524 if (!role) { 3525 yyerror2("role %s is not defined", id); 3526 free(id); 3527 return -1; 3528 } 3529 c->role = role->s.value; 3530 3531 /* no need to keep the role name */ 3532 free(id); 3533 3534 /* extract the type */ 3535 id = (char *)queue_remove(id_queue); 3536 if (!id) { 3537 yyerror("no type name for sid context definition?"); 3538 return -1; 3539 } 3540 if (!is_id_in_scope(SYM_TYPES, id)) { 3541 yyerror2("type %s is not within scope", id); 3542 free(id); 3543 return -1; 3544 } 3545 typdatum = (type_datum_t *) hashtab_search(policydbp->p_types.table, 3546 (hashtab_key_t) id); 3547 if (!typdatum || typdatum->flavor == TYPE_ATTRIB) { 3548 yyerror2("type %s is not defined or is an attribute", id); 3549 free(id); 3550 return -1; 3551 } 3552 c->type = typdatum->s.value; 3553 3554 /* no need to keep the type name */ 3555 free(id); 3556 3557 if (mlspol) { 3558 /* extract the low sensitivity */ 3559 id = (char *)queue_head(id_queue); 3560 if (!id) { 3561 yyerror("no sensitivity name for sid context" 3562 " definition?"); 3563 return -1; 3564 } 3565 3566 id = (char *)queue_remove(id_queue); 3567 for (l = 0; l < 2; l++) { 3568 levdatum = (level_datum_t *) 3569 hashtab_search(policydbp->p_levels.table, 3570 (hashtab_key_t) id); 3571 if (!levdatum) { 3572 yyerror2("Sensitivity %s is not defined", id); 3573 free(id); 3574 return -1; 3575 } 3576 free(id); 3577 c->range.level[l].sens = levdatum->level->sens; 3578 3579 /* extract low category set */ 3580 while ((id = queue_remove(id_queue))) { 3581 if (parse_categories(id, levdatum, 3582 &c->range.level[l].cat)) { 3583 free(id); 3584 return -1; 3585 } 3586 free(id); 3587 } 3588 3589 /* extract high sensitivity */ 3590 id = (char *)queue_remove(id_queue); 3591 if (!id) 3592 break; 3593 } 3594 3595 if (l == 0) { 3596 c->range.level[1].sens = c->range.level[0].sens; 3597 if (ebitmap_cpy(&c->range.level[1].cat, 3598 &c->range.level[0].cat)) { 3599 3600 yyerror("out of memory"); 3601 goto bad; 3602 } 3603 } 3604 } 3605 3606 if (!policydb_context_isvalid(policydbp, c)) { 3607 yyerror("invalid security context"); 3608 goto bad; 3609 } 3610 return 0; 3611 3612 bad: 3613 context_destroy(c); 3614 3615 return -1; 3616 } 3617 3618 int define_initial_sid_context(void) 3619 { 3620 char *id; 3621 ocontext_t *c, *head; 3622 3623 if (pass == 1) { 3624 id = (char *)queue_remove(id_queue); 3625 free(id); 3626 parse_security_context(NULL); 3627 return 0; 3628 } 3629 3630 id = (char *)queue_remove(id_queue); 3631 if (!id) { 3632 yyerror("no sid name for SID context definition?"); 3633 return -1; 3634 } 3635 head = policydbp->ocontexts[OCON_ISID]; 3636 for (c = head; c; c = c->next) { 3637 if (!strcmp(id, c->u.name)) 3638 break; 3639 } 3640 3641 if (!c) { 3642 yyerror2("SID %s is not defined", id); 3643 free(id); 3644 return -1; 3645 } 3646 if (c->context[0].user) { 3647 yyerror2("The context for SID %s is multiply defined", id); 3648 free(id); 3649 return -1; 3650 } 3651 /* no need to keep the sid name */ 3652 free(id); 3653 3654 if (parse_security_context(&c->context[0])) 3655 return -1; 3656 3657 return 0; 3658 } 3659 3660 int define_fs_context(unsigned int major, unsigned int minor) 3661 { 3662 ocontext_t *newc, *c, *head; 3663 3664 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 3665 yyerror("fscon not supported for target"); 3666 return -1; 3667 } 3668 3669 if (pass == 1) { 3670 parse_security_context(NULL); 3671 parse_security_context(NULL); 3672 return 0; 3673 } 3674 3675 newc = (ocontext_t *) malloc(sizeof(ocontext_t)); 3676 if (!newc) { 3677 yyerror("out of memory"); 3678 return -1; 3679 } 3680 memset(newc, 0, sizeof(ocontext_t)); 3681 3682 newc->u.name = (char *)malloc(6); 3683 if (!newc->u.name) { 3684 yyerror("out of memory"); 3685 free(newc); 3686 return -1; 3687 } 3688 sprintf(newc->u.name, "%02x:%02x", major, minor); 3689 3690 if (parse_security_context(&newc->context[0])) { 3691 free(newc->u.name); 3692 free(newc); 3693 return -1; 3694 } 3695 if (parse_security_context(&newc->context[1])) { 3696 context_destroy(&newc->context[0]); 3697 free(newc->u.name); 3698 free(newc); 3699 return -1; 3700 } 3701 head = policydbp->ocontexts[OCON_FS]; 3702 3703 for (c = head; c; c = c->next) { 3704 if (!strcmp(newc->u.name, c->u.name)) { 3705 yyerror2("duplicate entry for file system %s", 3706 newc->u.name); 3707 context_destroy(&newc->context[0]); 3708 context_destroy(&newc->context[1]); 3709 free(newc->u.name); 3710 free(newc); 3711 return -1; 3712 } 3713 } 3714 3715 newc->next = head; 3716 policydbp->ocontexts[OCON_FS] = newc; 3717 3718 return 0; 3719 } 3720 3721 int define_pirq_context(unsigned int pirq) 3722 { 3723 ocontext_t *newc, *c, *l, *head; 3724 char *id; 3725 3726 if (policydbp->target_platform != SEPOL_TARGET_XEN) { 3727 yyerror("pirqcon not supported for target"); 3728 return -1; 3729 } 3730 3731 if (pass == 1) { 3732 id = (char *) queue_remove(id_queue); 3733 free(id); 3734 parse_security_context(NULL); 3735 return 0; 3736 } 3737 3738 newc = malloc(sizeof(ocontext_t)); 3739 if (!newc) { 3740 yyerror("out of memory"); 3741 return -1; 3742 } 3743 memset(newc, 0, sizeof(ocontext_t)); 3744 3745 newc->u.pirq = pirq; 3746 3747 if (parse_security_context(&newc->context[0])) { 3748 free(newc); 3749 return -1; 3750 } 3751 3752 head = policydbp->ocontexts[OCON_XEN_PIRQ]; 3753 for (l = NULL, c = head; c; l = c, c = c->next) { 3754 unsigned int pirq2; 3755 3756 pirq2 = c->u.pirq; 3757 if (pirq == pirq2) { 3758 yyerror2("duplicate pirqcon entry for %d ", pirq); 3759 goto bad; 3760 } 3761 } 3762 3763 if (l) 3764 l->next = newc; 3765 else 3766 policydbp->ocontexts[OCON_XEN_PIRQ] = newc; 3767 3768 return 0; 3769 3770 bad: 3771 free(newc); 3772 return -1; 3773 } 3774 3775 int define_iomem_context(unsigned long low, unsigned long high) 3776 { 3777 ocontext_t *newc, *c, *l, *head; 3778 char *id; 3779 3780 if (policydbp->target_platform != SEPOL_TARGET_XEN) { 3781 yyerror("iomemcon not supported for target"); 3782 return -1; 3783 } 3784 3785 if (pass == 1) { 3786 id = (char *)queue_remove(id_queue); 3787 free(id); 3788 parse_security_context(NULL); 3789 return 0; 3790 } 3791 3792 newc = malloc(sizeof(ocontext_t)); 3793 if (!newc) { 3794 yyerror("out of memory"); 3795 return -1; 3796 } 3797 memset(newc, 0, sizeof(ocontext_t)); 3798 3799 newc->u.iomem.low_iomem = low; 3800 newc->u.iomem.high_iomem = high; 3801 3802 if (low > high) { 3803 yyerror2("low memory 0x%x exceeds high memory 0x%x", low, high); 3804 free(newc); 3805 return -1; 3806 } 3807 3808 if (parse_security_context(&newc->context[0])) { 3809 free(newc); 3810 return -1; 3811 } 3812 3813 head = policydbp->ocontexts[OCON_XEN_IOMEM]; 3814 for (l = NULL, c = head; c; l = c, c = c->next) { 3815 unsigned int low2, high2; 3816 3817 low2 = c->u.iomem.low_iomem; 3818 high2 = c->u.iomem.high_iomem; 3819 if (low <= high2 && low2 <= high) { 3820 yyerror2("iomemcon entry for 0x%x-0x%x overlaps with " 3821 "earlier entry 0x%x-0x%x", low, high, 3822 low2, high2); 3823 goto bad; 3824 } 3825 } 3826 3827 if (l) 3828 l->next = newc; 3829 else 3830 policydbp->ocontexts[OCON_XEN_IOMEM] = newc; 3831 3832 return 0; 3833 3834 bad: 3835 free(newc); 3836 return -1; 3837 } 3838 3839 int define_ioport_context(unsigned long low, unsigned long high) 3840 { 3841 ocontext_t *newc, *c, *l, *head; 3842 char *id; 3843 3844 if (policydbp->target_platform != SEPOL_TARGET_XEN) { 3845 yyerror("ioportcon not supported for target"); 3846 return -1; 3847 } 3848 3849 if (pass == 1) { 3850 id = (char *)queue_remove(id_queue); 3851 free(id); 3852 parse_security_context(NULL); 3853 return 0; 3854 } 3855 3856 newc = malloc(sizeof(ocontext_t)); 3857 if (!newc) { 3858 yyerror("out of memory"); 3859 return -1; 3860 } 3861 memset(newc, 0, sizeof(ocontext_t)); 3862 3863 newc->u.ioport.low_ioport = low; 3864 newc->u.ioport.high_ioport = high; 3865 3866 if (low > high) { 3867 yyerror2("low ioport 0x%x exceeds high ioport 0x%x", low, high); 3868 free(newc); 3869 return -1; 3870 } 3871 3872 if (parse_security_context(&newc->context[0])) { 3873 free(newc); 3874 return -1; 3875 } 3876 3877 head = policydbp->ocontexts[OCON_XEN_IOPORT]; 3878 for (l = NULL, c = head; c; l = c, c = c->next) { 3879 unsigned int low2, high2; 3880 3881 low2 = c->u.ioport.low_ioport; 3882 high2 = c->u.ioport.high_ioport; 3883 if (low <= high2 && low2 <= high) { 3884 yyerror2("ioportcon entry for 0x%x-0x%x overlaps with" 3885 "earlier entry 0x%x-0x%x", low, high, 3886 low2, high2); 3887 goto bad; 3888 } 3889 } 3890 3891 if (l) 3892 l->next = newc; 3893 else 3894 policydbp->ocontexts[OCON_XEN_IOPORT] = newc; 3895 3896 return 0; 3897 3898 bad: 3899 free(newc); 3900 return -1; 3901 } 3902 3903 int define_pcidevice_context(unsigned long device) 3904 { 3905 ocontext_t *newc, *c, *l, *head; 3906 char *id; 3907 3908 if (policydbp->target_platform != SEPOL_TARGET_XEN) { 3909 yyerror("pcidevicecon not supported for target"); 3910 return -1; 3911 } 3912 3913 if (pass == 1) { 3914 id = (char *) queue_remove(id_queue); 3915 free(id); 3916 parse_security_context(NULL); 3917 return 0; 3918 } 3919 3920 newc = malloc(sizeof(ocontext_t)); 3921 if (!newc) { 3922 yyerror("out of memory"); 3923 return -1; 3924 } 3925 memset(newc, 0, sizeof(ocontext_t)); 3926 3927 newc->u.device = device; 3928 3929 if (parse_security_context(&newc->context[0])) { 3930 free(newc); 3931 return -1; 3932 } 3933 3934 head = policydbp->ocontexts[OCON_XEN_PCIDEVICE]; 3935 for (l = NULL, c = head; c; l = c, c = c->next) { 3936 unsigned int device2; 3937 3938 device2 = c->u.device; 3939 if (device == device2) { 3940 yyerror2("duplicate pcidevicecon entry for 0x%x ", 3941 device); 3942 goto bad; 3943 } 3944 } 3945 3946 if (l) 3947 l->next = newc; 3948 else 3949 policydbp->ocontexts[OCON_XEN_PCIDEVICE] = newc; 3950 3951 return 0; 3952 3953 bad: 3954 free(newc); 3955 return -1; 3956 } 3957 3958 int define_port_context(unsigned int low, unsigned int high) 3959 { 3960 ocontext_t *newc, *c, *l, *head; 3961 unsigned int protocol; 3962 char *id; 3963 3964 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 3965 yyerror("portcon not supported for target"); 3966 return -1; 3967 } 3968 3969 if (pass == 1) { 3970 id = (char *)queue_remove(id_queue); 3971 free(id); 3972 parse_security_context(NULL); 3973 return 0; 3974 } 3975 3976 newc = malloc(sizeof(ocontext_t)); 3977 if (!newc) { 3978 yyerror("out of memory"); 3979 return -1; 3980 } 3981 memset(newc, 0, sizeof(ocontext_t)); 3982 3983 id = (char *)queue_remove(id_queue); 3984 if (!id) { 3985 free(newc); 3986 return -1; 3987 } 3988 if ((strcmp(id, "tcp") == 0) || (strcmp(id, "TCP") == 0)) { 3989 protocol = IPPROTO_TCP; 3990 } else if ((strcmp(id, "udp") == 0) || (strcmp(id, "UDP") == 0)) { 3991 protocol = IPPROTO_UDP; 3992 } else { 3993 yyerror2("unrecognized protocol %s", id); 3994 free(newc); 3995 return -1; 3996 } 3997 3998 newc->u.port.protocol = protocol; 3999 newc->u.port.low_port = low; 4000 newc->u.port.high_port = high; 4001 4002 if (low > high) { 4003 yyerror2("low port %d exceeds high port %d", low, high); 4004 free(newc); 4005 return -1; 4006 } 4007 4008 if (parse_security_context(&newc->context[0])) { 4009 free(newc); 4010 return -1; 4011 } 4012 4013 /* Preserve the matching order specified in the configuration. */ 4014 head = policydbp->ocontexts[OCON_PORT]; 4015 for (l = NULL, c = head; c; l = c, c = c->next) { 4016 unsigned int prot2, low2, high2; 4017 4018 prot2 = c->u.port.protocol; 4019 low2 = c->u.port.low_port; 4020 high2 = c->u.port.high_port; 4021 if (protocol != prot2) 4022 continue; 4023 if (low == low2 && high == high2) { 4024 yyerror2("duplicate portcon entry for %s %d-%d ", id, 4025 low, high); 4026 goto bad; 4027 } 4028 if (low2 <= low && high2 >= high) { 4029 yyerror2("portcon entry for %s %d-%d hidden by earlier " 4030 "entry for %d-%d", id, low, high, low2, high2); 4031 goto bad; 4032 } 4033 } 4034 4035 if (l) 4036 l->next = newc; 4037 else 4038 policydbp->ocontexts[OCON_PORT] = newc; 4039 4040 return 0; 4041 4042 bad: 4043 free(newc); 4044 return -1; 4045 } 4046 4047 int define_netif_context(void) 4048 { 4049 ocontext_t *newc, *c, *head; 4050 4051 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 4052 yyerror("netifcon not supported for target"); 4053 return -1; 4054 } 4055 4056 if (pass == 1) { 4057 free(queue_remove(id_queue)); 4058 parse_security_context(NULL); 4059 parse_security_context(NULL); 4060 return 0; 4061 } 4062 4063 newc = (ocontext_t *) malloc(sizeof(ocontext_t)); 4064 if (!newc) { 4065 yyerror("out of memory"); 4066 return -1; 4067 } 4068 memset(newc, 0, sizeof(ocontext_t)); 4069 4070 newc->u.name = (char *)queue_remove(id_queue); 4071 if (!newc->u.name) { 4072 free(newc); 4073 return -1; 4074 } 4075 if (parse_security_context(&newc->context[0])) { 4076 free(newc->u.name); 4077 free(newc); 4078 return -1; 4079 } 4080 if (parse_security_context(&newc->context[1])) { 4081 context_destroy(&newc->context[0]); 4082 free(newc->u.name); 4083 free(newc); 4084 return -1; 4085 } 4086 head = policydbp->ocontexts[OCON_NETIF]; 4087 4088 for (c = head; c; c = c->next) { 4089 if (!strcmp(newc->u.name, c->u.name)) { 4090 yyerror2("duplicate entry for network interface %s", 4091 newc->u.name); 4092 context_destroy(&newc->context[0]); 4093 context_destroy(&newc->context[1]); 4094 free(newc->u.name); 4095 free(newc); 4096 return -1; 4097 } 4098 } 4099 4100 newc->next = head; 4101 policydbp->ocontexts[OCON_NETIF] = newc; 4102 return 0; 4103 } 4104 4105 int define_ipv4_node_context() 4106 { 4107 char *id; 4108 int rc = 0; 4109 struct in_addr addr, mask; 4110 ocontext_t *newc, *c, *l, *head; 4111 4112 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 4113 yyerror("nodecon not supported for target"); 4114 return -1; 4115 } 4116 4117 if (pass == 1) { 4118 free(queue_remove(id_queue)); 4119 free(queue_remove(id_queue)); 4120 parse_security_context(NULL); 4121 goto out; 4122 } 4123 4124 id = queue_remove(id_queue); 4125 if (!id) { 4126 yyerror("failed to read ipv4 address"); 4127 rc = -1; 4128 goto out; 4129 } 4130 4131 rc = inet_pton(AF_INET, id, &addr); 4132 free(id); 4133 if (rc < 1) { 4134 yyerror("failed to parse ipv4 address"); 4135 if (rc == 0) 4136 rc = -1; 4137 goto out; 4138 } 4139 4140 id = queue_remove(id_queue); 4141 if (!id) { 4142 yyerror("failed to read ipv4 address"); 4143 rc = -1; 4144 goto out; 4145 } 4146 4147 rc = inet_pton(AF_INET, id, &mask); 4148 free(id); 4149 if (rc < 1) { 4150 yyerror("failed to parse ipv4 mask"); 4151 if (rc == 0) 4152 rc = -1; 4153 goto out; 4154 } 4155 4156 newc = malloc(sizeof(ocontext_t)); 4157 if (!newc) { 4158 yyerror("out of memory"); 4159 rc = -1; 4160 goto out; 4161 } 4162 4163 memset(newc, 0, sizeof(ocontext_t)); 4164 newc->u.node.addr = addr.s_addr; 4165 newc->u.node.mask = mask.s_addr; 4166 4167 if (parse_security_context(&newc->context[0])) { 4168 free(newc); 4169 return -1; 4170 } 4171 4172 /* Create order of most specific to least retaining 4173 the order specified in the configuration. */ 4174 head = policydbp->ocontexts[OCON_NODE]; 4175 for (l = NULL, c = head; c; l = c, c = c->next) { 4176 if (newc->u.node.mask > c->u.node.mask) 4177 break; 4178 } 4179 4180 newc->next = c; 4181 4182 if (l) 4183 l->next = newc; 4184 else 4185 policydbp->ocontexts[OCON_NODE] = newc; 4186 rc = 0; 4187 out: 4188 return rc; 4189 } 4190 4191 int define_ipv6_node_context(void) 4192 { 4193 char *id; 4194 int rc = 0; 4195 struct in6_addr addr, mask; 4196 ocontext_t *newc, *c, *l, *head; 4197 4198 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 4199 yyerror("nodecon not supported for target"); 4200 return -1; 4201 } 4202 4203 if (pass == 1) { 4204 free(queue_remove(id_queue)); 4205 free(queue_remove(id_queue)); 4206 parse_security_context(NULL); 4207 goto out; 4208 } 4209 4210 id = queue_remove(id_queue); 4211 if (!id) { 4212 yyerror("failed to read ipv6 address"); 4213 rc = -1; 4214 goto out; 4215 } 4216 4217 rc = inet_pton(AF_INET6, id, &addr); 4218 free(id); 4219 if (rc < 1) { 4220 yyerror("failed to parse ipv6 address"); 4221 if (rc == 0) 4222 rc = -1; 4223 goto out; 4224 } 4225 4226 id = queue_remove(id_queue); 4227 if (!id) { 4228 yyerror("failed to read ipv6 address"); 4229 rc = -1; 4230 goto out; 4231 } 4232 4233 rc = inet_pton(AF_INET6, id, &mask); 4234 free(id); 4235 if (rc < 1) { 4236 yyerror("failed to parse ipv6 mask"); 4237 if (rc == 0) 4238 rc = -1; 4239 goto out; 4240 } 4241 4242 newc = malloc(sizeof(ocontext_t)); 4243 if (!newc) { 4244 yyerror("out of memory"); 4245 rc = -1; 4246 goto out; 4247 } 4248 4249 memset(newc, 0, sizeof(ocontext_t)); 4250 4251 #ifdef DARWIN 4252 memcpy(&newc->u.node6.addr[0], &addr.s6_addr[0], 16); 4253 memcpy(&newc->u.node6.mask[0], &mask.s6_addr[0], 16); 4254 #else 4255 memcpy(&newc->u.node6.addr[0], &addr.s6_addr32[0], 16); 4256 memcpy(&newc->u.node6.mask[0], &mask.s6_addr32[0], 16); 4257 #endif 4258 4259 if (parse_security_context(&newc->context[0])) { 4260 free(newc); 4261 rc = -1; 4262 goto out; 4263 } 4264 4265 /* Create order of most specific to least retaining 4266 the order specified in the configuration. */ 4267 head = policydbp->ocontexts[OCON_NODE6]; 4268 for (l = NULL, c = head; c; l = c, c = c->next) { 4269 if (memcmp(&newc->u.node6.mask, &c->u.node6.mask, 16) > 0) 4270 break; 4271 } 4272 4273 newc->next = c; 4274 4275 if (l) 4276 l->next = newc; 4277 else 4278 policydbp->ocontexts[OCON_NODE6] = newc; 4279 4280 rc = 0; 4281 out: 4282 return rc; 4283 } 4284 4285 int define_fs_use(int behavior) 4286 { 4287 ocontext_t *newc, *c, *head; 4288 4289 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 4290 yyerror("fsuse not supported for target"); 4291 return -1; 4292 } 4293 4294 if (pass == 1) { 4295 free(queue_remove(id_queue)); 4296 parse_security_context(NULL); 4297 return 0; 4298 } 4299 4300 newc = (ocontext_t *) malloc(sizeof(ocontext_t)); 4301 if (!newc) { 4302 yyerror("out of memory"); 4303 return -1; 4304 } 4305 memset(newc, 0, sizeof(ocontext_t)); 4306 4307 newc->u.name = (char *)queue_remove(id_queue); 4308 if (!newc->u.name) { 4309 free(newc); 4310 return -1; 4311 } 4312 newc->v.behavior = behavior; 4313 if (parse_security_context(&newc->context[0])) { 4314 free(newc->u.name); 4315 free(newc); 4316 return -1; 4317 } 4318 4319 head = policydbp->ocontexts[OCON_FSUSE]; 4320 4321 for (c = head; c; c = c->next) { 4322 if (!strcmp(newc->u.name, c->u.name)) { 4323 yyerror2("duplicate fs_use entry for filesystem type %s", 4324 newc->u.name); 4325 context_destroy(&newc->context[0]); 4326 free(newc->u.name); 4327 free(newc); 4328 return -1; 4329 } 4330 } 4331 4332 newc->next = head; 4333 policydbp->ocontexts[OCON_FSUSE] = newc; 4334 return 0; 4335 } 4336 4337 int define_genfs_context_helper(char *fstype, int has_type) 4338 { 4339 struct genfs *genfs_p, *genfs, *newgenfs; 4340 ocontext_t *newc, *c, *head, *p; 4341 char *type = NULL; 4342 int len, len2; 4343 4344 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 4345 yyerror("genfs not supported for target"); 4346 return -1; 4347 } 4348 4349 if (pass == 1) { 4350 free(fstype); 4351 free(queue_remove(id_queue)); 4352 if (has_type) 4353 free(queue_remove(id_queue)); 4354 parse_security_context(NULL); 4355 return 0; 4356 } 4357 4358 for (genfs_p = NULL, genfs = policydbp->genfs; 4359 genfs; genfs_p = genfs, genfs = genfs->next) { 4360 if (strcmp(fstype, genfs->fstype) <= 0) 4361 break; 4362 } 4363 4364 if (!genfs || strcmp(fstype, genfs->fstype)) { 4365 newgenfs = malloc(sizeof(struct genfs)); 4366 if (!newgenfs) { 4367 yyerror("out of memory"); 4368 return -1; 4369 } 4370 memset(newgenfs, 0, sizeof(struct genfs)); 4371 newgenfs->fstype = fstype; 4372 newgenfs->next = genfs; 4373 if (genfs_p) 4374 genfs_p->next = newgenfs; 4375 else 4376 policydbp->genfs = newgenfs; 4377 genfs = newgenfs; 4378 } 4379 4380 newc = (ocontext_t *) malloc(sizeof(ocontext_t)); 4381 if (!newc) { 4382 yyerror("out of memory"); 4383 return -1; 4384 } 4385 memset(newc, 0, sizeof(ocontext_t)); 4386 4387 newc->u.name = (char *)queue_remove(id_queue); 4388 if (!newc->u.name) 4389 goto fail; 4390 if (has_type) { 4391 type = (char *)queue_remove(id_queue); 4392 if (!type) 4393 goto fail; 4394 if (type[1] != 0) { 4395 yyerror2("invalid type %s", type); 4396 goto fail; 4397 } 4398 switch (type[0]) { 4399 case 'b': 4400 newc->v.sclass = SECCLASS_BLK_FILE; 4401 break; 4402 case 'c': 4403 newc->v.sclass = SECCLASS_CHR_FILE; 4404 break; 4405 case 'd': 4406 newc->v.sclass = SECCLASS_DIR; 4407 break; 4408 case 'p': 4409 newc->v.sclass = SECCLASS_FIFO_FILE; 4410 break; 4411 case 'l': 4412 newc->v.sclass = SECCLASS_LNK_FILE; 4413 break; 4414 case 's': 4415 newc->v.sclass = SECCLASS_SOCK_FILE; 4416 break; 4417 case '-': 4418 newc->v.sclass = SECCLASS_FILE; 4419 break; 4420 default: 4421 yyerror2("invalid type %s", type); 4422 goto fail; 4423 } 4424 } 4425 if (parse_security_context(&newc->context[0])) 4426 goto fail; 4427 4428 head = genfs->head; 4429 4430 for (p = NULL, c = head; c; p = c, c = c->next) { 4431 if (!strcmp(newc->u.name, c->u.name) && 4432 (!newc->v.sclass || !c->v.sclass 4433 || newc->v.sclass == c->v.sclass)) { 4434 yyerror2("duplicate entry for genfs entry (%s, %s)", 4435 fstype, newc->u.name); 4436 goto fail; 4437 } 4438 len = strlen(newc->u.name); 4439 len2 = strlen(c->u.name); 4440 if (len > len2) 4441 break; 4442 } 4443 4444 newc->next = c; 4445 if (p) 4446 p->next = newc; 4447 else 4448 genfs->head = newc; 4449 return 0; 4450 fail: 4451 if (type) 4452 free(type); 4453 context_destroy(&newc->context[0]); 4454 if (fstype) 4455 free(fstype); 4456 if (newc->u.name) 4457 free(newc->u.name); 4458 free(newc); 4459 return -1; 4460 } 4461 4462 int define_genfs_context(int has_type) 4463 { 4464 return define_genfs_context_helper(queue_remove(id_queue), has_type); 4465 } 4466 4467 int define_range_trans(int class_specified) 4468 { 4469 char *id; 4470 level_datum_t *levdatum = 0; 4471 class_datum_t *cladatum; 4472 range_trans_rule_t *rule; 4473 int l, add = 1; 4474 4475 if (!mlspol) { 4476 yyerror("range_transition rule in non-MLS configuration"); 4477 return -1; 4478 } 4479 4480 if (pass == 1) { 4481 while ((id = queue_remove(id_queue))) 4482 free(id); 4483 while ((id = queue_remove(id_queue))) 4484 free(id); 4485 if (class_specified) 4486 while ((id = queue_remove(id_queue))) 4487 free(id); 4488 id = queue_remove(id_queue); 4489 free(id); 4490 for (l = 0; l < 2; l++) { 4491 while ((id = queue_remove(id_queue))) { 4492 free(id); 4493 } 4494 id = queue_remove(id_queue); 4495 if (!id) 4496 break; 4497 free(id); 4498 } 4499 return 0; 4500 } 4501 4502 rule = malloc(sizeof(struct range_trans_rule)); 4503 if (!rule) { 4504 yyerror("out of memory"); 4505 return -1; 4506 } 4507 range_trans_rule_init(rule); 4508 4509 while ((id = queue_remove(id_queue))) { 4510 if (set_types(&rule->stypes, id, &add, 0)) 4511 goto out; 4512 } 4513 add = 1; 4514 while ((id = queue_remove(id_queue))) { 4515 if (set_types(&rule->ttypes, id, &add, 0)) 4516 goto out; 4517 } 4518 4519 if (class_specified) { 4520 if (read_classes(&rule->tclasses)) 4521 goto out; 4522 } else { 4523 cladatum = hashtab_search(policydbp->p_classes.table, 4524 "process"); 4525 if (!cladatum) { 4526 yyerror2("could not find process class for " 4527 "legacy range_transition statement"); 4528 goto out; 4529 } 4530 4531 ebitmap_set_bit(&rule->tclasses, cladatum->s.value - 1, TRUE); 4532 } 4533 4534 id = (char *)queue_remove(id_queue); 4535 if (!id) { 4536 yyerror("no range in range_transition definition?"); 4537 goto out; 4538 } 4539 for (l = 0; l < 2; l++) { 4540 levdatum = hashtab_search(policydbp->p_levels.table, id); 4541 if (!levdatum) { 4542 yyerror2("unknown level %s used in range_transition " 4543 "definition", id); 4544 free(id); 4545 goto out; 4546 } 4547 free(id); 4548 4549 rule->trange.level[l].sens = levdatum->level->sens; 4550 4551 while ((id = queue_remove(id_queue))) { 4552 if (parse_semantic_categories(id, levdatum, 4553 &rule->trange.level[l].cat)) { 4554 free(id); 4555 goto out; 4556 } 4557 free(id); 4558 } 4559 4560 id = (char *)queue_remove(id_queue); 4561 if (!id) 4562 break; 4563 } 4564 if (l == 0) { 4565 if (mls_semantic_level_cpy(&rule->trange.level[1], 4566 &rule->trange.level[0])) { 4567 yyerror("out of memory"); 4568 goto out; 4569 } 4570 } 4571 4572 append_range_trans(rule); 4573 return 0; 4574 4575 out: 4576 range_trans_rule_destroy(rule); 4577 return -1; 4578 } 4579 4580 /* FLASK */ 4581