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