policy_define.c revision 13cd4c8960688af11ad23b4c946149015c80d549
1/* 2 * Author : Stephen Smalley, <sds@epoch.ncsc.mil> 3 */ 4 5/* 6 * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com> 7 * 8 * Support for enhanced MLS infrastructure. 9 * 10 * Updated: David Caplan, <dac@tresys.com> 11 * 12 * Added conditional policy language extensions 13 * 14 * Updated: Joshua Brindle <jbrindle@tresys.com> 15 * Karl MacMillan <kmacmillan@mentalrootkit.com> 16 * Jason Tang <jtang@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 54policydb_t *policydbp; 55queue_t id_queue = 0; 56unsigned int pass; 57char *curfile = 0; 58int mlspol = 0; 59 60extern unsigned long policydb_lineno; 61extern unsigned long source_lineno; 62extern unsigned int policydb_errors; 63 64extern int yywarn(char *msg); 65extern int yyerror(char *msg); 66 67#define ERRORMSG_LEN 255 68static char errormsg[ERRORMSG_LEN + 1] = {0}; 69 70static int id_has_dot(char *id); 71static int parse_security_context(context_struct_t *c); 72 73/* initialize all of the state variables for the scanner/parser */ 74void init_parser(int pass_number) 75{ 76 policydb_lineno = 1; 77 source_lineno = 1; 78 policydb_errors = 0; 79 pass = pass_number; 80} 81 82void 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 91int 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 107int 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. */ 133static int id_has_dot(char *id) 134{ 135 if (strchr(id, '.') >= id + 1) { 136 return 1; 137 } 138 return 0; 139} 140 141int 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 198int 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 236out: 237 free(type); 238 return rc; 239} 240 241int 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 279int 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 330int define_common_perms(void) 331{ 332 char *id = 0, *perm = 0; 333 common_datum_t *comdatum = 0; 334 perm_datum_t *perdatum = 0; 335 int ret; 336 337 if (pass == 2) { 338 while ((id = queue_remove(id_queue))) 339 free(id); 340 return 0; 341 } 342 343 id = (char *)queue_remove(id_queue); 344 if (!id) { 345 yyerror("no common name for common perm definition?"); 346 return -1; 347 } 348 comdatum = hashtab_search(policydbp->p_commons.table, id); 349 if (comdatum) { 350 yyerror2("duplicate declaration for common %s\n", id); 351 return -1; 352 } 353 comdatum = (common_datum_t *) malloc(sizeof(common_datum_t)); 354 if (!comdatum) { 355 yyerror("out of memory"); 356 goto bad; 357 } 358 memset(comdatum, 0, sizeof(common_datum_t)); 359 ret = hashtab_insert(policydbp->p_commons.table, 360 (hashtab_key_t) id, (hashtab_datum_t) comdatum); 361 362 if (ret == SEPOL_EEXIST) { 363 yyerror("duplicate common definition"); 364 goto bad; 365 } 366 if (ret == SEPOL_ENOMEM) { 367 yyerror("hash table overflow"); 368 goto bad; 369 } 370 comdatum->s.value = policydbp->p_commons.nprim + 1; 371 if (symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE)) { 372 yyerror("out of memory"); 373 goto bad; 374 } 375 policydbp->p_commons.nprim++; 376 while ((perm = queue_remove(id_queue))) { 377 perdatum = (perm_datum_t *) malloc(sizeof(perm_datum_t)); 378 if (!perdatum) { 379 yyerror("out of memory"); 380 goto bad_perm; 381 } 382 memset(perdatum, 0, sizeof(perm_datum_t)); 383 perdatum->s.value = comdatum->permissions.nprim + 1; 384 385 if (perdatum->s.value > (sizeof(sepol_access_vector_t) * 8)) { 386 yyerror 387 ("too many permissions to fit in an access vector"); 388 goto bad_perm; 389 } 390 ret = hashtab_insert(comdatum->permissions.table, 391 (hashtab_key_t) perm, 392 (hashtab_datum_t) perdatum); 393 394 if (ret == SEPOL_EEXIST) { 395 yyerror2("duplicate permission %s in common %s", perm, 396 id); 397 goto bad_perm; 398 } 399 if (ret == SEPOL_ENOMEM) { 400 yyerror("hash table overflow"); 401 goto bad_perm; 402 } 403 comdatum->permissions.nprim++; 404 } 405 406 return 0; 407 408 bad: 409 if (id) 410 free(id); 411 if (comdatum) 412 free(comdatum); 413 return -1; 414 415 bad_perm: 416 if (perm) 417 free(perm); 418 if (perdatum) 419 free(perdatum); 420 return -1; 421} 422 423int define_av_perms(int inherits) 424{ 425 char *id; 426 class_datum_t *cladatum; 427 common_datum_t *comdatum; 428 perm_datum_t *perdatum = 0, *perdatum2 = 0; 429 int ret; 430 431 if (pass == 2) { 432 while ((id = queue_remove(id_queue))) 433 free(id); 434 return 0; 435 } 436 437 id = (char *)queue_remove(id_queue); 438 if (!id) { 439 yyerror("no tclass name for av perm definition?"); 440 return -1; 441 } 442 cladatum = (class_datum_t *) hashtab_search(policydbp->p_classes.table, 443 (hashtab_key_t) id); 444 if (!cladatum) { 445 yyerror2("class %s is not defined", id); 446 goto bad; 447 } 448 free(id); 449 450 if (cladatum->comdatum || cladatum->permissions.nprim) { 451 yyerror("duplicate access vector definition"); 452 return -1; 453 } 454 if (symtab_init(&cladatum->permissions, PERM_SYMTAB_SIZE)) { 455 yyerror("out of memory"); 456 return -1; 457 } 458 if (inherits) { 459 id = (char *)queue_remove(id_queue); 460 if (!id) { 461 yyerror 462 ("no inherits name for access vector definition?"); 463 return -1; 464 } 465 comdatum = 466 (common_datum_t *) hashtab_search(policydbp->p_commons. 467 table, 468 (hashtab_key_t) id); 469 470 if (!comdatum) { 471 yyerror2("common %s is not defined", id); 472 goto bad; 473 } 474 cladatum->comkey = id; 475 cladatum->comdatum = comdatum; 476 477 /* 478 * Class-specific permissions start with values 479 * after the last common permission. 480 */ 481 cladatum->permissions.nprim += comdatum->permissions.nprim; 482 } 483 while ((id = queue_remove(id_queue))) { 484 perdatum = (perm_datum_t *) malloc(sizeof(perm_datum_t)); 485 if (!perdatum) { 486 yyerror("out of memory"); 487 goto bad; 488 } 489 memset(perdatum, 0, sizeof(perm_datum_t)); 490 perdatum->s.value = ++cladatum->permissions.nprim; 491 492 if (perdatum->s.value > (sizeof(sepol_access_vector_t) * 8)) { 493 yyerror 494 ("too many permissions to fit in an access vector"); 495 goto bad; 496 } 497 if (inherits) { 498 /* 499 * Class-specific permissions and 500 * common permissions exist in the same 501 * name space. 502 */ 503 perdatum2 = 504 (perm_datum_t *) hashtab_search(cladatum->comdatum-> 505 permissions.table, 506 (hashtab_key_t) id); 507 if (perdatum2) { 508 yyerror2("permission %s conflicts with an " 509 "inherited permission", id); 510 goto bad; 511 } 512 } 513 ret = hashtab_insert(cladatum->permissions.table, 514 (hashtab_key_t) id, 515 (hashtab_datum_t) perdatum); 516 517 if (ret == SEPOL_EEXIST) { 518 yyerror2("duplicate permission %s", id); 519 goto bad; 520 } 521 if (ret == SEPOL_ENOMEM) { 522 yyerror("hash table overflow"); 523 goto bad; 524 } 525 if (add_perm_to_class(perdatum->s.value, cladatum->s.value)) { 526 yyerror("out of memory"); 527 goto bad; 528 } 529 } 530 531 return 0; 532 533 bad: 534 if (id) 535 free(id); 536 if (perdatum) 537 free(perdatum); 538 return -1; 539} 540 541int define_sens(void) 542{ 543 char *id; 544 mls_level_t *level = 0; 545 level_datum_t *datum = 0, *aliasdatum = 0; 546 int ret; 547 uint32_t value; /* dummy variable -- its value is never used */ 548 549 if (!mlspol) { 550 yyerror("sensitivity definition in non-MLS configuration"); 551 return -1; 552 } 553 554 if (pass == 2) { 555 while ((id = queue_remove(id_queue))) 556 free(id); 557 return 0; 558 } 559 560 id = (char *)queue_remove(id_queue); 561 if (!id) { 562 yyerror("no sensitivity name for sensitivity definition?"); 563 return -1; 564 } 565 if (id_has_dot(id)) { 566 yyerror("sensitivity identifiers may not contain periods"); 567 goto bad; 568 } 569 level = (mls_level_t *) malloc(sizeof(mls_level_t)); 570 if (!level) { 571 yyerror("out of memory"); 572 goto bad; 573 } 574 mls_level_init(level); 575 level->sens = 0; /* actual value set in define_dominance */ 576 ebitmap_init(&level->cat); /* actual value set in define_level */ 577 578 datum = (level_datum_t *) malloc(sizeof(level_datum_t)); 579 if (!datum) { 580 yyerror("out of memory"); 581 goto bad; 582 } 583 level_datum_init(datum); 584 datum->isalias = FALSE; 585 datum->level = level; 586 587 ret = declare_symbol(SYM_LEVELS, id, datum, &value, &value); 588 switch (ret) { 589 case -3:{ 590 yyerror("Out of memory!"); 591 goto bad; 592 } 593 case -2:{ 594 yyerror("duplicate declaration of sensitivity level"); 595 goto bad; 596 } 597 case -1:{ 598 yyerror("could not declare sensitivity level here"); 599 goto bad; 600 } 601 case 0: 602 case 1:{ 603 break; 604 } 605 default:{ 606 assert(0); /* should never get here */ 607 } 608 } 609 610 while ((id = queue_remove(id_queue))) { 611 if (id_has_dot(id)) { 612 yyerror("sensitivity aliases may not contain periods"); 613 goto bad_alias; 614 } 615 aliasdatum = (level_datum_t *) malloc(sizeof(level_datum_t)); 616 if (!aliasdatum) { 617 yyerror("out of memory"); 618 goto bad_alias; 619 } 620 level_datum_init(aliasdatum); 621 aliasdatum->isalias = TRUE; 622 aliasdatum->level = level; 623 624 ret = declare_symbol(SYM_LEVELS, id, aliasdatum, NULL, &value); 625 switch (ret) { 626 case -3:{ 627 yyerror("Out of memory!"); 628 goto bad_alias; 629 } 630 case -2:{ 631 yyerror 632 ("duplicate declaration of sensitivity alias"); 633 goto bad_alias; 634 } 635 case -1:{ 636 yyerror 637 ("could not declare sensitivity alias here"); 638 goto bad_alias; 639 } 640 case 0: 641 case 1:{ 642 break; 643 } 644 default:{ 645 assert(0); /* should never get here */ 646 } 647 } 648 } 649 650 return 0; 651 652 bad: 653 if (id) 654 free(id); 655 if (level) 656 free(level); 657 if (datum) { 658 level_datum_destroy(datum); 659 free(datum); 660 } 661 return -1; 662 663 bad_alias: 664 if (id) 665 free(id); 666 if (aliasdatum) { 667 level_datum_destroy(aliasdatum); 668 free(aliasdatum); 669 } 670 return -1; 671} 672 673int define_dominance(void) 674{ 675 level_datum_t *datum; 676 int order; 677 char *id; 678 679 if (!mlspol) { 680 yyerror("dominance definition in non-MLS configuration"); 681 return -1; 682 } 683 684 if (pass == 2) { 685 while ((id = queue_remove(id_queue))) 686 free(id); 687 return 0; 688 } 689 690 order = 0; 691 while ((id = (char *)queue_remove(id_queue))) { 692 datum = 693 (level_datum_t *) hashtab_search(policydbp->p_levels.table, 694 (hashtab_key_t) id); 695 if (!datum) { 696 yyerror2("unknown sensitivity %s used in dominance " 697 "definition", id); 698 free(id); 699 return -1; 700 } 701 if (datum->level->sens != 0) { 702 yyerror2("sensitivity %s occurs multiply in dominance " 703 "definition", id); 704 free(id); 705 return -1; 706 } 707 datum->level->sens = ++order; 708 709 /* no need to keep sensitivity name */ 710 free(id); 711 } 712 713 if (order != policydbp->p_levels.nprim) { 714 yyerror 715 ("all sensitivities must be specified in dominance definition"); 716 return -1; 717 } 718 return 0; 719} 720 721int define_category(void) 722{ 723 char *id; 724 cat_datum_t *datum = 0, *aliasdatum = 0; 725 int ret; 726 uint32_t value; 727 728 if (!mlspol) { 729 yyerror("category definition in non-MLS configuration"); 730 return -1; 731 } 732 733 if (pass == 2) { 734 while ((id = queue_remove(id_queue))) 735 free(id); 736 return 0; 737 } 738 739 id = (char *)queue_remove(id_queue); 740 if (!id) { 741 yyerror("no category name for category definition?"); 742 return -1; 743 } 744 if (id_has_dot(id)) { 745 yyerror("category identifiers may not contain periods"); 746 goto bad; 747 } 748 datum = (cat_datum_t *) malloc(sizeof(cat_datum_t)); 749 if (!datum) { 750 yyerror("out of memory"); 751 goto bad; 752 } 753 cat_datum_init(datum); 754 datum->isalias = FALSE; 755 756 ret = declare_symbol(SYM_CATS, id, datum, &value, &value); 757 switch (ret) { 758 case -3:{ 759 yyerror("Out of memory!"); 760 goto bad; 761 } 762 case -2:{ 763 yyerror("duplicate declaration of category"); 764 goto bad; 765 } 766 case -1:{ 767 yyerror("could not declare category here"); 768 goto bad; 769 } 770 case 0: 771 case 1:{ 772 break; 773 } 774 default:{ 775 assert(0); /* should never get here */ 776 } 777 } 778 datum->s.value = value; 779 780 while ((id = queue_remove(id_queue))) { 781 if (id_has_dot(id)) { 782 yyerror("category aliases may not contain periods"); 783 goto bad_alias; 784 } 785 aliasdatum = (cat_datum_t *) malloc(sizeof(cat_datum_t)); 786 if (!aliasdatum) { 787 yyerror("out of memory"); 788 goto bad_alias; 789 } 790 cat_datum_init(aliasdatum); 791 aliasdatum->isalias = TRUE; 792 aliasdatum->s.value = datum->s.value; 793 794 ret = 795 declare_symbol(SYM_CATS, id, aliasdatum, NULL, 796 &datum->s.value); 797 switch (ret) { 798 case -3:{ 799 yyerror("Out of memory!"); 800 goto bad_alias; 801 } 802 case -2:{ 803 yyerror 804 ("duplicate declaration of category aliases"); 805 goto bad_alias; 806 } 807 case -1:{ 808 yyerror 809 ("could not declare category aliases here"); 810 goto bad_alias; 811 } 812 case 0: 813 case 1:{ 814 break; 815 } 816 default:{ 817 assert(0); /* should never get here */ 818 } 819 } 820 } 821 822 return 0; 823 824 bad: 825 if (id) 826 free(id); 827 if (datum) { 828 cat_datum_destroy(datum); 829 free(datum); 830 } 831 return -1; 832 833 bad_alias: 834 if (id) 835 free(id); 836 if (aliasdatum) { 837 cat_datum_destroy(aliasdatum); 838 free(aliasdatum); 839 } 840 return -1; 841} 842 843static int clone_level(hashtab_key_t key, hashtab_datum_t datum, void *arg) 844{ 845 level_datum_t *levdatum = (level_datum_t *) datum; 846 mls_level_t *level = (mls_level_t *) arg, *newlevel; 847 848 if (levdatum->level == level) { 849 levdatum->defined = 1; 850 if (!levdatum->isalias) 851 return 0; 852 newlevel = (mls_level_t *) malloc(sizeof(mls_level_t)); 853 if (!newlevel) 854 return -1; 855 if (mls_level_cpy(newlevel, level)) { 856 free(newlevel); 857 return -1; 858 } 859 levdatum->level = newlevel; 860 } 861 return 0; 862} 863 864int define_level(void) 865{ 866 char *id; 867 level_datum_t *levdatum; 868 869 if (!mlspol) { 870 yyerror("level definition in non-MLS configuration"); 871 return -1; 872 } 873 874 if (pass == 2) { 875 while ((id = queue_remove(id_queue))) 876 free(id); 877 return 0; 878 } 879 880 id = (char *)queue_remove(id_queue); 881 if (!id) { 882 yyerror("no level name for level definition?"); 883 return -1; 884 } 885 levdatum = (level_datum_t *) hashtab_search(policydbp->p_levels.table, 886 (hashtab_key_t) id); 887 if (!levdatum) { 888 yyerror2("unknown sensitivity %s used in level definition", id); 889 free(id); 890 return -1; 891 } 892 if (ebitmap_length(&levdatum->level->cat)) { 893 yyerror2("sensitivity %s used in multiple level definitions", 894 id); 895 free(id); 896 return -1; 897 } 898 free(id); 899 900 levdatum->defined = 1; 901 902 while ((id = queue_remove(id_queue))) { 903 cat_datum_t *cdatum; 904 int range_start, range_end, i; 905 906 if (id_has_dot(id)) { 907 char *id_start = id; 908 char *id_end = strchr(id, '.'); 909 910 *(id_end++) = '\0'; 911 912 cdatum = 913 (cat_datum_t *) hashtab_search(policydbp->p_cats. 914 table, 915 (hashtab_key_t) 916 id_start); 917 if (!cdatum) { 918 yyerror2("unknown category %s", id_start); 919 free(id); 920 return -1; 921 } 922 range_start = cdatum->s.value - 1; 923 cdatum = 924 (cat_datum_t *) hashtab_search(policydbp->p_cats. 925 table, 926 (hashtab_key_t) 927 id_end); 928 if (!cdatum) { 929 yyerror2("unknown category %s", id_end); 930 free(id); 931 return -1; 932 } 933 range_end = cdatum->s.value - 1; 934 935 if (range_end < range_start) { 936 yyerror2("category range is invalid"); 937 free(id); 938 return -1; 939 } 940 } else { 941 cdatum = 942 (cat_datum_t *) hashtab_search(policydbp->p_cats. 943 table, 944 (hashtab_key_t) id); 945 range_start = range_end = cdatum->s.value - 1; 946 } 947 948 for (i = range_start; i <= range_end; i++) { 949 if (ebitmap_set_bit(&levdatum->level->cat, i, TRUE)) { 950 yyerror("out of memory"); 951 free(id); 952 return -1; 953 } 954 } 955 956 free(id); 957 } 958 959 if (hashtab_map 960 (policydbp->p_levels.table, clone_level, levdatum->level)) { 961 yyerror("out of memory"); 962 return -1; 963 } 964 965 return 0; 966} 967 968int define_attrib(void) 969{ 970 if (pass == 2) { 971 free(queue_remove(id_queue)); 972 return 0; 973 } 974 975 if (declare_type(TRUE, TRUE) == NULL) { 976 return -1; 977 } 978 return 0; 979} 980 981static int add_aliases_to_type(type_datum_t * type) 982{ 983 char *id; 984 type_datum_t *aliasdatum = NULL; 985 int ret; 986 while ((id = queue_remove(id_queue))) { 987 if (id_has_dot(id)) { 988 free(id); 989 yyerror 990 ("type alias identifiers may not contain periods"); 991 return -1; 992 } 993 aliasdatum = (type_datum_t *) malloc(sizeof(type_datum_t)); 994 if (!aliasdatum) { 995 free(id); 996 yyerror("Out of memory!"); 997 return -1; 998 } 999 memset(aliasdatum, 0, sizeof(type_datum_t)); 1000 aliasdatum->s.value = type->s.value; 1001 1002 ret = declare_symbol(SYM_TYPES, id, aliasdatum, 1003 NULL, &aliasdatum->s.value); 1004 switch (ret) { 1005 case -3:{ 1006 yyerror("Out of memory!"); 1007 goto cleanup; 1008 } 1009 case -2:{ 1010 yyerror2("duplicate declaration of alias %s", 1011 id); 1012 goto cleanup; 1013 } 1014 case -1:{ 1015 yyerror("could not declare alias here"); 1016 goto cleanup; 1017 } 1018 case 0: 1019 case 1:{ 1020 break; 1021 } 1022 default:{ 1023 assert(0); /* should never get here */ 1024 } 1025 } 1026 } 1027 return 0; 1028 cleanup: 1029 free(id); 1030 type_datum_destroy(aliasdatum); 1031 free(aliasdatum); 1032 return -1; 1033} 1034 1035int define_typealias(void) 1036{ 1037 char *id; 1038 type_datum_t *t; 1039 1040 if (pass == 2) { 1041 while ((id = queue_remove(id_queue))) 1042 free(id); 1043 return 0; 1044 } 1045 1046 id = (char *)queue_remove(id_queue); 1047 if (!id) { 1048 yyerror("no type name for typealias definition?"); 1049 return -1; 1050 } 1051 1052 if (!is_id_in_scope(SYM_TYPES, id)) { 1053 yyerror2("type %s is not within scope", id); 1054 free(id); 1055 return -1; 1056 } 1057 t = hashtab_search(policydbp->p_types.table, id); 1058 if (!t || t->flavor == TYPE_ATTRIB) { 1059 yyerror2("unknown type %s, or it was already declared as an " 1060 "attribute", id); 1061 free(id); 1062 return -1; 1063 } 1064 return add_aliases_to_type(t); 1065} 1066 1067int define_typeattribute(void) 1068{ 1069 char *id; 1070 type_datum_t *t, *attr; 1071 1072 if (pass == 2) { 1073 while ((id = queue_remove(id_queue))) 1074 free(id); 1075 return 0; 1076 } 1077 1078 id = (char *)queue_remove(id_queue); 1079 if (!id) { 1080 yyerror("no type name for typeattribute definition?"); 1081 return -1; 1082 } 1083 1084 if (!is_id_in_scope(SYM_TYPES, id)) { 1085 yyerror2("type %s is not within scope", id); 1086 free(id); 1087 return -1; 1088 } 1089 t = hashtab_search(policydbp->p_types.table, id); 1090 if (!t || t->flavor == TYPE_ATTRIB) { 1091 yyerror2("unknown type %s", id); 1092 free(id); 1093 return -1; 1094 } 1095 1096 while ((id = queue_remove(id_queue))) { 1097 if (!is_id_in_scope(SYM_TYPES, id)) { 1098 yyerror2("attribute %s is not within scope", id); 1099 free(id); 1100 return -1; 1101 } 1102 attr = hashtab_search(policydbp->p_types.table, id); 1103 if (!attr) { 1104 /* treat it as a fatal error */ 1105 yyerror2("attribute %s is not declared", id); 1106 free(id); 1107 return -1; 1108 } 1109 1110 if (attr->flavor != TYPE_ATTRIB) { 1111 yyerror2("%s is a type, not an attribute", id); 1112 free(id); 1113 return -1; 1114 } 1115 1116 if ((attr = get_local_type(id, attr->s.value, 1)) == NULL) { 1117 yyerror("Out of memory!"); 1118 return -1; 1119 } 1120 1121 if (ebitmap_set_bit(&attr->types, (t->s.value - 1), TRUE)) { 1122 yyerror("out of memory"); 1123 return -1; 1124 } 1125 } 1126 1127 return 0; 1128} 1129 1130int define_type(int alias) 1131{ 1132 char *id; 1133 type_datum_t *datum, *attr; 1134 int newattr = 0; 1135 1136 if (pass == 2) { 1137 while ((id = queue_remove(id_queue))) 1138 free(id); 1139 if (alias) { 1140 while ((id = queue_remove(id_queue))) 1141 free(id); 1142 } 1143 return 0; 1144 } 1145 1146 if ((datum = declare_type(TRUE, FALSE)) == NULL) { 1147 return -1; 1148 } 1149 1150 if (alias) { 1151 if (add_aliases_to_type(datum) == -1) { 1152 return -1; 1153 } 1154 } 1155 1156 while ((id = queue_remove(id_queue))) { 1157 if (!is_id_in_scope(SYM_TYPES, id)) { 1158 yyerror2("attribute %s is not within scope", id); 1159 free(id); 1160 return -1; 1161 } 1162 attr = hashtab_search(policydbp->p_types.table, id); 1163 if (!attr) { 1164 /* treat it as a fatal error */ 1165 yyerror2("attribute %s is not declared", id); 1166 return -1; 1167 } else { 1168 newattr = 0; 1169 } 1170 1171 if (attr->flavor != TYPE_ATTRIB) { 1172 yyerror2("%s is a type, not an attribute", id); 1173 return -1; 1174 } 1175 1176 if ((attr = get_local_type(id, attr->s.value, 1)) == NULL) { 1177 yyerror("Out of memory!"); 1178 return -1; 1179 } 1180 1181 if (ebitmap_set_bit(&attr->types, datum->s.value - 1, TRUE)) { 1182 yyerror("Out of memory"); 1183 return -1; 1184 } 1185 } 1186 1187 return 0; 1188} 1189 1190struct val_to_name { 1191 unsigned int val; 1192 char *name; 1193}; 1194 1195/* Adds a type, given by its textual name, to a typeset. If *add is 1196 0, then add the type to the negative set; otherwise if *add is 1 1197 then add it to the positive side. */ 1198static int set_types(type_set_t * set, char *id, int *add, char starallowed) 1199{ 1200 type_datum_t *t; 1201 1202 if (strcmp(id, "*") == 0) { 1203 if (!starallowed) { 1204 yyerror("* not allowed in this type of rule"); 1205 return -1; 1206 } 1207 /* set TYPE_STAR flag */ 1208 set->flags = TYPE_STAR; 1209 free(id); 1210 *add = 1; 1211 return 0; 1212 } 1213 1214 if (strcmp(id, "~") == 0) { 1215 if (!starallowed) { 1216 yyerror("~ not allowed in this type of rule"); 1217 return -1; 1218 } 1219 /* complement the set */ 1220 set->flags = TYPE_COMP; 1221 free(id); 1222 *add = 1; 1223 return 0; 1224 } 1225 1226 if (strcmp(id, "-") == 0) { 1227 *add = 0; 1228 free(id); 1229 return 0; 1230 } 1231 1232 if (!is_id_in_scope(SYM_TYPES, id)) { 1233 yyerror2("type %s is not within scope", id); 1234 free(id); 1235 return -1; 1236 } 1237 t = hashtab_search(policydbp->p_types.table, id); 1238 if (!t) { 1239 yyerror2("unknown type %s", id); 1240 free(id); 1241 return -1; 1242 } 1243 1244 if (*add == 0) { 1245 if (ebitmap_set_bit(&set->negset, t->s.value - 1, TRUE)) 1246 goto oom; 1247 } else { 1248 if (ebitmap_set_bit(&set->types, t->s.value - 1, TRUE)) 1249 goto oom; 1250 } 1251 free(id); 1252 *add = 1; 1253 return 0; 1254 oom: 1255 yyerror("Out of memory"); 1256 free(id); 1257 return -1; 1258} 1259 1260int define_compute_type_helper(int which, avrule_t ** rule) 1261{ 1262 char *id; 1263 type_datum_t *datum; 1264 class_datum_t *cladatum; 1265 ebitmap_t tclasses; 1266 ebitmap_node_t *node; 1267 avrule_t *avrule; 1268 class_perm_node_t *perm; 1269 int i, add = 1; 1270 1271 avrule = malloc(sizeof(avrule_t)); 1272 if (!avrule) { 1273 yyerror("out of memory"); 1274 return -1; 1275 } 1276 avrule_init(avrule); 1277 avrule->specified = which; 1278 avrule->line = policydb_lineno; 1279 1280 while ((id = queue_remove(id_queue))) { 1281 if (set_types(&avrule->stypes, id, &add, 0)) 1282 return -1; 1283 } 1284 add = 1; 1285 while ((id = queue_remove(id_queue))) { 1286 if (set_types(&avrule->ttypes, id, &add, 0)) 1287 return -1; 1288 } 1289 1290 ebitmap_init(&tclasses); 1291 while ((id = queue_remove(id_queue))) { 1292 if (!is_id_in_scope(SYM_CLASSES, id)) { 1293 yyerror2("class %s is not within scope", id); 1294 free(id); 1295 goto bad; 1296 } 1297 cladatum = hashtab_search(policydbp->p_classes.table, id); 1298 if (!cladatum) { 1299 yyerror2("unknown class %s", id); 1300 goto bad; 1301 } 1302 if (ebitmap_set_bit(&tclasses, cladatum->s.value - 1, TRUE)) { 1303 yyerror("Out of memory"); 1304 goto bad; 1305 } 1306 free(id); 1307 } 1308 1309 id = (char *)queue_remove(id_queue); 1310 if (!id) { 1311 yyerror("no newtype?"); 1312 goto bad; 1313 } 1314 if (!is_id_in_scope(SYM_TYPES, id)) { 1315 yyerror2("type %s is not within scope", id); 1316 free(id); 1317 goto bad; 1318 } 1319 datum = (type_datum_t *) hashtab_search(policydbp->p_types.table, 1320 (hashtab_key_t) id); 1321 if (!datum || datum->flavor == TYPE_ATTRIB) { 1322 yyerror2("unknown type %s", id); 1323 goto bad; 1324 } 1325 1326 ebitmap_for_each_bit(&tclasses, node, i) { 1327 if (ebitmap_node_get_bit(node, i)) { 1328 perm = malloc(sizeof(class_perm_node_t)); 1329 if (!perm) { 1330 yyerror("out of memory"); 1331 return -1; 1332 } 1333 class_perm_node_init(perm); 1334 perm->class = i + 1; 1335 perm->data = datum->s.value; 1336 perm->next = avrule->perms; 1337 avrule->perms = perm; 1338 } 1339 } 1340 ebitmap_destroy(&tclasses); 1341 1342 *rule = avrule; 1343 return 0; 1344 1345 bad: 1346 avrule_destroy(avrule); 1347 free(avrule); 1348 return -1; 1349} 1350 1351int define_compute_type(int which) 1352{ 1353 char *id; 1354 avrule_t *avrule; 1355 1356 if (pass == 1) { 1357 while ((id = queue_remove(id_queue))) 1358 free(id); 1359 while ((id = queue_remove(id_queue))) 1360 free(id); 1361 while ((id = queue_remove(id_queue))) 1362 free(id); 1363 id = queue_remove(id_queue); 1364 free(id); 1365 return 0; 1366 } 1367 1368 if (define_compute_type_helper(which, &avrule)) 1369 return -1; 1370 1371 append_avrule(avrule); 1372 return 0; 1373} 1374 1375avrule_t *define_cond_compute_type(int which) 1376{ 1377 char *id; 1378 avrule_t *avrule; 1379 1380 if (pass == 1) { 1381 while ((id = queue_remove(id_queue))) 1382 free(id); 1383 while ((id = queue_remove(id_queue))) 1384 free(id); 1385 while ((id = queue_remove(id_queue))) 1386 free(id); 1387 id = queue_remove(id_queue); 1388 free(id); 1389 return (avrule_t *) 1; 1390 } 1391 1392 if (define_compute_type_helper(which, &avrule)) 1393 return COND_ERR; 1394 1395 return avrule; 1396} 1397 1398int define_bool(void) 1399{ 1400 char *id, *bool_value; 1401 cond_bool_datum_t *datum; 1402 int ret; 1403 uint32_t value; 1404 1405 if (pass == 2) { 1406 while ((id = queue_remove(id_queue))) 1407 free(id); 1408 return 0; 1409 } 1410 1411 id = (char *)queue_remove(id_queue); 1412 if (!id) { 1413 yyerror("no identifier for bool definition?"); 1414 return -1; 1415 } 1416 if (id_has_dot(id)) { 1417 free(id); 1418 yyerror("boolean identifiers may not contain periods"); 1419 return -1; 1420 } 1421 datum = (cond_bool_datum_t *) malloc(sizeof(cond_bool_datum_t)); 1422 if (!datum) { 1423 yyerror("out of memory"); 1424 free(id); 1425 return -1; 1426 } 1427 memset(datum, 0, sizeof(cond_bool_datum_t)); 1428 ret = declare_symbol(SYM_BOOLS, id, datum, &value, &value); 1429 switch (ret) { 1430 case -3:{ 1431 yyerror("Out of memory!"); 1432 goto cleanup; 1433 } 1434 case -2:{ 1435 yyerror2("duplicate declaration of boolean %s", id); 1436 goto cleanup; 1437 } 1438 case -1:{ 1439 yyerror("could not declare boolean here"); 1440 goto cleanup; 1441 } 1442 case 0: 1443 case 1:{ 1444 break; 1445 } 1446 default:{ 1447 assert(0); /* should never get here */ 1448 } 1449 } 1450 datum->s.value = value; 1451 1452 bool_value = (char *)queue_remove(id_queue); 1453 if (!bool_value) { 1454 yyerror("no default value for bool definition?"); 1455 free(id); 1456 return -1; 1457 } 1458 1459 datum->state = (int)(bool_value[0] == 'T') ? 1 : 0; 1460 return 0; 1461 cleanup: 1462 cond_destroy_bool(id, datum, NULL); 1463 return -1; 1464} 1465 1466avrule_t *define_cond_pol_list(avrule_t * avlist, avrule_t * sl) 1467{ 1468 if (pass == 1) { 1469 /* return something so we get through pass 1 */ 1470 return (avrule_t *) 1; 1471 } 1472 1473 if (sl == NULL) { 1474 /* This is a require block, return previous list */ 1475 return avlist; 1476 } 1477 1478 /* prepend the new avlist to the pre-existing one */ 1479 sl->next = avlist; 1480 return sl; 1481} 1482 1483int define_te_avtab_helper(int which, avrule_t ** rule) 1484{ 1485 char *id; 1486 class_datum_t *cladatum; 1487 perm_datum_t *perdatum = NULL; 1488 class_perm_node_t *perms, *tail = NULL, *cur_perms = NULL; 1489 ebitmap_t tclasses; 1490 ebitmap_node_t *node; 1491 avrule_t *avrule; 1492 unsigned int i; 1493 int add = 1, ret = 0; 1494 int suppress = 0; 1495 1496 avrule = (avrule_t *) malloc(sizeof(avrule_t)); 1497 if (!avrule) { 1498 yyerror("memory error"); 1499 ret = -1; 1500 goto out; 1501 } 1502 avrule_init(avrule); 1503 avrule->specified = which; 1504 avrule->line = policydb_lineno; 1505 1506 while ((id = queue_remove(id_queue))) { 1507 if (set_types 1508 (&avrule->stypes, id, &add, 1509 which == AVRULE_NEVERALLOW ? 1 : 0)) { 1510 ret = -1; 1511 goto out; 1512 } 1513 } 1514 add = 1; 1515 while ((id = queue_remove(id_queue))) { 1516 if (strcmp(id, "self") == 0) { 1517 free(id); 1518 avrule->flags |= RULE_SELF; 1519 continue; 1520 } 1521 if (set_types 1522 (&avrule->ttypes, id, &add, 1523 which == AVRULE_NEVERALLOW ? 1 : 0)) { 1524 ret = -1; 1525 goto out; 1526 } 1527 } 1528 1529 ebitmap_init(&tclasses); 1530 while ((id = queue_remove(id_queue))) { 1531 if (!is_id_in_scope(SYM_CLASSES, id)) { 1532 yyerror2("class %s is not within scope", id); 1533 ret = -1; 1534 goto out; 1535 } 1536 cladatum = hashtab_search(policydbp->p_classes.table, id); 1537 if (!cladatum) { 1538 yyerror2("unknown class %s used in rule", id); 1539 ret = -1; 1540 goto out; 1541 } 1542 if (ebitmap_set_bit(&tclasses, cladatum->s.value - 1, TRUE)) { 1543 yyerror("Out of memory"); 1544 ret = -1; 1545 goto out; 1546 } 1547 free(id); 1548 } 1549 1550 perms = NULL; 1551 ebitmap_for_each_bit(&tclasses, node, i) { 1552 if (!ebitmap_node_get_bit(node, i)) 1553 continue; 1554 cur_perms = 1555 (class_perm_node_t *) malloc(sizeof(class_perm_node_t)); 1556 if (!cur_perms) { 1557 yyerror("out of memory"); 1558 ret = -1; 1559 goto out; 1560 } 1561 class_perm_node_init(cur_perms); 1562 cur_perms->class = i + 1; 1563 if (!perms) 1564 perms = cur_perms; 1565 if (tail) 1566 tail->next = cur_perms; 1567 tail = cur_perms; 1568 } 1569 1570 while ((id = queue_remove(id_queue))) { 1571 cur_perms = perms; 1572 ebitmap_for_each_bit(&tclasses, node, i) { 1573 if (!ebitmap_node_get_bit(node, i)) 1574 continue; 1575 cladatum = policydbp->class_val_to_struct[i]; 1576 1577 if (strcmp(id, "*") == 0) { 1578 /* set all permissions in the class */ 1579 cur_perms->data = ~0U; 1580 goto next; 1581 } 1582 1583 if (strcmp(id, "~") == 0) { 1584 /* complement the set */ 1585 if (which == AVRULE_DONTAUDIT) 1586 yywarn("dontaudit rule with a ~?"); 1587 cur_perms->data = ~cur_perms->data; 1588 goto next; 1589 } 1590 1591 perdatum = 1592 hashtab_search(cladatum->permissions.table, id); 1593 if (!perdatum) { 1594 if (cladatum->comdatum) { 1595 perdatum = 1596 hashtab_search(cladatum->comdatum-> 1597 permissions.table, 1598 id); 1599 } 1600 } 1601 if (!perdatum) { 1602 if (!suppress) 1603 yyerror2("permission %s is not defined" 1604 " for class %s", id, 1605 policydbp->p_class_val_to_name[i]); 1606 continue; 1607 } else 1608 if (!is_perm_in_scope 1609 (id, policydbp->p_class_val_to_name[i])) { 1610 if (!suppress) { 1611 yyerror2("permission %s of class %s is" 1612 " not within scope", id, 1613 policydbp->p_class_val_to_name[i]); 1614 } 1615 continue; 1616 } else { 1617 cur_perms->data |= 1U << (perdatum->s.value - 1); 1618 } 1619 next: 1620 cur_perms = cur_perms->next; 1621 } 1622 1623 free(id); 1624 } 1625 1626 ebitmap_destroy(&tclasses); 1627 1628 avrule->perms = perms; 1629 *rule = avrule; 1630 1631 out: 1632 return ret; 1633 1634} 1635 1636avrule_t *define_cond_te_avtab(int which) 1637{ 1638 char *id; 1639 avrule_t *avrule; 1640 int i; 1641 1642 if (pass == 1) { 1643 for (i = 0; i < 4; i++) { 1644 while ((id = queue_remove(id_queue))) 1645 free(id); 1646 } 1647 return (avrule_t *) 1; /* any non-NULL value */ 1648 } 1649 1650 if (define_te_avtab_helper(which, &avrule)) 1651 return COND_ERR; 1652 1653 return avrule; 1654} 1655 1656int define_te_avtab(int which) 1657{ 1658 char *id; 1659 avrule_t *avrule; 1660 int i; 1661 1662 if (pass == 1) { 1663 for (i = 0; i < 4; i++) { 1664 while ((id = queue_remove(id_queue))) 1665 free(id); 1666 } 1667 return 0; 1668 } 1669 1670 if (define_te_avtab_helper(which, &avrule)) 1671 return -1; 1672 1673 /* append this avrule to the end of the current rules list */ 1674 append_avrule(avrule); 1675 return 0; 1676} 1677 1678int define_role_types(void) 1679{ 1680 role_datum_t *role; 1681 char *id; 1682 int add = 1; 1683 1684 if (pass == 1) { 1685 while ((id = queue_remove(id_queue))) 1686 free(id); 1687 return 0; 1688 } 1689 1690 if ((role = declare_role()) == NULL) { 1691 return -1; 1692 } 1693 while ((id = queue_remove(id_queue))) { 1694 if (set_types(&role->types, id, &add, 0)) 1695 return -1; 1696 } 1697 1698 return 0; 1699} 1700 1701role_datum_t *merge_roles_dom(role_datum_t * r1, role_datum_t * r2) 1702{ 1703 role_datum_t *new; 1704 1705 if (pass == 1) { 1706 return (role_datum_t *) 1; /* any non-NULL value */ 1707 } 1708 1709 new = malloc(sizeof(role_datum_t)); 1710 if (!new) { 1711 yyerror("out of memory"); 1712 return NULL; 1713 } 1714 memset(new, 0, sizeof(role_datum_t)); 1715 new->s.value = 0; /* temporary role */ 1716 if (ebitmap_or(&new->dominates, &r1->dominates, &r2->dominates)) { 1717 yyerror("out of memory"); 1718 return NULL; 1719 } 1720 if (ebitmap_or(&new->types.types, &r1->types.types, &r2->types.types)) { 1721 yyerror("out of memory"); 1722 return NULL; 1723 } 1724 if (!r1->s.value) { 1725 /* free intermediate result */ 1726 type_set_destroy(&r1->types); 1727 ebitmap_destroy(&r1->dominates); 1728 free(r1); 1729 } 1730 if (!r2->s.value) { 1731 /* free intermediate result */ 1732 yyerror("right hand role is temporary?"); 1733 type_set_destroy(&r2->types); 1734 ebitmap_destroy(&r2->dominates); 1735 free(r2); 1736 } 1737 return new; 1738} 1739 1740/* This function eliminates the ordering dependency of role dominance rule */ 1741static int dominate_role_recheck(hashtab_key_t key, hashtab_datum_t datum, 1742 void *arg) 1743{ 1744 role_datum_t *rdp = (role_datum_t *) arg; 1745 role_datum_t *rdatum = (role_datum_t *) datum; 1746 ebitmap_node_t *node; 1747 int i; 1748 1749 /* Don't bother to process against self role */ 1750 if (rdatum->s.value == rdp->s.value) 1751 return 0; 1752 1753 /* If a dominating role found */ 1754 if (ebitmap_get_bit(&(rdatum->dominates), rdp->s.value - 1)) { 1755 ebitmap_t types; 1756 ebitmap_init(&types); 1757 if (type_set_expand(&rdp->types, &types, policydbp, 1)) { 1758 ebitmap_destroy(&types); 1759 return -1; 1760 } 1761 /* raise types and dominates from dominated role */ 1762 ebitmap_for_each_bit(&rdp->dominates, node, i) { 1763 if (ebitmap_node_get_bit(node, i)) 1764 if (ebitmap_set_bit 1765 (&rdatum->dominates, i, TRUE)) 1766 goto oom; 1767 } 1768 ebitmap_for_each_bit(&types, node, i) { 1769 if (ebitmap_node_get_bit(node, i)) 1770 if (ebitmap_set_bit 1771 (&rdatum->types.types, i, TRUE)) 1772 goto oom; 1773 } 1774 ebitmap_destroy(&types); 1775 } 1776 1777 /* go through all the roles */ 1778 return 0; 1779 oom: 1780 yyerror("Out of memory"); 1781 return -1; 1782} 1783 1784role_datum_t *define_role_dom(role_datum_t * r) 1785{ 1786 role_datum_t *role; 1787 char *role_id; 1788 ebitmap_node_t *node; 1789 unsigned int i; 1790 int ret; 1791 1792 if (pass == 1) { 1793 role_id = queue_remove(id_queue); 1794 free(role_id); 1795 return (role_datum_t *) 1; /* any non-NULL value */ 1796 } 1797 1798 yywarn("Role dominance has been deprecated"); 1799 1800 role_id = queue_remove(id_queue); 1801 if (!is_id_in_scope(SYM_ROLES, role_id)) { 1802 yyerror2("role %s is not within scope", role_id); 1803 free(role_id); 1804 return NULL; 1805 } 1806 role = (role_datum_t *) hashtab_search(policydbp->p_roles.table, 1807 role_id); 1808 if (!role) { 1809 role = (role_datum_t *) malloc(sizeof(role_datum_t)); 1810 if (!role) { 1811 yyerror("out of memory"); 1812 free(role_id); 1813 return NULL; 1814 } 1815 memset(role, 0, sizeof(role_datum_t)); 1816 ret = 1817 declare_symbol(SYM_ROLES, (hashtab_key_t) role_id, 1818 (hashtab_datum_t) role, &role->s.value, 1819 &role->s.value); 1820 switch (ret) { 1821 case -3:{ 1822 yyerror("Out of memory!"); 1823 goto cleanup; 1824 } 1825 case -2:{ 1826 yyerror2("duplicate declaration of role %s", 1827 role_id); 1828 goto cleanup; 1829 } 1830 case -1:{ 1831 yyerror("could not declare role here"); 1832 goto cleanup; 1833 } 1834 case 0: 1835 case 1:{ 1836 break; 1837 } 1838 default:{ 1839 assert(0); /* should never get here */ 1840 } 1841 } 1842 if (ebitmap_set_bit(&role->dominates, role->s.value - 1, TRUE)) { 1843 yyerror("Out of memory!"); 1844 goto cleanup; 1845 } 1846 } 1847 if (r) { 1848 ebitmap_t types; 1849 ebitmap_init(&types); 1850 ebitmap_for_each_bit(&r->dominates, node, i) { 1851 if (ebitmap_node_get_bit(node, i)) 1852 if (ebitmap_set_bit(&role->dominates, i, TRUE)) 1853 goto oom; 1854 } 1855 if (type_set_expand(&r->types, &types, policydbp, 1)) { 1856 ebitmap_destroy(&types); 1857 return NULL; 1858 } 1859 ebitmap_for_each_bit(&types, node, i) { 1860 if (ebitmap_node_get_bit(node, i)) 1861 if (ebitmap_set_bit 1862 (&role->types.types, i, TRUE)) 1863 goto oom; 1864 } 1865 ebitmap_destroy(&types); 1866 if (!r->s.value) { 1867 /* free intermediate result */ 1868 type_set_destroy(&r->types); 1869 ebitmap_destroy(&r->dominates); 1870 free(r); 1871 } 1872 /* 1873 * Now go through all the roles and escalate this role's 1874 * dominates and types if a role dominates this role. 1875 */ 1876 hashtab_map(policydbp->p_roles.table, 1877 dominate_role_recheck, role); 1878 } 1879 return role; 1880 cleanup: 1881 free(role_id); 1882 role_datum_destroy(role); 1883 free(role); 1884 return NULL; 1885 oom: 1886 yyerror("Out of memory"); 1887 goto cleanup; 1888} 1889 1890static int role_val_to_name_helper(hashtab_key_t key, hashtab_datum_t datum, 1891 void *p) 1892{ 1893 struct val_to_name *v = p; 1894 role_datum_t *roldatum; 1895 1896 roldatum = (role_datum_t *) datum; 1897 1898 if (v->val == roldatum->s.value) { 1899 v->name = key; 1900 return 1; 1901 } 1902 1903 return 0; 1904} 1905 1906static char *role_val_to_name(unsigned int val) 1907{ 1908 struct val_to_name v; 1909 int rc; 1910 1911 v.val = val; 1912 rc = hashtab_map(policydbp->p_roles.table, role_val_to_name_helper, &v); 1913 if (rc) 1914 return v.name; 1915 return NULL; 1916} 1917 1918static int set_roles(role_set_t * set, char *id) 1919{ 1920 role_datum_t *r; 1921 1922 if (strcmp(id, "*") == 0) { 1923 free(id); 1924 yyerror("* is not allowed for role sets"); 1925 return -1; 1926 } 1927 1928 if (strcmp(id, "~") == 0) { 1929 free(id); 1930 yyerror("~ is not allowed for role sets"); 1931 return -1; 1932 } 1933 if (!is_id_in_scope(SYM_ROLES, id)) { 1934 yyerror2("role %s is not within scope", id); 1935 free(id); 1936 return -1; 1937 } 1938 r = hashtab_search(policydbp->p_roles.table, id); 1939 if (!r) { 1940 yyerror2("unknown role %s", id); 1941 free(id); 1942 return -1; 1943 } 1944 1945 if (ebitmap_set_bit(&set->roles, r->s.value - 1, TRUE)) { 1946 yyerror("out of memory"); 1947 free(id); 1948 return -1; 1949 } 1950 free(id); 1951 return 0; 1952} 1953 1954int define_role_trans(void) 1955{ 1956 char *id; 1957 role_datum_t *role; 1958 role_set_t roles; 1959 type_set_t types; 1960 ebitmap_t e_types, e_roles; 1961 ebitmap_node_t *tnode, *rnode; 1962 struct role_trans *tr = NULL; 1963 struct role_trans_rule *rule = NULL; 1964 unsigned int i, j; 1965 int add = 1; 1966 1967 if (pass == 1) { 1968 while ((id = queue_remove(id_queue))) 1969 free(id); 1970 while ((id = queue_remove(id_queue))) 1971 free(id); 1972 id = queue_remove(id_queue); 1973 free(id); 1974 return 0; 1975 } 1976 1977 role_set_init(&roles); 1978 ebitmap_init(&e_roles); 1979 type_set_init(&types); 1980 ebitmap_init(&e_types); 1981 1982 while ((id = queue_remove(id_queue))) { 1983 if (set_roles(&roles, id)) 1984 return -1; 1985 } 1986 add = 1; 1987 while ((id = queue_remove(id_queue))) { 1988 if (set_types(&types, id, &add, 0)) 1989 return -1; 1990 } 1991 1992 id = (char *)queue_remove(id_queue); 1993 if (!id) { 1994 yyerror("no new role in transition definition?"); 1995 goto bad; 1996 } 1997 if (!is_id_in_scope(SYM_ROLES, id)) { 1998 yyerror2("role %s is not within scope", id); 1999 free(id); 2000 goto bad; 2001 } 2002 role = hashtab_search(policydbp->p_roles.table, id); 2003 if (!role) { 2004 yyerror2("unknown role %s used in transition definition", id); 2005 goto bad; 2006 } 2007 2008 /* This ebitmap business is just to ensure that there are not conflicting role_trans rules */ 2009 if (role_set_expand(&roles, &e_roles, policydbp, NULL)) 2010 goto bad; 2011 2012 if (type_set_expand(&types, &e_types, policydbp, 1)) 2013 goto bad; 2014 2015 ebitmap_for_each_bit(&e_roles, rnode, i) { 2016 if (!ebitmap_node_get_bit(rnode, i)) 2017 continue; 2018 ebitmap_for_each_bit(&e_types, tnode, j) { 2019 if (!ebitmap_node_get_bit(tnode, j)) 2020 continue; 2021 2022 for (tr = policydbp->role_tr; tr; tr = tr->next) { 2023 if (tr->role == (i + 1) && tr->type == (j + 1)) { 2024 yyerror2("duplicate role transition for (%s,%s)", 2025 role_val_to_name(i + 1), 2026 policydbp->p_type_val_to_name[j]); 2027 goto bad; 2028 } 2029 } 2030 2031 tr = malloc(sizeof(struct role_trans)); 2032 if (!tr) { 2033 yyerror("out of memory"); 2034 return -1; 2035 } 2036 memset(tr, 0, sizeof(struct role_trans)); 2037 tr->role = i + 1; 2038 tr->type = j + 1; 2039 tr->new_role = role->s.value; 2040 tr->next = policydbp->role_tr; 2041 policydbp->role_tr = tr; 2042 } 2043 } 2044 /* Now add the real rule */ 2045 rule = malloc(sizeof(struct role_trans_rule)); 2046 if (!rule) { 2047 yyerror("out of memory"); 2048 return -1; 2049 } 2050 memset(rule, 0, sizeof(struct role_trans_rule)); 2051 rule->roles = roles; 2052 rule->types = types; 2053 rule->new_role = role->s.value; 2054 2055 append_role_trans(rule); 2056 2057 ebitmap_destroy(&e_roles); 2058 ebitmap_destroy(&e_types); 2059 2060 return 0; 2061 2062 bad: 2063 return -1; 2064} 2065 2066int define_role_allow(void) 2067{ 2068 char *id; 2069 struct role_allow_rule *ra = 0; 2070 2071 if (pass == 1) { 2072 while ((id = queue_remove(id_queue))) 2073 free(id); 2074 while ((id = queue_remove(id_queue))) 2075 free(id); 2076 return 0; 2077 } 2078 2079 ra = malloc(sizeof(role_allow_rule_t)); 2080 if (!ra) { 2081 yyerror("out of memory"); 2082 return -1; 2083 } 2084 role_allow_rule_init(ra); 2085 2086 while ((id = queue_remove(id_queue))) { 2087 if (set_roles(&ra->roles, id)) 2088 return -1; 2089 } 2090 2091 while ((id = queue_remove(id_queue))) { 2092 if (set_roles(&ra->new_roles, id)) 2093 return -1; 2094 } 2095 2096 append_role_allow(ra); 2097 return 0; 2098} 2099 2100static constraint_expr_t *constraint_expr_clone(constraint_expr_t * expr) 2101{ 2102 constraint_expr_t *h = NULL, *l = NULL, *e, *newe; 2103 for (e = expr; e; e = e->next) { 2104 newe = malloc(sizeof(*newe)); 2105 if (!newe) 2106 goto oom; 2107 if (constraint_expr_init(newe) == -1) { 2108 free(newe); 2109 goto oom; 2110 } 2111 if (l) 2112 l->next = newe; 2113 else 2114 h = newe; 2115 l = newe; 2116 newe->expr_type = e->expr_type; 2117 newe->attr = e->attr; 2118 newe->op = e->op; 2119 if (newe->expr_type == CEXPR_NAMES) { 2120 if (newe->attr & CEXPR_TYPE) { 2121 if (type_set_cpy 2122 (newe->type_names, e->type_names)) 2123 goto oom; 2124 } else { 2125 if (ebitmap_cpy(&newe->names, &e->names)) 2126 goto oom; 2127 } 2128 } 2129 } 2130 2131 return h; 2132 oom: 2133 e = h; 2134 while (e) { 2135 l = e; 2136 e = e->next; 2137 constraint_expr_destroy(l); 2138 } 2139 return NULL; 2140} 2141 2142int define_constraint(constraint_expr_t * expr) 2143{ 2144 struct constraint_node *node; 2145 char *id; 2146 class_datum_t *cladatum; 2147 perm_datum_t *perdatum; 2148 ebitmap_t classmap; 2149 ebitmap_node_t *enode; 2150 constraint_expr_t *e; 2151 unsigned int i; 2152 int depth; 2153 unsigned char useexpr = 1; 2154 2155 if (pass == 1) { 2156 while ((id = queue_remove(id_queue))) 2157 free(id); 2158 while ((id = queue_remove(id_queue))) 2159 free(id); 2160 return 0; 2161 } 2162 2163 depth = -1; 2164 for (e = expr; e; e = e->next) { 2165 switch (e->expr_type) { 2166 case CEXPR_NOT: 2167 if (depth < 0) { 2168 yyerror("illegal constraint expression"); 2169 return -1; 2170 } 2171 break; 2172 case CEXPR_AND: 2173 case CEXPR_OR: 2174 if (depth < 1) { 2175 yyerror("illegal constraint expression"); 2176 return -1; 2177 } 2178 depth--; 2179 break; 2180 case CEXPR_ATTR: 2181 case CEXPR_NAMES: 2182 if (e->attr & CEXPR_XTARGET) { 2183 yyerror("illegal constraint expression"); 2184 return -1; /* only for validatetrans rules */ 2185 } 2186 if (depth == (CEXPR_MAXDEPTH - 1)) { 2187 yyerror("constraint expression is too deep"); 2188 return -1; 2189 } 2190 depth++; 2191 break; 2192 default: 2193 yyerror("illegal constraint expression"); 2194 return -1; 2195 } 2196 } 2197 if (depth != 0) { 2198 yyerror("illegal constraint expression"); 2199 return -1; 2200 } 2201 2202 ebitmap_init(&classmap); 2203 while ((id = queue_remove(id_queue))) { 2204 if (!is_id_in_scope(SYM_CLASSES, id)) { 2205 yyerror2("class %s is not within scope", id); 2206 free(id); 2207 return -1; 2208 } 2209 cladatum = 2210 (class_datum_t *) hashtab_search(policydbp->p_classes.table, 2211 (hashtab_key_t) id); 2212 if (!cladatum) { 2213 yyerror2("class %s is not defined", id); 2214 ebitmap_destroy(&classmap); 2215 free(id); 2216 return -1; 2217 } 2218 if (ebitmap_set_bit(&classmap, cladatum->s.value - 1, TRUE)) { 2219 yyerror("out of memory"); 2220 ebitmap_destroy(&classmap); 2221 free(id); 2222 return -1; 2223 } 2224 node = malloc(sizeof(struct constraint_node)); 2225 if (!node) { 2226 yyerror("out of memory"); 2227 return -1; 2228 } 2229 memset(node, 0, sizeof(constraint_node_t)); 2230 if (useexpr) { 2231 node->expr = expr; 2232 useexpr = 0; 2233 } else { 2234 node->expr = constraint_expr_clone(expr); 2235 } 2236 if (!node->expr) { 2237 yyerror("out of memory"); 2238 return -1; 2239 } 2240 node->permissions = 0; 2241 2242 node->next = cladatum->constraints; 2243 cladatum->constraints = node; 2244 2245 free(id); 2246 } 2247 2248 while ((id = queue_remove(id_queue))) { 2249 ebitmap_for_each_bit(&classmap, enode, i) { 2250 if (ebitmap_node_get_bit(enode, i)) { 2251 cladatum = policydbp->class_val_to_struct[i]; 2252 node = cladatum->constraints; 2253 2254 perdatum = 2255 (perm_datum_t *) hashtab_search(cladatum-> 2256 permissions. 2257 table, 2258 (hashtab_key_t) 2259 id); 2260 if (!perdatum) { 2261 if (cladatum->comdatum) { 2262 perdatum = 2263 (perm_datum_t *) 2264 hashtab_search(cladatum-> 2265 comdatum-> 2266 permissions. 2267 table, 2268 (hashtab_key_t) 2269 id); 2270 } 2271 if (!perdatum) { 2272 yyerror2("permission %s is not" 2273 " defined", id); 2274 free(id); 2275 ebitmap_destroy(&classmap); 2276 return -1; 2277 } 2278 } 2279 node->permissions |= 2280 (1 << (perdatum->s.value - 1)); 2281 } 2282 } 2283 free(id); 2284 } 2285 2286 ebitmap_destroy(&classmap); 2287 2288 return 0; 2289} 2290 2291int define_validatetrans(constraint_expr_t * expr) 2292{ 2293 struct constraint_node *node; 2294 char *id; 2295 class_datum_t *cladatum; 2296 ebitmap_t classmap; 2297 constraint_expr_t *e; 2298 int depth; 2299 unsigned char useexpr = 1; 2300 2301 if (pass == 1) { 2302 while ((id = queue_remove(id_queue))) 2303 free(id); 2304 return 0; 2305 } 2306 2307 depth = -1; 2308 for (e = expr; e; e = e->next) { 2309 switch (e->expr_type) { 2310 case CEXPR_NOT: 2311 if (depth < 0) { 2312 yyerror("illegal validatetrans expression"); 2313 return -1; 2314 } 2315 break; 2316 case CEXPR_AND: 2317 case CEXPR_OR: 2318 if (depth < 1) { 2319 yyerror("illegal validatetrans expression"); 2320 return -1; 2321 } 2322 depth--; 2323 break; 2324 case CEXPR_ATTR: 2325 case CEXPR_NAMES: 2326 if (depth == (CEXPR_MAXDEPTH - 1)) { 2327 yyerror("validatetrans expression is too deep"); 2328 return -1; 2329 } 2330 depth++; 2331 break; 2332 default: 2333 yyerror("illegal validatetrans expression"); 2334 return -1; 2335 } 2336 } 2337 if (depth != 0) { 2338 yyerror("illegal validatetrans expression"); 2339 return -1; 2340 } 2341 2342 ebitmap_init(&classmap); 2343 while ((id = queue_remove(id_queue))) { 2344 if (!is_id_in_scope(SYM_CLASSES, id)) { 2345 yyerror2("class %s is not within scope", id); 2346 free(id); 2347 return -1; 2348 } 2349 cladatum = 2350 (class_datum_t *) hashtab_search(policydbp->p_classes.table, 2351 (hashtab_key_t) id); 2352 if (!cladatum) { 2353 yyerror2("class %s is not defined", id); 2354 ebitmap_destroy(&classmap); 2355 free(id); 2356 return -1; 2357 } 2358 if (ebitmap_set_bit(&classmap, (cladatum->s.value - 1), TRUE)) { 2359 yyerror("out of memory"); 2360 ebitmap_destroy(&classmap); 2361 free(id); 2362 return -1; 2363 } 2364 2365 node = malloc(sizeof(struct constraint_node)); 2366 if (!node) { 2367 yyerror("out of memory"); 2368 return -1; 2369 } 2370 memset(node, 0, sizeof(constraint_node_t)); 2371 if (useexpr) { 2372 node->expr = expr; 2373 useexpr = 0; 2374 } else { 2375 node->expr = constraint_expr_clone(expr); 2376 } 2377 node->permissions = 0; 2378 2379 node->next = cladatum->validatetrans; 2380 cladatum->validatetrans = node; 2381 2382 free(id); 2383 } 2384 2385 ebitmap_destroy(&classmap); 2386 2387 return 0; 2388} 2389 2390uintptr_t define_cexpr(uint32_t expr_type, uintptr_t arg1, uintptr_t arg2) 2391{ 2392 struct constraint_expr *expr, *e1 = NULL, *e2; 2393 user_datum_t *user; 2394 role_datum_t *role; 2395 ebitmap_t negset; 2396 char *id; 2397 uint32_t val; 2398 int add = 1; 2399 2400 if (pass == 1) { 2401 if (expr_type == CEXPR_NAMES) { 2402 while ((id = queue_remove(id_queue))) 2403 free(id); 2404 } 2405 return 1; /* any non-NULL value */ 2406 } 2407 2408 if ((expr = malloc(sizeof(*expr))) == NULL || 2409 constraint_expr_init(expr) == -1) { 2410 yyerror("out of memory"); 2411 free(expr); 2412 return 0; 2413 } 2414 expr->expr_type = expr_type; 2415 2416 switch (expr_type) { 2417 case CEXPR_NOT: 2418 e1 = NULL; 2419 e2 = (struct constraint_expr *)arg1; 2420 while (e2) { 2421 e1 = e2; 2422 e2 = e2->next; 2423 } 2424 if (!e1 || e1->next) { 2425 yyerror("illegal constraint expression"); 2426 constraint_expr_destroy(expr); 2427 return 0; 2428 } 2429 e1->next = expr; 2430 return arg1; 2431 case CEXPR_AND: 2432 case CEXPR_OR: 2433 e1 = NULL; 2434 e2 = (struct constraint_expr *)arg1; 2435 while (e2) { 2436 e1 = e2; 2437 e2 = e2->next; 2438 } 2439 if (!e1 || e1->next) { 2440 yyerror("illegal constraint expression"); 2441 constraint_expr_destroy(expr); 2442 return 0; 2443 } 2444 e1->next = (struct constraint_expr *)arg2; 2445 2446 e1 = NULL; 2447 e2 = (struct constraint_expr *)arg2; 2448 while (e2) { 2449 e1 = e2; 2450 e2 = e2->next; 2451 } 2452 if (!e1 || e1->next) { 2453 yyerror("illegal constraint expression"); 2454 constraint_expr_destroy(expr); 2455 return 0; 2456 } 2457 e1->next = expr; 2458 return arg1; 2459 case CEXPR_ATTR: 2460 expr->attr = arg1; 2461 expr->op = arg2; 2462 return (uintptr_t) expr; 2463 case CEXPR_NAMES: 2464 add = 1; 2465 expr->attr = arg1; 2466 expr->op = arg2; 2467 ebitmap_init(&negset); 2468 while ((id = (char *)queue_remove(id_queue))) { 2469 if (expr->attr & CEXPR_USER) { 2470 if (!is_id_in_scope(SYM_USERS, id)) { 2471 yyerror2("user %s is not within scope", 2472 id); 2473 constraint_expr_destroy(expr); 2474 return 0; 2475 } 2476 user = 2477 (user_datum_t *) hashtab_search(policydbp-> 2478 p_users. 2479 table, 2480 (hashtab_key_t) 2481 id); 2482 if (!user) { 2483 yyerror2("unknown user %s", id); 2484 constraint_expr_destroy(expr); 2485 return 0; 2486 } 2487 val = user->s.value; 2488 } else if (expr->attr & CEXPR_ROLE) { 2489 if (!is_id_in_scope(SYM_ROLES, id)) { 2490 yyerror2("role %s is not within scope", 2491 id); 2492 constraint_expr_destroy(expr); 2493 return 0; 2494 } 2495 role = 2496 (role_datum_t *) hashtab_search(policydbp-> 2497 p_roles. 2498 table, 2499 (hashtab_key_t) 2500 id); 2501 if (!role) { 2502 yyerror2("unknown role %s", id); 2503 constraint_expr_destroy(expr); 2504 return 0; 2505 } 2506 val = role->s.value; 2507 } else if (expr->attr & CEXPR_TYPE) { 2508 if (set_types(expr->type_names, id, &add, 0)) { 2509 constraint_expr_destroy(expr); 2510 return 0; 2511 } 2512 continue; 2513 } else { 2514 yyerror("invalid constraint expression"); 2515 constraint_expr_destroy(expr); 2516 return 0; 2517 } 2518 if (ebitmap_set_bit(&expr->names, val - 1, TRUE)) { 2519 yyerror("out of memory"); 2520 ebitmap_destroy(&expr->names); 2521 constraint_expr_destroy(expr); 2522 return 0; 2523 } 2524 free(id); 2525 } 2526 ebitmap_destroy(&negset); 2527 return (uintptr_t) expr; 2528 default: 2529 yyerror("invalid constraint expression"); 2530 constraint_expr_destroy(expr); 2531 return 0; 2532 } 2533 2534 yyerror("invalid constraint expression"); 2535 free(expr); 2536 return 0; 2537} 2538 2539int define_conditional(cond_expr_t * expr, avrule_t * t, avrule_t * f) 2540{ 2541 cond_expr_t *e; 2542 int depth; 2543 cond_node_t cn, *cn_old; 2544 2545 /* expression cannot be NULL */ 2546 if (!expr) { 2547 yyerror("illegal conditional expression"); 2548 return -1; 2549 } 2550 if (!t) { 2551 if (!f) { 2552 /* empty is fine, destroy expression and return */ 2553 cond_expr_destroy(expr); 2554 return 0; 2555 } 2556 /* Invert */ 2557 t = f; 2558 f = 0; 2559 expr = define_cond_expr(COND_NOT, expr, 0); 2560 if (!expr) { 2561 yyerror("unable to invert"); 2562 return -1; 2563 } 2564 } 2565 2566 /* verify expression */ 2567 depth = -1; 2568 for (e = expr; e; e = e->next) { 2569 switch (e->expr_type) { 2570 case COND_NOT: 2571 if (depth < 0) { 2572 yyerror 2573 ("illegal conditional expression; Bad NOT"); 2574 return -1; 2575 } 2576 break; 2577 case COND_AND: 2578 case COND_OR: 2579 case COND_XOR: 2580 case COND_EQ: 2581 case COND_NEQ: 2582 if (depth < 1) { 2583 yyerror 2584 ("illegal conditional expression; Bad binary op"); 2585 return -1; 2586 } 2587 depth--; 2588 break; 2589 case COND_BOOL: 2590 if (depth == (COND_EXPR_MAXDEPTH - 1)) { 2591 yyerror 2592 ("conditional expression is like totally too deep"); 2593 return -1; 2594 } 2595 depth++; 2596 break; 2597 default: 2598 yyerror("illegal conditional expression"); 2599 return -1; 2600 } 2601 } 2602 if (depth != 0) { 2603 yyerror("illegal conditional expression"); 2604 return -1; 2605 } 2606 2607 /* use tmp conditional node to partially build new node */ 2608 memset(&cn, 0, sizeof(cn)); 2609 cn.expr = expr; 2610 cn.avtrue_list = t; 2611 cn.avfalse_list = f; 2612 2613 /* normalize/precompute expression */ 2614 if (cond_normalize_expr(policydbp, &cn) < 0) { 2615 yyerror("problem normalizing conditional expression"); 2616 return -1; 2617 } 2618 2619 /* get the existing conditional node, or create a new one */ 2620 cn_old = get_current_cond_list(&cn); 2621 if (!cn_old) { 2622 return -1; 2623 } 2624 2625 append_cond_list(&cn); 2626 2627 /* note that there is no check here for duplicate rules, nor 2628 * check that rule already exists in base -- that will be 2629 * handled during conditional expansion, in expand.c */ 2630 2631 cn.avtrue_list = NULL; 2632 cn.avfalse_list = NULL; 2633 cond_node_destroy(&cn); 2634 2635 return 0; 2636} 2637 2638cond_expr_t *define_cond_expr(uint32_t expr_type, void *arg1, void *arg2) 2639{ 2640 struct cond_expr *expr, *e1 = NULL, *e2; 2641 cond_bool_datum_t *bool_var; 2642 char *id; 2643 2644 /* expressions are handled in the second pass */ 2645 if (pass == 1) { 2646 if (expr_type == COND_BOOL) { 2647 while ((id = queue_remove(id_queue))) { 2648 free(id); 2649 } 2650 } 2651 return (cond_expr_t *) 1; /* any non-NULL value */ 2652 } 2653 2654 /* create a new expression struct */ 2655 expr = malloc(sizeof(struct cond_expr)); 2656 if (!expr) { 2657 yyerror("out of memory"); 2658 return NULL; 2659 } 2660 memset(expr, 0, sizeof(cond_expr_t)); 2661 expr->expr_type = expr_type; 2662 2663 /* create the type asked for */ 2664 switch (expr_type) { 2665 case COND_NOT: 2666 e1 = NULL; 2667 e2 = (struct cond_expr *)arg1; 2668 while (e2) { 2669 e1 = e2; 2670 e2 = e2->next; 2671 } 2672 if (!e1 || e1->next) { 2673 yyerror("illegal conditional NOT expression"); 2674 free(expr); 2675 return NULL; 2676 } 2677 e1->next = expr; 2678 return (struct cond_expr *)arg1; 2679 case COND_AND: 2680 case COND_OR: 2681 case COND_XOR: 2682 case COND_EQ: 2683 case COND_NEQ: 2684 e1 = NULL; 2685 e2 = (struct cond_expr *)arg1; 2686 while (e2) { 2687 e1 = e2; 2688 e2 = e2->next; 2689 } 2690 if (!e1 || e1->next) { 2691 yyerror 2692 ("illegal left side of conditional binary op expression"); 2693 free(expr); 2694 return NULL; 2695 } 2696 e1->next = (struct cond_expr *)arg2; 2697 2698 e1 = NULL; 2699 e2 = (struct cond_expr *)arg2; 2700 while (e2) { 2701 e1 = e2; 2702 e2 = e2->next; 2703 } 2704 if (!e1 || e1->next) { 2705 yyerror 2706 ("illegal right side of conditional binary op expression"); 2707 free(expr); 2708 return NULL; 2709 } 2710 e1->next = expr; 2711 return (struct cond_expr *)arg1; 2712 case COND_BOOL: 2713 id = (char *)queue_remove(id_queue); 2714 if (!id) { 2715 yyerror("bad conditional; expected boolean id"); 2716 free(id); 2717 free(expr); 2718 return NULL; 2719 } 2720 if (!is_id_in_scope(SYM_BOOLS, id)) { 2721 yyerror2("boolean %s is not within scope", id); 2722 free(id); 2723 free(expr); 2724 return NULL; 2725 } 2726 bool_var = 2727 (cond_bool_datum_t *) hashtab_search(policydbp->p_bools. 2728 table, 2729 (hashtab_key_t) id); 2730 if (!bool_var) { 2731 yyerror2("unknown boolean %s in conditional expression", 2732 id); 2733 free(expr); 2734 free(id); 2735 return NULL; 2736 } 2737 expr->bool = bool_var->s.value; 2738 free(id); 2739 return expr; 2740 default: 2741 yyerror("illegal conditional expression"); 2742 return NULL; 2743 } 2744} 2745 2746static int set_user_roles(role_set_t * set, char *id) 2747{ 2748 role_datum_t *r; 2749 unsigned int i; 2750 ebitmap_node_t *node; 2751 2752 if (strcmp(id, "*") == 0) { 2753 free(id); 2754 yyerror("* is not allowed in user declarations"); 2755 return -1; 2756 } 2757 2758 if (strcmp(id, "~") == 0) { 2759 free(id); 2760 yyerror("~ is not allowed in user declarations"); 2761 return -1; 2762 } 2763 2764 if (!is_id_in_scope(SYM_ROLES, id)) { 2765 yyerror2("role %s is not within scope", id); 2766 free(id); 2767 return -1; 2768 } 2769 r = hashtab_search(policydbp->p_roles.table, id); 2770 if (!r) { 2771 yyerror2("unknown role %s", id); 2772 free(id); 2773 return -1; 2774 } 2775 2776 /* set the role and every role it dominates */ 2777 ebitmap_for_each_bit(&r->dominates, node, i) { 2778 if (ebitmap_node_get_bit(node, i)) 2779 if (ebitmap_set_bit(&set->roles, i, TRUE)) 2780 goto oom; 2781 } 2782 free(id); 2783 return 0; 2784 oom: 2785 yyerror("out of memory"); 2786 return -1; 2787} 2788 2789static int parse_categories(char *id, level_datum_t * levdatum, ebitmap_t * cats) 2790{ 2791 cat_datum_t *cdatum; 2792 int range_start, range_end, i; 2793 2794 if (id_has_dot(id)) { 2795 char *id_start = id; 2796 char *id_end = strchr(id, '.'); 2797 2798 *(id_end++) = '\0'; 2799 2800 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 2801 (hashtab_key_t) 2802 id_start); 2803 if (!cdatum) { 2804 yyerror2("unknown category %s", id_start); 2805 return -1; 2806 } 2807 range_start = cdatum->s.value - 1; 2808 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 2809 (hashtab_key_t) id_end); 2810 if (!cdatum) { 2811 yyerror2("unknown category %s", id_end); 2812 return -1; 2813 } 2814 range_end = cdatum->s.value - 1; 2815 2816 if (range_end < range_start) { 2817 yyerror2("category range is invalid"); 2818 return -1; 2819 } 2820 } else { 2821 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 2822 (hashtab_key_t) id); 2823 if (!cdatum) { 2824 yyerror2("unknown category %s", id); 2825 return -1; 2826 } 2827 range_start = range_end = cdatum->s.value - 1; 2828 } 2829 2830 for (i = range_start; i <= range_end; i++) { 2831 if (!ebitmap_get_bit(&levdatum->level->cat, i)) { 2832 uint32_t level_value = levdatum->level->sens - 1; 2833 policydb_index_others(NULL, policydbp, 0); 2834 yyerror2("category %s can not be associated " 2835 "with level %s", 2836 policydbp->p_cat_val_to_name[i], 2837 policydbp->p_sens_val_to_name[level_value]); 2838 return -1; 2839 } 2840 if (ebitmap_set_bit(cats, i, TRUE)) { 2841 yyerror("out of memory"); 2842 return -1; 2843 } 2844 } 2845 2846 return 0; 2847} 2848 2849static int parse_semantic_categories(char *id, level_datum_t * levdatum, 2850 mls_semantic_cat_t ** cats) 2851{ 2852 cat_datum_t *cdatum; 2853 mls_semantic_cat_t *newcat; 2854 unsigned int range_start, range_end; 2855 2856 if (id_has_dot(id)) { 2857 char *id_start = id; 2858 char *id_end = strchr(id, '.'); 2859 2860 *(id_end++) = '\0'; 2861 2862 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 2863 (hashtab_key_t) 2864 id_start); 2865 if (!cdatum) { 2866 yyerror2("unknown category %s", id_start); 2867 return -1; 2868 } 2869 range_start = cdatum->s.value; 2870 2871 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 2872 (hashtab_key_t) id_end); 2873 if (!cdatum) { 2874 yyerror2("unknown category %s", id_end); 2875 return -1; 2876 } 2877 range_end = cdatum->s.value; 2878 } else { 2879 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 2880 (hashtab_key_t) id); 2881 if (!cdatum) { 2882 yyerror2("unknown category %s", id); 2883 return -1; 2884 } 2885 range_start = range_end = cdatum->s.value; 2886 } 2887 2888 newcat = (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t)); 2889 if (!newcat) { 2890 yyerror("out of memory"); 2891 return -1; 2892 } 2893 2894 mls_semantic_cat_init(newcat); 2895 newcat->next = *cats; 2896 newcat->low = range_start; 2897 newcat->high = range_end; 2898 2899 *cats = newcat; 2900 2901 return 0; 2902} 2903 2904int define_user(void) 2905{ 2906 char *id; 2907 user_datum_t *usrdatum; 2908 level_datum_t *levdatum; 2909 int l; 2910 2911 if (pass == 1) { 2912 while ((id = queue_remove(id_queue))) 2913 free(id); 2914 if (mlspol) { 2915 while ((id = queue_remove(id_queue))) 2916 free(id); 2917 id = queue_remove(id_queue); 2918 free(id); 2919 for (l = 0; l < 2; l++) { 2920 while ((id = queue_remove(id_queue))) { 2921 free(id); 2922 } 2923 id = queue_remove(id_queue); 2924 if (!id) 2925 break; 2926 free(id); 2927 } 2928 } 2929 return 0; 2930 } 2931 2932 if ((usrdatum = declare_user()) == NULL) { 2933 return -1; 2934 } 2935 2936 while ((id = queue_remove(id_queue))) { 2937 if (set_user_roles(&usrdatum->roles, id)) 2938 continue; 2939 } 2940 2941 if (mlspol) { 2942 id = queue_remove(id_queue); 2943 if (!id) { 2944 yyerror("no default level specified for user"); 2945 return -1; 2946 } 2947 2948 levdatum = (level_datum_t *) 2949 hashtab_search(policydbp->p_levels.table, 2950 (hashtab_key_t) id); 2951 if (!levdatum) { 2952 yyerror2("unknown sensitivity %s used in user" 2953 " level definition", id); 2954 free(id); 2955 return -1; 2956 } 2957 free(id); 2958 2959 usrdatum->dfltlevel.sens = levdatum->level->sens; 2960 2961 while ((id = queue_remove(id_queue))) { 2962 if (parse_semantic_categories(id, levdatum, 2963 &usrdatum->dfltlevel.cat)) { 2964 free(id); 2965 return -1; 2966 } 2967 free(id); 2968 } 2969 2970 id = queue_remove(id_queue); 2971 2972 for (l = 0; l < 2; l++) { 2973 levdatum = (level_datum_t *) 2974 hashtab_search(policydbp->p_levels.table, 2975 (hashtab_key_t) id); 2976 if (!levdatum) { 2977 yyerror2("unknown sensitivity %s used in user" 2978 " range definition", id); 2979 free(id); 2980 return -1; 2981 } 2982 free(id); 2983 2984 usrdatum->range.level[l].sens = levdatum->level->sens; 2985 2986 while ((id = queue_remove(id_queue))) { 2987 if (parse_semantic_categories(id, levdatum, 2988 &usrdatum->range.level[l].cat)) { 2989 free(id); 2990 return -1; 2991 } 2992 free(id); 2993 } 2994 2995 id = queue_remove(id_queue); 2996 if (!id) 2997 break; 2998 } 2999 3000 if (l == 0) { 3001 if (mls_semantic_level_cpy(&usrdatum->range.level[1], 3002 &usrdatum->range.level[0])) { 3003 yyerror("out of memory"); 3004 return -1; 3005 } 3006 } 3007 } 3008 return 0; 3009} 3010 3011static int parse_security_context(context_struct_t * c) 3012{ 3013 char *id; 3014 role_datum_t *role; 3015 type_datum_t *typdatum; 3016 user_datum_t *usrdatum; 3017 level_datum_t *levdatum; 3018 int l; 3019 3020 if (pass == 1) { 3021 id = queue_remove(id_queue); 3022 free(id); /* user */ 3023 id = queue_remove(id_queue); 3024 free(id); /* role */ 3025 id = queue_remove(id_queue); 3026 free(id); /* type */ 3027 if (mlspol) { 3028 id = queue_remove(id_queue); 3029 free(id); 3030 for (l = 0; l < 2; l++) { 3031 while ((id = queue_remove(id_queue))) { 3032 free(id); 3033 } 3034 id = queue_remove(id_queue); 3035 if (!id) 3036 break; 3037 free(id); 3038 } 3039 } 3040 return 0; 3041 } 3042 3043 context_init(c); 3044 3045 /* extract the user */ 3046 id = queue_remove(id_queue); 3047 if (!id) { 3048 yyerror("no effective user?"); 3049 goto bad; 3050 } 3051 if (!is_id_in_scope(SYM_USERS, id)) { 3052 yyerror2("user %s is not within scope", id); 3053 free(id); 3054 goto bad; 3055 } 3056 usrdatum = (user_datum_t *) hashtab_search(policydbp->p_users.table, 3057 (hashtab_key_t) id); 3058 if (!usrdatum) { 3059 yyerror2("user %s is not defined", id); 3060 free(id); 3061 goto bad; 3062 } 3063 c->user = usrdatum->s.value; 3064 3065 /* no need to keep the user name */ 3066 free(id); 3067 3068 /* extract the role */ 3069 id = (char *)queue_remove(id_queue); 3070 if (!id) { 3071 yyerror("no role name for sid context definition?"); 3072 return -1; 3073 } 3074 if (!is_id_in_scope(SYM_ROLES, id)) { 3075 yyerror2("role %s is not within scope", id); 3076 free(id); 3077 return -1; 3078 } 3079 role = (role_datum_t *) hashtab_search(policydbp->p_roles.table, 3080 (hashtab_key_t) id); 3081 if (!role) { 3082 yyerror2("role %s is not defined", id); 3083 free(id); 3084 return -1; 3085 } 3086 c->role = role->s.value; 3087 3088 /* no need to keep the role name */ 3089 free(id); 3090 3091 /* extract the type */ 3092 id = (char *)queue_remove(id_queue); 3093 if (!id) { 3094 yyerror("no type name for sid context definition?"); 3095 return -1; 3096 } 3097 if (!is_id_in_scope(SYM_TYPES, id)) { 3098 yyerror2("type %s is not within scope", id); 3099 free(id); 3100 return -1; 3101 } 3102 typdatum = (type_datum_t *) hashtab_search(policydbp->p_types.table, 3103 (hashtab_key_t) id); 3104 if (!typdatum || typdatum->flavor == TYPE_ATTRIB) { 3105 yyerror2("type %s is not defined or is an attribute", id); 3106 free(id); 3107 return -1; 3108 } 3109 c->type = typdatum->s.value; 3110 3111 /* no need to keep the type name */ 3112 free(id); 3113 3114 if (mlspol) { 3115 /* extract the low sensitivity */ 3116 id = (char *)queue_head(id_queue); 3117 if (!id) { 3118 yyerror("no sensitivity name for sid context" 3119 " definition?"); 3120 return -1; 3121 } 3122 3123 id = (char *)queue_remove(id_queue); 3124 for (l = 0; l < 2; l++) { 3125 levdatum = (level_datum_t *) 3126 hashtab_search(policydbp->p_levels.table, 3127 (hashtab_key_t) id); 3128 if (!levdatum) { 3129 yyerror2("Sensitivity %s is not defined", id); 3130 free(id); 3131 return -1; 3132 } 3133 free(id); 3134 c->range.level[l].sens = levdatum->level->sens; 3135 3136 /* extract low category set */ 3137 while ((id = queue_remove(id_queue))) { 3138 if (parse_categories(id, levdatum, 3139 &c->range.level[l].cat)) { 3140 free(id); 3141 return -1; 3142 } 3143 free(id); 3144 } 3145 3146 /* extract high sensitivity */ 3147 id = (char *)queue_remove(id_queue); 3148 if (!id) 3149 break; 3150 } 3151 3152 if (l == 0) { 3153 c->range.level[1].sens = c->range.level[0].sens; 3154 if (ebitmap_cpy(&c->range.level[1].cat, 3155 &c->range.level[0].cat)) { 3156 3157 yyerror("out of memory"); 3158 goto bad; 3159 } 3160 } 3161 } 3162 3163 if (!policydb_context_isvalid(policydbp, c)) { 3164 yyerror("invalid security context"); 3165 goto bad; 3166 } 3167 return 0; 3168 3169 bad: 3170 context_destroy(c); 3171 3172 return -1; 3173} 3174 3175int define_initial_sid_context(void) 3176{ 3177 char *id; 3178 ocontext_t *c, *head; 3179 3180 if (pass == 1) { 3181 id = (char *)queue_remove(id_queue); 3182 free(id); 3183 parse_security_context(NULL); 3184 return 0; 3185 } 3186 3187 id = (char *)queue_remove(id_queue); 3188 if (!id) { 3189 yyerror("no sid name for SID context definition?"); 3190 return -1; 3191 } 3192 head = policydbp->ocontexts[OCON_ISID]; 3193 for (c = head; c; c = c->next) { 3194 if (!strcmp(id, c->u.name)) 3195 break; 3196 } 3197 3198 if (!c) { 3199 yyerror2("SID %s is not defined", id); 3200 free(id); 3201 return -1; 3202 } 3203 if (c->context[0].user) { 3204 yyerror2("The context for SID %s is multiply defined", id); 3205 free(id); 3206 return -1; 3207 } 3208 /* no need to keep the sid name */ 3209 free(id); 3210 3211 if (parse_security_context(&c->context[0])) 3212 return -1; 3213 3214 return 0; 3215} 3216 3217int define_fs_context(unsigned int major, unsigned int minor) 3218{ 3219 ocontext_t *newc, *c, *head; 3220 3221 if (pass == 1) { 3222 parse_security_context(NULL); 3223 parse_security_context(NULL); 3224 return 0; 3225 } 3226 3227 newc = (ocontext_t *) malloc(sizeof(ocontext_t)); 3228 if (!newc) { 3229 yyerror("out of memory"); 3230 return -1; 3231 } 3232 memset(newc, 0, sizeof(ocontext_t)); 3233 3234 newc->u.name = (char *)malloc(6); 3235 if (!newc->u.name) { 3236 yyerror("out of memory"); 3237 free(newc); 3238 return -1; 3239 } 3240 sprintf(newc->u.name, "%02x:%02x", major, minor); 3241 3242 if (parse_security_context(&newc->context[0])) { 3243 free(newc->u.name); 3244 free(newc); 3245 return -1; 3246 } 3247 if (parse_security_context(&newc->context[1])) { 3248 context_destroy(&newc->context[0]); 3249 free(newc->u.name); 3250 free(newc); 3251 return -1; 3252 } 3253 head = policydbp->ocontexts[OCON_FS]; 3254 3255 for (c = head; c; c = c->next) { 3256 if (!strcmp(newc->u.name, c->u.name)) { 3257 yyerror2("duplicate entry for file system %s", 3258 newc->u.name); 3259 context_destroy(&newc->context[0]); 3260 context_destroy(&newc->context[1]); 3261 free(newc->u.name); 3262 free(newc); 3263 return -1; 3264 } 3265 } 3266 3267 newc->next = head; 3268 policydbp->ocontexts[OCON_FS] = newc; 3269 3270 return 0; 3271} 3272 3273int define_port_context(unsigned int low, unsigned int high) 3274{ 3275 ocontext_t *newc, *c, *l, *head; 3276 unsigned int protocol; 3277 char *id; 3278 3279 if (pass == 1) { 3280 id = (char *)queue_remove(id_queue); 3281 free(id); 3282 parse_security_context(NULL); 3283 return 0; 3284 } 3285 3286 newc = malloc(sizeof(ocontext_t)); 3287 if (!newc) { 3288 yyerror("out of memory"); 3289 return -1; 3290 } 3291 memset(newc, 0, sizeof(ocontext_t)); 3292 3293 id = (char *)queue_remove(id_queue); 3294 if (!id) { 3295 free(newc); 3296 return -1; 3297 } 3298 if ((strcmp(id, "tcp") == 0) || (strcmp(id, "TCP") == 0)) { 3299 protocol = IPPROTO_TCP; 3300 } else if ((strcmp(id, "udp") == 0) || (strcmp(id, "UDP") == 0)) { 3301 protocol = IPPROTO_UDP; 3302 } else { 3303 yyerror2("unrecognized protocol %s", id); 3304 free(newc); 3305 return -1; 3306 } 3307 3308 newc->u.port.protocol = protocol; 3309 newc->u.port.low_port = low; 3310 newc->u.port.high_port = high; 3311 3312 if (low > high) { 3313 yyerror2("low port %d exceeds high port %d", low, high); 3314 free(newc); 3315 return -1; 3316 } 3317 3318 if (parse_security_context(&newc->context[0])) { 3319 free(newc); 3320 return -1; 3321 } 3322 3323 /* Preserve the matching order specified in the configuration. */ 3324 head = policydbp->ocontexts[OCON_PORT]; 3325 for (l = NULL, c = head; c; l = c, c = c->next) { 3326 unsigned int prot2, low2, high2; 3327 3328 prot2 = c->u.port.protocol; 3329 low2 = c->u.port.low_port; 3330 high2 = c->u.port.high_port; 3331 if (protocol != prot2) 3332 continue; 3333 if (low == low2 && high == high2) { 3334 yyerror2("duplicate portcon entry for %s %d-%d ", id, 3335 low, high); 3336 goto bad; 3337 } 3338 if (low2 <= low && high2 >= high) { 3339 yyerror2("portcon entry for %s %d-%d hidden by earlier " 3340 "entry for %d-%d", id, low, high, low2, high2); 3341 goto bad; 3342 } 3343 } 3344 3345 if (l) 3346 l->next = newc; 3347 else 3348 policydbp->ocontexts[OCON_PORT] = newc; 3349 3350 return 0; 3351 3352 bad: 3353 free(newc); 3354 return -1; 3355} 3356 3357int define_netif_context(void) 3358{ 3359 ocontext_t *newc, *c, *head; 3360 3361 if (pass == 1) { 3362 free(queue_remove(id_queue)); 3363 parse_security_context(NULL); 3364 parse_security_context(NULL); 3365 return 0; 3366 } 3367 3368 newc = (ocontext_t *) malloc(sizeof(ocontext_t)); 3369 if (!newc) { 3370 yyerror("out of memory"); 3371 return -1; 3372 } 3373 memset(newc, 0, sizeof(ocontext_t)); 3374 3375 newc->u.name = (char *)queue_remove(id_queue); 3376 if (!newc->u.name) { 3377 free(newc); 3378 return -1; 3379 } 3380 if (parse_security_context(&newc->context[0])) { 3381 free(newc->u.name); 3382 free(newc); 3383 return -1; 3384 } 3385 if (parse_security_context(&newc->context[1])) { 3386 context_destroy(&newc->context[0]); 3387 free(newc->u.name); 3388 free(newc); 3389 return -1; 3390 } 3391 head = policydbp->ocontexts[OCON_NETIF]; 3392 3393 for (c = head; c; c = c->next) { 3394 if (!strcmp(newc->u.name, c->u.name)) { 3395 yyerror2("duplicate entry for network interface %s", 3396 newc->u.name); 3397 context_destroy(&newc->context[0]); 3398 context_destroy(&newc->context[1]); 3399 free(newc->u.name); 3400 free(newc); 3401 return -1; 3402 } 3403 } 3404 3405 newc->next = head; 3406 policydbp->ocontexts[OCON_NETIF] = newc; 3407 return 0; 3408} 3409 3410int define_ipv4_node_context() 3411{ 3412 char *id; 3413 int rc = 0; 3414 struct in_addr addr, mask; 3415 ocontext_t *newc, *c, *l, *head; 3416 3417 if (pass == 1) { 3418 free(queue_remove(id_queue)); 3419 free(queue_remove(id_queue)); 3420 parse_security_context(NULL); 3421 goto out; 3422 } 3423 3424 id = queue_remove(id_queue); 3425 if (!id) { 3426 yyerror("failed to read ipv4 address"); 3427 rc = -1; 3428 goto out; 3429 } 3430 3431 rc = inet_pton(AF_INET, id, &addr); 3432 free(id); 3433 if (rc < 1) { 3434 yyerror("failed to parse ipv4 address"); 3435 if (rc == 0) 3436 rc = -1; 3437 goto out; 3438 } 3439 3440 id = queue_remove(id_queue); 3441 if (!id) { 3442 yyerror("failed to read ipv4 address"); 3443 rc = -1; 3444 goto out; 3445 } 3446 3447 rc = inet_pton(AF_INET, id, &mask); 3448 free(id); 3449 if (rc < 1) { 3450 yyerror("failed to parse ipv4 mask"); 3451 if (rc == 0) 3452 rc = -1; 3453 goto out; 3454 } 3455 3456 newc = malloc(sizeof(ocontext_t)); 3457 if (!newc) { 3458 yyerror("out of memory"); 3459 rc = -1; 3460 goto out; 3461 } 3462 3463 memset(newc, 0, sizeof(ocontext_t)); 3464 newc->u.node.addr = addr.s_addr; 3465 newc->u.node.mask = mask.s_addr; 3466 3467 if (parse_security_context(&newc->context[0])) { 3468 free(newc); 3469 return -1; 3470 } 3471 3472 /* Create order of most specific to least retaining 3473 the order specified in the configuration. */ 3474 head = policydbp->ocontexts[OCON_NODE]; 3475 for (l = NULL, c = head; c; l = c, c = c->next) { 3476 if (newc->u.node.mask > c->u.node.mask) 3477 break; 3478 } 3479 3480 newc->next = c; 3481 3482 if (l) 3483 l->next = newc; 3484 else 3485 policydbp->ocontexts[OCON_NODE] = newc; 3486 rc = 0; 3487out: 3488 return rc; 3489} 3490 3491int define_ipv6_node_context(void) 3492{ 3493 char *id; 3494 int rc = 0; 3495 struct in6_addr addr, mask; 3496 ocontext_t *newc, *c, *l, *head; 3497 3498 if (pass == 1) { 3499 free(queue_remove(id_queue)); 3500 free(queue_remove(id_queue)); 3501 parse_security_context(NULL); 3502 goto out; 3503 } 3504 3505 id = queue_remove(id_queue); 3506 if (!id) { 3507 yyerror("failed to read ipv6 address"); 3508 rc = -1; 3509 goto out; 3510 } 3511 3512 rc = inet_pton(AF_INET6, id, &addr); 3513 free(id); 3514 if (rc < 1) { 3515 yyerror("failed to parse ipv6 address"); 3516 if (rc == 0) 3517 rc = -1; 3518 goto out; 3519 } 3520 3521 id = queue_remove(id_queue); 3522 if (!id) { 3523 yyerror("failed to read ipv6 address"); 3524 rc = -1; 3525 goto out; 3526 } 3527 3528 rc = inet_pton(AF_INET6, id, &mask); 3529 free(id); 3530 if (rc < 1) { 3531 yyerror("failed to parse ipv6 mask"); 3532 if (rc == 0) 3533 rc = -1; 3534 goto out; 3535 } 3536 3537 newc = malloc(sizeof(ocontext_t)); 3538 if (!newc) { 3539 yyerror("out of memory"); 3540 rc = -1; 3541 goto out; 3542 } 3543 3544 memset(newc, 0, sizeof(ocontext_t)); 3545 memcpy(&newc->u.node6.addr[0], &addr.s6_addr32[0], 16); 3546 memcpy(&newc->u.node6.mask[0], &mask.s6_addr32[0], 16); 3547 3548 if (parse_security_context(&newc->context[0])) { 3549 free(newc); 3550 rc = -1; 3551 goto out; 3552 } 3553 3554 /* Create order of most specific to least retaining 3555 the order specified in the configuration. */ 3556 head = policydbp->ocontexts[OCON_NODE6]; 3557 for (l = NULL, c = head; c; l = c, c = c->next) { 3558 if (memcmp(&newc->u.node6.mask, &c->u.node6.mask, 16) > 0) 3559 break; 3560 } 3561 3562 newc->next = c; 3563 3564 if (l) 3565 l->next = newc; 3566 else 3567 policydbp->ocontexts[OCON_NODE6] = newc; 3568 3569 rc = 0; 3570 out: 3571 return rc; 3572} 3573 3574int define_fs_use(int behavior) 3575{ 3576 ocontext_t *newc, *c, *head; 3577 3578 if (pass == 1) { 3579 free(queue_remove(id_queue)); 3580 parse_security_context(NULL); 3581 return 0; 3582 } 3583 3584 newc = (ocontext_t *) malloc(sizeof(ocontext_t)); 3585 if (!newc) { 3586 yyerror("out of memory"); 3587 return -1; 3588 } 3589 memset(newc, 0, sizeof(ocontext_t)); 3590 3591 newc->u.name = (char *)queue_remove(id_queue); 3592 if (!newc->u.name) { 3593 free(newc); 3594 return -1; 3595 } 3596 newc->v.behavior = behavior; 3597 if (parse_security_context(&newc->context[0])) { 3598 free(newc->u.name); 3599 free(newc); 3600 return -1; 3601 } 3602 3603 head = policydbp->ocontexts[OCON_FSUSE]; 3604 3605 for (c = head; c; c = c->next) { 3606 if (!strcmp(newc->u.name, c->u.name)) { 3607 yyerror2("duplicate fs_use entry for filesystem type %s", 3608 newc->u.name); 3609 context_destroy(&newc->context[0]); 3610 free(newc->u.name); 3611 free(newc); 3612 return -1; 3613 } 3614 } 3615 3616 newc->next = head; 3617 policydbp->ocontexts[OCON_FSUSE] = newc; 3618 return 0; 3619} 3620 3621int define_genfs_context_helper(char *fstype, int has_type) 3622{ 3623 struct genfs *genfs_p, *genfs, *newgenfs; 3624 ocontext_t *newc, *c, *head, *p; 3625 char *type = NULL; 3626 int len, len2; 3627 3628 if (pass == 1) { 3629 free(fstype); 3630 free(queue_remove(id_queue)); 3631 if (has_type) 3632 free(queue_remove(id_queue)); 3633 parse_security_context(NULL); 3634 return 0; 3635 } 3636 3637 for (genfs_p = NULL, genfs = policydbp->genfs; 3638 genfs; genfs_p = genfs, genfs = genfs->next) { 3639 if (strcmp(fstype, genfs->fstype) <= 0) 3640 break; 3641 } 3642 3643 if (!genfs || strcmp(fstype, genfs->fstype)) { 3644 newgenfs = malloc(sizeof(struct genfs)); 3645 if (!newgenfs) { 3646 yyerror("out of memory"); 3647 return -1; 3648 } 3649 memset(newgenfs, 0, sizeof(struct genfs)); 3650 newgenfs->fstype = fstype; 3651 newgenfs->next = genfs; 3652 if (genfs_p) 3653 genfs_p->next = newgenfs; 3654 else 3655 policydbp->genfs = newgenfs; 3656 genfs = newgenfs; 3657 } 3658 3659 newc = (ocontext_t *) malloc(sizeof(ocontext_t)); 3660 if (!newc) { 3661 yyerror("out of memory"); 3662 return -1; 3663 } 3664 memset(newc, 0, sizeof(ocontext_t)); 3665 3666 newc->u.name = (char *)queue_remove(id_queue); 3667 if (!newc->u.name) 3668 goto fail; 3669 if (has_type) { 3670 type = (char *)queue_remove(id_queue); 3671 if (!type) 3672 goto fail; 3673 if (type[1] != 0) { 3674 yyerror2("invalid type %s", type); 3675 goto fail; 3676 } 3677 switch (type[0]) { 3678 case 'b': 3679 newc->v.sclass = SECCLASS_BLK_FILE; 3680 break; 3681 case 'c': 3682 newc->v.sclass = SECCLASS_CHR_FILE; 3683 break; 3684 case 'd': 3685 newc->v.sclass = SECCLASS_DIR; 3686 break; 3687 case 'p': 3688 newc->v.sclass = SECCLASS_FIFO_FILE; 3689 break; 3690 case 'l': 3691 newc->v.sclass = SECCLASS_LNK_FILE; 3692 break; 3693 case 's': 3694 newc->v.sclass = SECCLASS_SOCK_FILE; 3695 break; 3696 case '-': 3697 newc->v.sclass = SECCLASS_FILE; 3698 break; 3699 default: 3700 yyerror2("invalid type %s", type); 3701 goto fail; 3702 } 3703 } 3704 if (parse_security_context(&newc->context[0])) 3705 goto fail; 3706 3707 head = genfs->head; 3708 3709 for (p = NULL, c = head; c; p = c, c = c->next) { 3710 if (!strcmp(newc->u.name, c->u.name) && 3711 (!newc->v.sclass || !c->v.sclass 3712 || newc->v.sclass == c->v.sclass)) { 3713 yyerror2("duplicate entry for genfs entry (%s, %s)", 3714 fstype, newc->u.name); 3715 goto fail; 3716 } 3717 len = strlen(newc->u.name); 3718 len2 = strlen(c->u.name); 3719 if (len > len2) 3720 break; 3721 } 3722 3723 newc->next = c; 3724 if (p) 3725 p->next = newc; 3726 else 3727 genfs->head = newc; 3728 return 0; 3729 fail: 3730 if (type) 3731 free(type); 3732 context_destroy(&newc->context[0]); 3733 if (fstype) 3734 free(fstype); 3735 if (newc->u.name) 3736 free(newc->u.name); 3737 free(newc); 3738 return -1; 3739} 3740 3741int define_genfs_context(int has_type) 3742{ 3743 return define_genfs_context_helper(queue_remove(id_queue), has_type); 3744} 3745 3746int define_range_trans(int class_specified) 3747{ 3748 char *id; 3749 level_datum_t *levdatum = 0; 3750 class_datum_t *cladatum; 3751 range_trans_rule_t *rule; 3752 int l, add = 1; 3753 3754 if (!mlspol) { 3755 yyerror("range_transition rule in non-MLS configuration"); 3756 return -1; 3757 } 3758 3759 if (pass == 1) { 3760 while ((id = queue_remove(id_queue))) 3761 free(id); 3762 while ((id = queue_remove(id_queue))) 3763 free(id); 3764 if (class_specified) 3765 while ((id = queue_remove(id_queue))) 3766 free(id); 3767 id = queue_remove(id_queue); 3768 free(id); 3769 for (l = 0; l < 2; l++) { 3770 while ((id = queue_remove(id_queue))) { 3771 free(id); 3772 } 3773 id = queue_remove(id_queue); 3774 if (!id) 3775 break; 3776 free(id); 3777 } 3778 return 0; 3779 } 3780 3781 rule = malloc(sizeof(struct range_trans_rule)); 3782 if (!rule) { 3783 yyerror("out of memory"); 3784 return -1; 3785 } 3786 range_trans_rule_init(rule); 3787 3788 while ((id = queue_remove(id_queue))) { 3789 if (set_types(&rule->stypes, id, &add, 0)) 3790 goto out; 3791 } 3792 add = 1; 3793 while ((id = queue_remove(id_queue))) { 3794 if (set_types(&rule->ttypes, id, &add, 0)) 3795 goto out; 3796 } 3797 3798 if (class_specified) { 3799 while ((id = queue_remove(id_queue))) { 3800 if (!is_id_in_scope(SYM_CLASSES, id)) { 3801 yyerror2("class %s is not within scope", id); 3802 free(id); 3803 goto out; 3804 } 3805 cladatum = hashtab_search(policydbp->p_classes.table, 3806 id); 3807 if (!cladatum) { 3808 yyerror2("unknown class %s", id); 3809 goto out; 3810 } 3811 3812 ebitmap_set_bit(&rule->tclasses, cladatum->s.value - 1, 3813 TRUE); 3814 free(id); 3815 } 3816 } else { 3817 cladatum = hashtab_search(policydbp->p_classes.table, 3818 "process"); 3819 if (!cladatum) { 3820 yyerror2("could not find process class for " 3821 "legacy range_transition statement"); 3822 goto out; 3823 } 3824 3825 ebitmap_set_bit(&rule->tclasses, cladatum->s.value - 1, TRUE); 3826 } 3827 3828 id = (char *)queue_remove(id_queue); 3829 if (!id) { 3830 yyerror("no range in range_transition definition?"); 3831 goto out; 3832 } 3833 for (l = 0; l < 2; l++) { 3834 levdatum = hashtab_search(policydbp->p_levels.table, id); 3835 if (!levdatum) { 3836 yyerror2("unknown level %s used in range_transition " 3837 "definition", id); 3838 free(id); 3839 goto out; 3840 } 3841 free(id); 3842 3843 rule->trange.level[l].sens = levdatum->level->sens; 3844 3845 while ((id = queue_remove(id_queue))) { 3846 if (parse_semantic_categories(id, levdatum, 3847 &rule->trange.level[l].cat)) { 3848 free(id); 3849 goto out; 3850 } 3851 free(id); 3852 } 3853 3854 id = (char *)queue_remove(id_queue); 3855 if (!id) 3856 break; 3857 } 3858 if (l == 0) { 3859 if (mls_semantic_level_cpy(&rule->trange.level[1], 3860 &rule->trange.level[0])) { 3861 yyerror("out of memory"); 3862 goto out; 3863 } 3864 } 3865 3866 append_range_trans(rule); 3867 return 0; 3868 3869out: 3870 range_trans_rule_destroy(rule); 3871 return -1; 3872} 3873 3874/* FLASK */ 3875