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