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