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