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 uint32_t i; 1525 int add = 1; 1526 1527 avrule = malloc(sizeof(avrule_t)); 1528 if (!avrule) { 1529 yyerror("out of memory"); 1530 return -1; 1531 } 1532 avrule_init(avrule); 1533 avrule->specified = which; 1534 avrule->line = policydb_lineno; 1535 avrule->source_line = source_lineno; 1536 avrule->source_filename = strdup(source_file); 1537 if (!avrule->source_filename) { 1538 yyerror("out of memory"); 1539 return -1; 1540 } 1541 1542 while ((id = queue_remove(id_queue))) { 1543 if (set_types(&avrule->stypes, id, &add, 0)) 1544 goto bad; 1545 } 1546 add = 1; 1547 while ((id = queue_remove(id_queue))) { 1548 if (set_types(&avrule->ttypes, id, &add, 0)) 1549 goto bad; 1550 } 1551 1552 ebitmap_init(&tclasses); 1553 if (read_classes(&tclasses)) 1554 goto bad; 1555 1556 id = (char *)queue_remove(id_queue); 1557 if (!id) { 1558 yyerror("no newtype?"); 1559 goto bad; 1560 } 1561 if (!is_id_in_scope(SYM_TYPES, id)) { 1562 yyerror2("type %s is not within scope", id); 1563 free(id); 1564 goto bad; 1565 } 1566 datum = (type_datum_t *) hashtab_search(policydbp->p_types.table, 1567 (hashtab_key_t) id); 1568 if (!datum || datum->flavor == TYPE_ATTRIB) { 1569 yyerror2("unknown type %s", id); 1570 goto bad; 1571 } 1572 1573 ebitmap_for_each_bit(&tclasses, node, i) { 1574 if (ebitmap_node_get_bit(node, i)) { 1575 perm = malloc(sizeof(class_perm_node_t)); 1576 if (!perm) { 1577 yyerror("out of memory"); 1578 goto bad; 1579 } 1580 class_perm_node_init(perm); 1581 perm->tclass = i + 1; 1582 perm->data = datum->s.value; 1583 perm->next = avrule->perms; 1584 avrule->perms = perm; 1585 } 1586 } 1587 ebitmap_destroy(&tclasses); 1588 1589 *rule = avrule; 1590 return 0; 1591 1592 bad: 1593 avrule_destroy(avrule); 1594 free(avrule); 1595 return -1; 1596 } 1597 1598 int define_compute_type(int which) 1599 { 1600 char *id; 1601 avrule_t *avrule; 1602 1603 if (pass == 1) { 1604 while ((id = queue_remove(id_queue))) 1605 free(id); 1606 while ((id = queue_remove(id_queue))) 1607 free(id); 1608 while ((id = queue_remove(id_queue))) 1609 free(id); 1610 id = queue_remove(id_queue); 1611 free(id); 1612 return 0; 1613 } 1614 1615 if (define_compute_type_helper(which, &avrule)) 1616 return -1; 1617 1618 append_avrule(avrule); 1619 return 0; 1620 } 1621 1622 avrule_t *define_cond_compute_type(int which) 1623 { 1624 char *id; 1625 avrule_t *avrule; 1626 1627 if (pass == 1) { 1628 while ((id = queue_remove(id_queue))) 1629 free(id); 1630 while ((id = queue_remove(id_queue))) 1631 free(id); 1632 while ((id = queue_remove(id_queue))) 1633 free(id); 1634 id = queue_remove(id_queue); 1635 free(id); 1636 return (avrule_t *) 1; 1637 } 1638 1639 if (define_compute_type_helper(which, &avrule)) 1640 return COND_ERR; 1641 1642 return avrule; 1643 } 1644 1645 int define_bool_tunable(int is_tunable) 1646 { 1647 char *id, *bool_value; 1648 cond_bool_datum_t *datum; 1649 int ret; 1650 uint32_t value; 1651 1652 if (pass == 2) { 1653 while ((id = queue_remove(id_queue))) 1654 free(id); 1655 return 0; 1656 } 1657 1658 id = (char *)queue_remove(id_queue); 1659 if (!id) { 1660 yyerror("no identifier for bool definition?"); 1661 return -1; 1662 } 1663 if (id_has_dot(id)) { 1664 free(id); 1665 yyerror("boolean identifiers may not contain periods"); 1666 return -1; 1667 } 1668 datum = (cond_bool_datum_t *) malloc(sizeof(cond_bool_datum_t)); 1669 if (!datum) { 1670 yyerror("out of memory"); 1671 free(id); 1672 return -1; 1673 } 1674 memset(datum, 0, sizeof(cond_bool_datum_t)); 1675 if (is_tunable) 1676 datum->flags |= COND_BOOL_FLAGS_TUNABLE; 1677 ret = declare_symbol(SYM_BOOLS, id, datum, &value, &value); 1678 switch (ret) { 1679 case -3:{ 1680 yyerror("Out of memory!"); 1681 goto cleanup; 1682 } 1683 case -2:{ 1684 yyerror2("duplicate declaration of boolean %s", id); 1685 goto cleanup; 1686 } 1687 case -1:{ 1688 yyerror("could not declare boolean here"); 1689 goto cleanup; 1690 } 1691 case 0: 1692 case 1:{ 1693 break; 1694 } 1695 default:{ 1696 assert(0); /* should never get here */ 1697 } 1698 } 1699 datum->s.value = value; 1700 1701 bool_value = (char *)queue_remove(id_queue); 1702 if (!bool_value) { 1703 yyerror("no default value for bool definition?"); 1704 free(id); 1705 return -1; 1706 } 1707 1708 datum->state = (int)(bool_value[0] == 'T') ? 1 : 0; 1709 return 0; 1710 cleanup: 1711 cond_destroy_bool(id, datum, NULL); 1712 return -1; 1713 } 1714 1715 avrule_t *define_cond_pol_list(avrule_t * avlist, avrule_t * sl) 1716 { 1717 if (pass == 1) { 1718 /* return something so we get through pass 1 */ 1719 return (avrule_t *) 1; 1720 } 1721 1722 if (sl == NULL) { 1723 /* This is a require block, return previous list */ 1724 return avlist; 1725 } 1726 1727 /* prepend the new avlist to the pre-existing one */ 1728 sl->next = avlist; 1729 return sl; 1730 } 1731 1732 typedef struct av_ioctl_range { 1733 uint16_t low; 1734 uint16_t high; 1735 } av_ioctl_range_t; 1736 1737 struct av_ioctl_range_list { 1738 uint8_t omit; 1739 av_ioctl_range_t range; 1740 struct av_ioctl_range_list *next; 1741 }; 1742 1743 int avrule_sort_ioctls(struct av_ioctl_range_list **rangehead) 1744 { 1745 struct av_ioctl_range_list *r, *r2, *sorted, *sortedhead = NULL; 1746 1747 /* order list by range.low */ 1748 for (r = *rangehead; r != NULL; r = r->next) { 1749 sorted = malloc(sizeof(struct av_ioctl_range_list)); 1750 if (sorted == NULL) 1751 goto error; 1752 memcpy(sorted, r, sizeof(struct av_ioctl_range_list)); 1753 sorted->next = NULL; 1754 if (sortedhead == NULL) { 1755 sortedhead = sorted; 1756 continue; 1757 } 1758 for (r2 = sortedhead; r2 != NULL; r2 = r2->next) { 1759 if (sorted->range.low < r2->range.low) { 1760 /* range is the new head */ 1761 sorted->next = r2; 1762 sortedhead = sorted; 1763 break; 1764 } else if ((r2 ->next != NULL) && 1765 (r->range.low < r2->next->range.low)) { 1766 /* insert range between elements */ 1767 sorted->next = r2->next; 1768 r2->next = sorted; 1769 break; 1770 } else if (r2->next == NULL) { 1771 /* range is the new tail*/ 1772 r2->next = sorted; 1773 break; 1774 } 1775 } 1776 } 1777 1778 r = *rangehead; 1779 while (r != NULL) { 1780 r2 = r; 1781 r = r->next; 1782 free(r2); 1783 } 1784 *rangehead = sortedhead; 1785 return 0; 1786 error: 1787 yyerror("out of memory"); 1788 return -1; 1789 } 1790 1791 int avrule_merge_ioctls(struct av_ioctl_range_list **rangehead) 1792 { 1793 struct av_ioctl_range_list *r, *tmp; 1794 r = *rangehead; 1795 while (r != NULL && r->next != NULL) { 1796 /* merge */ 1797 if ((r->range.high + 1) >= r->next->range.low) { 1798 /* keep the higher of the two */ 1799 if (r->range.high < r->next->range.high) 1800 r->range.high = r->next->range.high; 1801 tmp = r->next; 1802 r->next = r->next->next; 1803 free(tmp); 1804 continue; 1805 } 1806 r = r->next; 1807 } 1808 return 0; 1809 } 1810 1811 int avrule_read_ioctls(struct av_ioctl_range_list **rangehead) 1812 { 1813 char *id; 1814 struct av_ioctl_range_list *rnew, *r = NULL; 1815 *rangehead = NULL; 1816 uint8_t omit = 0; 1817 1818 /* read in all the ioctl commands */ 1819 while ((id = queue_remove(id_queue))) { 1820 if (strcmp(id,"~") == 0) { 1821 /* these are values to be omitted */ 1822 free(id); 1823 omit = 1; 1824 } else if (strcmp(id,"-") == 0) { 1825 /* high value of range */ 1826 free(id); 1827 id = queue_remove(id_queue); 1828 r->range.high = (uint16_t) strtoul(id,NULL,0); 1829 if (r->range.high < r->range.low) { 1830 yyerror("Ioctl ranges must be in ascending order."); 1831 return -1; 1832 } 1833 free(id); 1834 } else { 1835 /* read in new low value */ 1836 rnew = malloc(sizeof(struct av_ioctl_range_list)); 1837 if (rnew == NULL) 1838 goto error; 1839 rnew->next = NULL; 1840 if (*rangehead == NULL) { 1841 *rangehead = rnew; 1842 r = *rangehead; 1843 } else { 1844 r->next = rnew; 1845 r = r->next; 1846 } 1847 rnew->range.low = (uint16_t) strtoul(id,NULL,0); 1848 rnew->range.high = rnew->range.low; 1849 free(id); 1850 } 1851 } 1852 r = *rangehead; 1853 r->omit = omit; 1854 return 0; 1855 error: 1856 yyerror("out of memory"); 1857 return -1; 1858 } 1859 1860 /* flip to included ranges */ 1861 int avrule_omit_ioctls(struct av_ioctl_range_list **rangehead) 1862 { 1863 struct av_ioctl_range_list *rnew, *r, *newhead, *r2; 1864 1865 rnew = calloc(1, sizeof(struct av_ioctl_range_list)); 1866 if (!rnew) 1867 goto error; 1868 1869 newhead = rnew; 1870 1871 r = *rangehead; 1872 r2 = newhead; 1873 1874 if (r->range.low == 0) { 1875 r2->range.low = r->range.high + 1; 1876 r = r->next; 1877 } else { 1878 r2->range.low = 0; 1879 } 1880 1881 while (r) { 1882 r2->range.high = r->range.low - 1; 1883 rnew = calloc(1, sizeof(struct av_ioctl_range_list)); 1884 if (!rnew) 1885 goto error; 1886 r2->next = rnew; 1887 r2 = r2->next; 1888 1889 r2->range.low = r->range.high + 1; 1890 if (!r->next) 1891 r2->range.high = 0xffff; 1892 r = r->next; 1893 } 1894 1895 r = *rangehead; 1896 while (r != NULL) { 1897 r2 = r; 1898 r = r->next; 1899 free(r2); 1900 } 1901 *rangehead = newhead; 1902 return 0; 1903 1904 error: 1905 yyerror("out of memory"); 1906 return -1; 1907 } 1908 1909 int avrule_ioctl_ranges(struct av_ioctl_range_list **rangelist) 1910 { 1911 struct av_ioctl_range_list *rangehead; 1912 uint8_t omit; 1913 1914 /* read in ranges to include and omit */ 1915 if (avrule_read_ioctls(&rangehead)) 1916 return -1; 1917 omit = rangehead->omit; 1918 if (rangehead == NULL) { 1919 yyerror("error processing ioctl commands"); 1920 return -1; 1921 } 1922 /* sort and merge the input ioctls */ 1923 if (avrule_sort_ioctls(&rangehead)) 1924 return -1; 1925 if (avrule_merge_ioctls(&rangehead)) 1926 return -1; 1927 /* flip ranges if these are ommited*/ 1928 if (omit) { 1929 if (avrule_omit_ioctls(&rangehead)) 1930 return -1; 1931 } 1932 1933 *rangelist = rangehead; 1934 return 0; 1935 } 1936 1937 int define_te_avtab_xperms_helper(int which, avrule_t ** rule) 1938 { 1939 char *id; 1940 class_perm_node_t *perms, *tail = NULL, *cur_perms = NULL; 1941 class_datum_t *cladatum; 1942 perm_datum_t *perdatum = NULL; 1943 ebitmap_t tclasses; 1944 ebitmap_node_t *node; 1945 avrule_t *avrule; 1946 unsigned int i; 1947 int add = 1, ret = 0; 1948 1949 avrule = (avrule_t *) malloc(sizeof(avrule_t)); 1950 if (!avrule) { 1951 yyerror("out of memory"); 1952 ret = -1; 1953 goto out; 1954 } 1955 avrule_init(avrule); 1956 avrule->specified = which; 1957 avrule->line = policydb_lineno; 1958 avrule->source_line = source_lineno; 1959 avrule->source_filename = strdup(source_file); 1960 avrule->xperms = NULL; 1961 if (!avrule->source_filename) { 1962 yyerror("out of memory"); 1963 return -1; 1964 } 1965 1966 while ((id = queue_remove(id_queue))) { 1967 if (set_types 1968 (&avrule->stypes, id, &add, 1969 which == AVRULE_XPERMS_NEVERALLOW ? 1 : 0)) { 1970 ret = -1; 1971 goto out; 1972 } 1973 } 1974 add = 1; 1975 while ((id = queue_remove(id_queue))) { 1976 if (strcmp(id, "self") == 0) { 1977 free(id); 1978 avrule->flags |= RULE_SELF; 1979 continue; 1980 } 1981 if (set_types 1982 (&avrule->ttypes, id, &add, 1983 which == AVRULE_XPERMS_NEVERALLOW ? 1 : 0)) { 1984 ret = -1; 1985 goto out; 1986 } 1987 } 1988 1989 ebitmap_init(&tclasses); 1990 ret = read_classes(&tclasses); 1991 if (ret) 1992 goto out; 1993 1994 perms = NULL; 1995 id = queue_head(id_queue); 1996 ebitmap_for_each_bit(&tclasses, node, i) { 1997 if (!ebitmap_node_get_bit(node, i)) 1998 continue; 1999 cur_perms = 2000 (class_perm_node_t *) malloc(sizeof(class_perm_node_t)); 2001 if (!cur_perms) { 2002 yyerror("out of memory"); 2003 ret = -1; 2004 goto out; 2005 } 2006 class_perm_node_init(cur_perms); 2007 cur_perms->tclass = i + 1; 2008 if (!perms) 2009 perms = cur_perms; 2010 if (tail) 2011 tail->next = cur_perms; 2012 tail = cur_perms; 2013 2014 cladatum = policydbp->class_val_to_struct[i]; 2015 perdatum = hashtab_search(cladatum->permissions.table, id); 2016 if (!perdatum) { 2017 if (cladatum->comdatum) { 2018 perdatum = hashtab_search(cladatum->comdatum-> 2019 permissions.table, 2020 id); 2021 } 2022 } 2023 if (!perdatum) { 2024 yyerror2("permission %s is not defined" 2025 " for class %s", id, 2026 policydbp->p_class_val_to_name[i]); 2027 continue; 2028 } else if (!is_perm_in_scope (id, policydbp->p_class_val_to_name[i])) { 2029 yyerror2("permission %s of class %s is" 2030 " not within scope", id, 2031 policydbp->p_class_val_to_name[i]); 2032 continue; 2033 } else { 2034 cur_perms->data |= 1U << (perdatum->s.value - 1); 2035 } 2036 } 2037 2038 ebitmap_destroy(&tclasses); 2039 2040 avrule->perms = perms; 2041 *rule = avrule; 2042 2043 out: 2044 return ret; 2045 } 2046 2047 /* index of the u32 containing the permission */ 2048 #define XPERM_IDX(x) (x >> 5) 2049 /* set bits 0 through x-1 within the u32 */ 2050 #define XPERM_SETBITS(x) ((1 << (x & 0x1f)) - 1) 2051 /* low value for this u32 */ 2052 #define XPERM_LOW(x) (x << 5) 2053 /* high value for this u32 */ 2054 #define XPERM_HIGH(x) (((x + 1) << 5) - 1) 2055 void avrule_xperm_setrangebits(uint16_t low, uint16_t high, 2056 av_extended_perms_t *xperms) 2057 { 2058 unsigned int i; 2059 uint16_t h = high + 1; 2060 /* for each u32 that this low-high range touches, set driver permissions */ 2061 for (i = XPERM_IDX(low); i <= XPERM_IDX(high); i++) { 2062 /* set all bits in u32 */ 2063 if ((low <= XPERM_LOW(i)) && (high >= XPERM_HIGH(i))) 2064 xperms->perms[i] |= ~0U; 2065 /* set low bits */ 2066 else if ((low <= XPERM_LOW(i)) && (high < XPERM_HIGH(i))) 2067 xperms->perms[i] |= XPERM_SETBITS(h); 2068 /* set high bits */ 2069 else if ((low > XPERM_LOW(i)) && (high >= XPERM_HIGH(i))) 2070 xperms->perms[i] |= ~0U - XPERM_SETBITS(low); 2071 /* set middle bits */ 2072 else if ((low > XPERM_LOW(i)) && (high <= XPERM_HIGH(i))) 2073 xperms->perms[i] |= XPERM_SETBITS(h) - XPERM_SETBITS(low); 2074 } 2075 } 2076 2077 int avrule_xperms_used(av_extended_perms_t *xperms) 2078 { 2079 unsigned int i; 2080 2081 for (i = 0; i < sizeof(xperms->perms)/sizeof(xperms->perms[0]); i++) { 2082 if (xperms->perms[i]) 2083 return 1; 2084 } 2085 return 0; 2086 } 2087 2088 /* 2089 * using definitions found in kernel document ioctl-number.txt 2090 * The kernel components of an ioctl command are: 2091 * dir, size, driver, and fucntion. Only the driver and function fields 2092 * are considered here 2093 */ 2094 #define IOC_DRIV(x) (x >> 8) 2095 #define IOC_FUNC(x) (x & 0xff) 2096 #define IOC_CMD(driver, func) ((driver << 8) + func) 2097 int avrule_ioctl_partialdriver(struct av_ioctl_range_list *rangelist, 2098 av_extended_perms_t *complete_driver, 2099 av_extended_perms_t **extended_perms) 2100 { 2101 struct av_ioctl_range_list *r; 2102 av_extended_perms_t *xperms; 2103 uint8_t low, high; 2104 2105 xperms = calloc(1, sizeof(av_extended_perms_t)); 2106 if (!xperms) { 2107 yyerror("out of memory"); 2108 return - 1; 2109 } 2110 2111 r = rangelist; 2112 while(r) { 2113 low = IOC_DRIV(r->range.low); 2114 high = IOC_DRIV(r->range.high); 2115 if (complete_driver) { 2116 if (!xperm_test(low, complete_driver->perms)) 2117 xperm_set(low, xperms->perms); 2118 if (!xperm_test(high, complete_driver->perms)) 2119 xperm_set(high, xperms->perms); 2120 } else { 2121 xperm_set(low, xperms->perms); 2122 xperm_set(high, xperms->perms); 2123 } 2124 r = r->next; 2125 } 2126 if (avrule_xperms_used(xperms)) { 2127 *extended_perms = xperms; 2128 } else { 2129 free(xperms); 2130 *extended_perms = NULL; 2131 } 2132 return 0; 2133 2134 } 2135 2136 int avrule_ioctl_completedriver(struct av_ioctl_range_list *rangelist, 2137 av_extended_perms_t **extended_perms) 2138 { 2139 struct av_ioctl_range_list *r; 2140 av_extended_perms_t *xperms; 2141 uint16_t low, high; 2142 xperms = calloc(1, sizeof(av_extended_perms_t)); 2143 if (!xperms) { 2144 yyerror("out of memory"); 2145 return - 1; 2146 } 2147 2148 r = rangelist; 2149 while(r) { 2150 /* 2151 * Any driver code that has sequence 0x00 - 0xff is a complete code, 2152 * 2153 * if command number = 0xff, then round high up to next code, 2154 * else 0x00 - 0xfe keep current code 2155 * of this range. temporarily u32 for the + 1 2156 * to account for possible rollover before right shift 2157 */ 2158 high = IOC_DRIV((uint32_t) (r->range.high + 1)); 2159 /* if 0x00 keep current driver code else 0x01 - 0xff round up to next code*/ 2160 low = IOC_DRIV(r->range.low); 2161 if (IOC_FUNC(r->range.low)) 2162 low++; 2163 if (high > low) 2164 avrule_xperm_setrangebits(low, high - 1, xperms); 2165 r = r->next; 2166 } 2167 if (avrule_xperms_used(xperms)) { 2168 xperms->driver = 0x00; 2169 xperms->specified = AVRULE_XPERMS_IOCTLDRIVER; 2170 *extended_perms = xperms; 2171 } else { 2172 free(xperms); 2173 *extended_perms = NULL; 2174 } 2175 return 0; 2176 } 2177 2178 int avrule_ioctl_func(struct av_ioctl_range_list *rangelist, 2179 av_extended_perms_t **extended_perms, unsigned int driver) 2180 { 2181 struct av_ioctl_range_list *r; 2182 av_extended_perms_t *xperms; 2183 uint16_t low, high; 2184 2185 *extended_perms = NULL; 2186 xperms = calloc(1, sizeof(av_extended_perms_t)); 2187 if (!xperms) { 2188 yyerror("out of memory"); 2189 return - 1; 2190 } 2191 2192 r = rangelist; 2193 /* for the passed in driver code, find the ranges that apply */ 2194 while (r) { 2195 low = r->range.low; 2196 high = r->range.high; 2197 if ((driver != IOC_DRIV(low)) && (driver != IOC_DRIV(high))) { 2198 r = r->next; 2199 continue; 2200 } 2201 2202 if (driver == IOC_DRIV(low)) { 2203 if (high > IOC_CMD(driver, 0xff)) 2204 high = IOC_CMD(driver, 0xff); 2205 2206 } else { 2207 if (low < IOC_CMD(driver, 0)) 2208 low = IOC_CMD(driver, 0); 2209 } 2210 2211 low = IOC_FUNC(low); 2212 high = IOC_FUNC(high); 2213 avrule_xperm_setrangebits(low, high, xperms); 2214 xperms->driver = driver; 2215 xperms->specified = AVRULE_XPERMS_IOCTLFUNCTION; 2216 r = r->next; 2217 } 2218 2219 if (avrule_xperms_used(xperms)) { 2220 *extended_perms = xperms; 2221 } else { 2222 free(xperms); 2223 *extended_perms = NULL; 2224 } 2225 return 0; 2226 } 2227 2228 void avrule_ioctl_freeranges(struct av_ioctl_range_list *rangelist) 2229 { 2230 struct av_ioctl_range_list *r, *tmp; 2231 r = rangelist; 2232 while (r) { 2233 tmp = r; 2234 r = r->next; 2235 free(tmp); 2236 } 2237 } 2238 2239 unsigned int xperms_for_each_bit(unsigned int *bit, av_extended_perms_t *xperms) 2240 { 2241 unsigned int i; 2242 for (i = *bit; i < sizeof(xperms->perms)*8; i++) { 2243 if (xperm_test(i,xperms->perms)) { 2244 xperm_clear(i, xperms->perms); 2245 *bit = i; 2246 return 1; 2247 } 2248 } 2249 return 0; 2250 } 2251 2252 int avrule_cpy(avrule_t *dest, avrule_t *src) 2253 { 2254 class_perm_node_t *src_perms; 2255 class_perm_node_t *dest_perms, *dest_tail; 2256 dest_tail = NULL; 2257 2258 avrule_init(dest); 2259 dest->specified = src->specified; 2260 dest->flags = src->flags; 2261 if (type_set_cpy(&dest->stypes, &src->stypes)) { 2262 yyerror("out of memory"); 2263 return - 1; 2264 } 2265 if (type_set_cpy(&dest->ttypes, &src->ttypes)) { 2266 yyerror("out of memory"); 2267 return - 1; 2268 } 2269 dest->line = src->line; 2270 dest->source_filename = strdup(source_file); 2271 if (!dest->source_filename) { 2272 yyerror("out of memory"); 2273 return -1; 2274 } 2275 dest->source_line = src->source_line; 2276 2277 /* increment through the class perms and copy over */ 2278 src_perms = src->perms; 2279 while (src_perms) { 2280 dest_perms = (class_perm_node_t *) calloc(1, sizeof(class_perm_node_t)); 2281 class_perm_node_init(dest_perms); 2282 if (!dest_perms) { 2283 yyerror("out of memory"); 2284 return -1; 2285 } 2286 if (!dest->perms) 2287 dest->perms = dest_perms; 2288 else 2289 dest_tail->next = dest_perms; 2290 2291 dest_perms->tclass = src_perms->tclass; 2292 dest_perms->data = src_perms->data; 2293 dest_perms->next = NULL; 2294 dest_tail = dest_perms; 2295 src_perms = src_perms->next; 2296 } 2297 return 0; 2298 } 2299 2300 int define_te_avtab_ioctl(avrule_t *avrule_template) 2301 { 2302 avrule_t *avrule; 2303 struct av_ioctl_range_list *rangelist; 2304 av_extended_perms_t *complete_driver, *partial_driver, *xperms; 2305 unsigned int i; 2306 2307 2308 /* organize ioctl ranges */ 2309 if (avrule_ioctl_ranges(&rangelist)) 2310 return -1; 2311 2312 /* create rule for ioctl driver types that are entirely enabled */ 2313 if (avrule_ioctl_completedriver(rangelist, &complete_driver)) 2314 return -1; 2315 if (complete_driver) { 2316 avrule = (avrule_t *) calloc(1, sizeof(avrule_t)); 2317 if (!avrule) { 2318 yyerror("out of memory"); 2319 return -1; 2320 } 2321 if (avrule_cpy(avrule, avrule_template)) 2322 return -1; 2323 avrule->xperms = complete_driver; 2324 append_avrule(avrule); 2325 } 2326 2327 /* flag ioctl driver codes that are partially enabled */ 2328 if (avrule_ioctl_partialdriver(rangelist, complete_driver, &partial_driver)) 2329 return -1; 2330 2331 if (!partial_driver || !avrule_xperms_used(partial_driver)) 2332 goto done; 2333 2334 /* 2335 * create rule for each partially used driver codes 2336 * "partially used" meaning that the code number e.g. socket 0x89 2337 * has some permission bits set and others not set. 2338 */ 2339 i = 0; 2340 while (xperms_for_each_bit(&i, partial_driver)) { 2341 if (avrule_ioctl_func(rangelist, &xperms, i)) 2342 return -1; 2343 2344 if (xperms) { 2345 avrule = (avrule_t *) calloc(1, sizeof(avrule_t)); 2346 if (!avrule) { 2347 yyerror("out of memory"); 2348 return -1; 2349 } 2350 if (avrule_cpy(avrule, avrule_template)) 2351 return -1; 2352 avrule->xperms = xperms; 2353 append_avrule(avrule); 2354 } 2355 } 2356 2357 done: 2358 if (partial_driver) 2359 free(partial_driver); 2360 2361 return 0; 2362 } 2363 2364 int define_te_avtab_extended_perms(int which) 2365 { 2366 char *id; 2367 unsigned int i; 2368 avrule_t *avrule_template; 2369 2370 if (pass == 1) { 2371 for (i = 0; i < 4; i++) { 2372 while ((id = queue_remove(id_queue))) 2373 free(id); 2374 } 2375 return 0; 2376 } 2377 2378 /* populate avrule template with source/target/tclass */ 2379 if (define_te_avtab_xperms_helper(which, &avrule_template)) 2380 return -1; 2381 2382 id = queue_remove(id_queue); 2383 if (strcmp(id,"ioctl") == 0) { 2384 if (define_te_avtab_ioctl(avrule_template)) 2385 return -1; 2386 free(id); 2387 } else { 2388 yyerror("only ioctl extended permissions are supported"); 2389 return -1; 2390 } 2391 return 0; 2392 } 2393 2394 int define_te_avtab_helper(int which, avrule_t ** rule) 2395 { 2396 char *id; 2397 class_datum_t *cladatum; 2398 perm_datum_t *perdatum = NULL; 2399 class_perm_node_t *perms, *tail = NULL, *cur_perms = NULL; 2400 ebitmap_t tclasses; 2401 ebitmap_node_t *node; 2402 avrule_t *avrule; 2403 unsigned int i; 2404 int add = 1, ret = 0; 2405 int suppress = 0; 2406 2407 avrule = (avrule_t *) malloc(sizeof(avrule_t)); 2408 if (!avrule) { 2409 yyerror("memory error"); 2410 ret = -1; 2411 goto out; 2412 } 2413 avrule_init(avrule); 2414 avrule->specified = which; 2415 avrule->line = policydb_lineno; 2416 avrule->source_line = source_lineno; 2417 avrule->source_filename = strdup(source_file); 2418 avrule->xperms = NULL; 2419 if (!avrule->source_filename) { 2420 yyerror("out of memory"); 2421 return -1; 2422 } 2423 2424 2425 while ((id = queue_remove(id_queue))) { 2426 if (set_types 2427 (&avrule->stypes, id, &add, 2428 which == AVRULE_NEVERALLOW ? 1 : 0)) { 2429 ret = -1; 2430 goto out; 2431 } 2432 } 2433 add = 1; 2434 while ((id = queue_remove(id_queue))) { 2435 if (strcmp(id, "self") == 0) { 2436 free(id); 2437 avrule->flags |= RULE_SELF; 2438 continue; 2439 } 2440 if (set_types 2441 (&avrule->ttypes, id, &add, 2442 which == AVRULE_NEVERALLOW ? 1 : 0)) { 2443 ret = -1; 2444 goto out; 2445 } 2446 } 2447 2448 ebitmap_init(&tclasses); 2449 ret = read_classes(&tclasses); 2450 if (ret) 2451 goto out; 2452 2453 perms = NULL; 2454 ebitmap_for_each_bit(&tclasses, node, i) { 2455 if (!ebitmap_node_get_bit(node, i)) 2456 continue; 2457 cur_perms = 2458 (class_perm_node_t *) malloc(sizeof(class_perm_node_t)); 2459 if (!cur_perms) { 2460 yyerror("out of memory"); 2461 ret = -1; 2462 goto out; 2463 } 2464 class_perm_node_init(cur_perms); 2465 cur_perms->tclass = i + 1; 2466 if (!perms) 2467 perms = cur_perms; 2468 if (tail) 2469 tail->next = cur_perms; 2470 tail = cur_perms; 2471 } 2472 2473 while ((id = queue_remove(id_queue))) { 2474 cur_perms = perms; 2475 ebitmap_for_each_bit(&tclasses, node, i) { 2476 if (!ebitmap_node_get_bit(node, i)) 2477 continue; 2478 cladatum = policydbp->class_val_to_struct[i]; 2479 2480 if (strcmp(id, "*") == 0) { 2481 /* set all permissions in the class */ 2482 cur_perms->data = ~0U; 2483 goto next; 2484 } 2485 2486 if (strcmp(id, "~") == 0) { 2487 /* complement the set */ 2488 if (which == AVRULE_DONTAUDIT) 2489 yywarn("dontaudit rule with a ~?"); 2490 cur_perms->data = ~cur_perms->data; 2491 goto next; 2492 } 2493 2494 perdatum = 2495 hashtab_search(cladatum->permissions.table, id); 2496 if (!perdatum) { 2497 if (cladatum->comdatum) { 2498 perdatum = 2499 hashtab_search(cladatum->comdatum-> 2500 permissions.table, 2501 id); 2502 } 2503 } 2504 if (!perdatum) { 2505 if (!suppress) 2506 yyerror2("permission %s is not defined" 2507 " for class %s", id, 2508 policydbp->p_class_val_to_name[i]); 2509 continue; 2510 } else 2511 if (!is_perm_in_scope 2512 (id, policydbp->p_class_val_to_name[i])) { 2513 if (!suppress) { 2514 yyerror2("permission %s of class %s is" 2515 " not within scope", id, 2516 policydbp->p_class_val_to_name[i]); 2517 } 2518 continue; 2519 } else { 2520 cur_perms->data |= 1U << (perdatum->s.value - 1); 2521 } 2522 next: 2523 cur_perms = cur_perms->next; 2524 } 2525 2526 free(id); 2527 } 2528 2529 ebitmap_destroy(&tclasses); 2530 2531 avrule->perms = perms; 2532 *rule = avrule; 2533 2534 out: 2535 return ret; 2536 2537 } 2538 2539 avrule_t *define_cond_te_avtab(int which) 2540 { 2541 char *id; 2542 avrule_t *avrule; 2543 int i; 2544 2545 if (pass == 1) { 2546 for (i = 0; i < 4; i++) { 2547 while ((id = queue_remove(id_queue))) 2548 free(id); 2549 } 2550 return (avrule_t *) 1; /* any non-NULL value */ 2551 } 2552 2553 if (define_te_avtab_helper(which, &avrule)) 2554 return COND_ERR; 2555 2556 return avrule; 2557 } 2558 2559 int define_te_avtab(int which) 2560 { 2561 char *id; 2562 avrule_t *avrule; 2563 int i; 2564 2565 if (pass == 1) { 2566 for (i = 0; i < 4; i++) { 2567 while ((id = queue_remove(id_queue))) 2568 free(id); 2569 } 2570 return 0; 2571 } 2572 2573 if (define_te_avtab_helper(which, &avrule)) 2574 return -1; 2575 2576 /* append this avrule to the end of the current rules list */ 2577 append_avrule(avrule); 2578 return 0; 2579 } 2580 2581 /* The role-types rule is no longer used to declare regular role or 2582 * role attribute, but solely aimed for declaring role-types associations. 2583 */ 2584 int define_role_types(void) 2585 { 2586 role_datum_t *role; 2587 char *id; 2588 int add = 1; 2589 2590 if (pass == 1) { 2591 while ((id = queue_remove(id_queue))) 2592 free(id); 2593 return 0; 2594 } 2595 2596 id = (char *)queue_remove(id_queue); 2597 if (!id) { 2598 yyerror("no role name for role-types rule?"); 2599 return -1; 2600 } 2601 2602 if (!is_id_in_scope(SYM_ROLES, id)) { 2603 yyerror2("role %s is not within scope", id); 2604 free(id); 2605 return -1; 2606 } 2607 2608 role = hashtab_search(policydbp->p_roles.table, id); 2609 if (!role) { 2610 yyerror2("unknown role %s", id); 2611 free(id); 2612 return -1; 2613 } 2614 2615 while ((id = queue_remove(id_queue))) { 2616 if (set_types(&role->types, id, &add, 0)) 2617 return -1; 2618 } 2619 2620 return 0; 2621 } 2622 2623 int define_attrib_role(void) 2624 { 2625 if (pass == 2) { 2626 free(queue_remove(id_queue)); 2627 return 0; 2628 } 2629 2630 /* Declare a role attribute */ 2631 if (declare_role(TRUE) == NULL) 2632 return -1; 2633 2634 return 0; 2635 } 2636 2637 int define_role_attr(void) 2638 { 2639 char *id; 2640 role_datum_t *r, *attr; 2641 2642 if (pass == 2) { 2643 while ((id = queue_remove(id_queue))) 2644 free(id); 2645 return 0; 2646 } 2647 2648 /* Declare a regular role */ 2649 if ((r = declare_role(FALSE)) == NULL) 2650 return -1; 2651 2652 while ((id = queue_remove(id_queue))) { 2653 if (!is_id_in_scope(SYM_ROLES, id)) { 2654 yyerror2("attribute %s is not within scope", id); 2655 free(id); 2656 return -1; 2657 } 2658 attr = hashtab_search(policydbp->p_roles.table, id); 2659 if (!attr) { 2660 /* treat it as a fatal error */ 2661 yyerror2("role attribute %s is not declared", id); 2662 free(id); 2663 return -1; 2664 } 2665 2666 if (attr->flavor != ROLE_ATTRIB) { 2667 yyerror2("%s is a regular role, not an attribute", id); 2668 free(id); 2669 return -1; 2670 } 2671 2672 if ((attr = get_local_role(id, attr->s.value, 1)) == NULL) { 2673 yyerror("Out of memory!"); 2674 return -1; 2675 } 2676 2677 if (ebitmap_set_bit(&attr->roles, (r->s.value - 1), TRUE)) { 2678 yyerror("out of memory"); 2679 return -1; 2680 } 2681 } 2682 2683 return 0; 2684 } 2685 2686 int define_roleattribute(void) 2687 { 2688 char *id; 2689 role_datum_t *r, *attr; 2690 2691 if (pass == 2) { 2692 while ((id = queue_remove(id_queue))) 2693 free(id); 2694 return 0; 2695 } 2696 2697 id = (char *)queue_remove(id_queue); 2698 if (!id) { 2699 yyerror("no role name for roleattribute definition?"); 2700 return -1; 2701 } 2702 2703 if (!is_id_in_scope(SYM_ROLES, id)) { 2704 yyerror2("role %s is not within scope", id); 2705 free(id); 2706 return -1; 2707 } 2708 r = hashtab_search(policydbp->p_roles.table, id); 2709 /* We support adding one role attribute into another */ 2710 if (!r) { 2711 yyerror2("unknown role %s", id); 2712 free(id); 2713 return -1; 2714 } 2715 2716 while ((id = queue_remove(id_queue))) { 2717 if (!is_id_in_scope(SYM_ROLES, id)) { 2718 yyerror2("attribute %s is not within scope", id); 2719 free(id); 2720 return -1; 2721 } 2722 attr = hashtab_search(policydbp->p_roles.table, id); 2723 if (!attr) { 2724 /* treat it as a fatal error */ 2725 yyerror2("role attribute %s is not declared", id); 2726 free(id); 2727 return -1; 2728 } 2729 2730 if (attr->flavor != ROLE_ATTRIB) { 2731 yyerror2("%s is a regular role, not an attribute", id); 2732 free(id); 2733 return -1; 2734 } 2735 2736 if ((attr = get_local_role(id, attr->s.value, 1)) == NULL) { 2737 yyerror("Out of memory!"); 2738 return -1; 2739 } 2740 2741 if (ebitmap_set_bit(&attr->roles, (r->s.value - 1), TRUE)) { 2742 yyerror("out of memory"); 2743 return -1; 2744 } 2745 } 2746 2747 return 0; 2748 } 2749 2750 role_datum_t *merge_roles_dom(role_datum_t * r1, role_datum_t * r2) 2751 { 2752 role_datum_t *new; 2753 2754 if (pass == 1) { 2755 return (role_datum_t *) 1; /* any non-NULL value */ 2756 } 2757 2758 new = malloc(sizeof(role_datum_t)); 2759 if (!new) { 2760 yyerror("out of memory"); 2761 return NULL; 2762 } 2763 memset(new, 0, sizeof(role_datum_t)); 2764 new->s.value = 0; /* temporary role */ 2765 if (ebitmap_or(&new->dominates, &r1->dominates, &r2->dominates)) { 2766 yyerror("out of memory"); 2767 free(new); 2768 return NULL; 2769 } 2770 if (ebitmap_or(&new->types.types, &r1->types.types, &r2->types.types)) { 2771 yyerror("out of memory"); 2772 free(new); 2773 return NULL; 2774 } 2775 if (!r1->s.value) { 2776 /* free intermediate result */ 2777 type_set_destroy(&r1->types); 2778 ebitmap_destroy(&r1->dominates); 2779 free(r1); 2780 } 2781 if (!r2->s.value) { 2782 /* free intermediate result */ 2783 yyerror("right hand role is temporary?"); 2784 type_set_destroy(&r2->types); 2785 ebitmap_destroy(&r2->dominates); 2786 free(r2); 2787 } 2788 return new; 2789 } 2790 2791 /* This function eliminates the ordering dependency of role dominance rule */ 2792 static int dominate_role_recheck(hashtab_key_t key __attribute__ ((unused)), 2793 hashtab_datum_t datum, void *arg) 2794 { 2795 role_datum_t *rdp = (role_datum_t *) arg; 2796 role_datum_t *rdatum = (role_datum_t *) datum; 2797 ebitmap_node_t *node; 2798 uint32_t i; 2799 2800 /* Don't bother to process against self role */ 2801 if (rdatum->s.value == rdp->s.value) 2802 return 0; 2803 2804 /* If a dominating role found */ 2805 if (ebitmap_get_bit(&(rdatum->dominates), rdp->s.value - 1)) { 2806 ebitmap_t types; 2807 ebitmap_init(&types); 2808 if (type_set_expand(&rdp->types, &types, policydbp, 1)) { 2809 ebitmap_destroy(&types); 2810 return -1; 2811 } 2812 /* raise types and dominates from dominated role */ 2813 ebitmap_for_each_bit(&rdp->dominates, node, i) { 2814 if (ebitmap_node_get_bit(node, i)) 2815 if (ebitmap_set_bit 2816 (&rdatum->dominates, i, TRUE)) 2817 goto oom; 2818 } 2819 ebitmap_for_each_bit(&types, node, i) { 2820 if (ebitmap_node_get_bit(node, i)) 2821 if (ebitmap_set_bit 2822 (&rdatum->types.types, i, TRUE)) 2823 goto oom; 2824 } 2825 ebitmap_destroy(&types); 2826 } 2827 2828 /* go through all the roles */ 2829 return 0; 2830 oom: 2831 yyerror("Out of memory"); 2832 return -1; 2833 } 2834 2835 role_datum_t *define_role_dom(role_datum_t * r) 2836 { 2837 role_datum_t *role; 2838 char *role_id; 2839 ebitmap_node_t *node; 2840 unsigned int i; 2841 int ret; 2842 2843 if (pass == 1) { 2844 role_id = queue_remove(id_queue); 2845 free(role_id); 2846 return (role_datum_t *) 1; /* any non-NULL value */ 2847 } 2848 2849 yywarn("Role dominance has been deprecated"); 2850 2851 role_id = queue_remove(id_queue); 2852 if (!is_id_in_scope(SYM_ROLES, role_id)) { 2853 yyerror2("role %s is not within scope", role_id); 2854 free(role_id); 2855 return NULL; 2856 } 2857 role = (role_datum_t *) hashtab_search(policydbp->p_roles.table, 2858 role_id); 2859 if (!role) { 2860 role = (role_datum_t *) malloc(sizeof(role_datum_t)); 2861 if (!role) { 2862 yyerror("out of memory"); 2863 free(role_id); 2864 return NULL; 2865 } 2866 memset(role, 0, sizeof(role_datum_t)); 2867 ret = 2868 declare_symbol(SYM_ROLES, (hashtab_key_t) role_id, 2869 (hashtab_datum_t) role, &role->s.value, 2870 &role->s.value); 2871 switch (ret) { 2872 case -3:{ 2873 yyerror("Out of memory!"); 2874 goto cleanup; 2875 } 2876 case -2:{ 2877 yyerror2("duplicate declaration of role %s", 2878 role_id); 2879 goto cleanup; 2880 } 2881 case -1:{ 2882 yyerror("could not declare role here"); 2883 goto cleanup; 2884 } 2885 case 0: 2886 case 1:{ 2887 break; 2888 } 2889 default:{ 2890 assert(0); /* should never get here */ 2891 } 2892 } 2893 if (ebitmap_set_bit(&role->dominates, role->s.value - 1, TRUE)) { 2894 yyerror("Out of memory!"); 2895 goto cleanup; 2896 } 2897 } 2898 if (r) { 2899 ebitmap_t types; 2900 ebitmap_init(&types); 2901 ebitmap_for_each_bit(&r->dominates, node, i) { 2902 if (ebitmap_node_get_bit(node, i)) 2903 if (ebitmap_set_bit(&role->dominates, i, TRUE)) 2904 goto oom; 2905 } 2906 if (type_set_expand(&r->types, &types, policydbp, 1)) { 2907 ebitmap_destroy(&types); 2908 return NULL; 2909 } 2910 ebitmap_for_each_bit(&types, node, i) { 2911 if (ebitmap_node_get_bit(node, i)) 2912 if (ebitmap_set_bit 2913 (&role->types.types, i, TRUE)) 2914 goto oom; 2915 } 2916 ebitmap_destroy(&types); 2917 if (!r->s.value) { 2918 /* free intermediate result */ 2919 type_set_destroy(&r->types); 2920 ebitmap_destroy(&r->dominates); 2921 free(r); 2922 } 2923 /* 2924 * Now go through all the roles and escalate this role's 2925 * dominates and types if a role dominates this role. 2926 */ 2927 hashtab_map(policydbp->p_roles.table, 2928 dominate_role_recheck, role); 2929 } 2930 return role; 2931 cleanup: 2932 free(role_id); 2933 role_datum_destroy(role); 2934 free(role); 2935 return NULL; 2936 oom: 2937 yyerror("Out of memory"); 2938 goto cleanup; 2939 } 2940 2941 static int role_val_to_name_helper(hashtab_key_t key, hashtab_datum_t datum, 2942 void *p) 2943 { 2944 struct val_to_name *v = p; 2945 role_datum_t *roldatum; 2946 2947 roldatum = (role_datum_t *) datum; 2948 2949 if (v->val == roldatum->s.value) { 2950 v->name = key; 2951 return 1; 2952 } 2953 2954 return 0; 2955 } 2956 2957 static char *role_val_to_name(unsigned int val) 2958 { 2959 struct val_to_name v; 2960 int rc; 2961 2962 v.val = val; 2963 rc = hashtab_map(policydbp->p_roles.table, role_val_to_name_helper, &v); 2964 if (rc) 2965 return v.name; 2966 return NULL; 2967 } 2968 2969 static int set_roles(role_set_t * set, char *id) 2970 { 2971 role_datum_t *r; 2972 2973 if (strcmp(id, "*") == 0) { 2974 free(id); 2975 yyerror("* is not allowed for role sets"); 2976 return -1; 2977 } 2978 2979 if (strcmp(id, "~") == 0) { 2980 free(id); 2981 yyerror("~ is not allowed for role sets"); 2982 return -1; 2983 } 2984 if (!is_id_in_scope(SYM_ROLES, id)) { 2985 yyerror2("role %s is not within scope", id); 2986 free(id); 2987 return -1; 2988 } 2989 r = hashtab_search(policydbp->p_roles.table, id); 2990 if (!r) { 2991 yyerror2("unknown role %s", id); 2992 free(id); 2993 return -1; 2994 } 2995 2996 if (ebitmap_set_bit(&set->roles, r->s.value - 1, TRUE)) { 2997 yyerror("out of memory"); 2998 free(id); 2999 return -1; 3000 } 3001 free(id); 3002 return 0; 3003 } 3004 3005 int define_role_trans(int class_specified) 3006 { 3007 char *id; 3008 role_datum_t *role; 3009 role_set_t roles; 3010 type_set_t types; 3011 class_datum_t *cladatum; 3012 ebitmap_t e_types, e_roles, e_classes; 3013 ebitmap_node_t *tnode, *rnode, *cnode; 3014 struct role_trans *tr = NULL; 3015 struct role_trans_rule *rule = NULL; 3016 unsigned int i, j, k; 3017 int add = 1; 3018 3019 if (pass == 1) { 3020 while ((id = queue_remove(id_queue))) 3021 free(id); 3022 while ((id = queue_remove(id_queue))) 3023 free(id); 3024 if (class_specified) 3025 while ((id = queue_remove(id_queue))) 3026 free(id); 3027 id = queue_remove(id_queue); 3028 free(id); 3029 return 0; 3030 } 3031 3032 role_set_init(&roles); 3033 ebitmap_init(&e_roles); 3034 type_set_init(&types); 3035 ebitmap_init(&e_types); 3036 ebitmap_init(&e_classes); 3037 3038 while ((id = queue_remove(id_queue))) { 3039 if (set_roles(&roles, id)) 3040 return -1; 3041 } 3042 add = 1; 3043 while ((id = queue_remove(id_queue))) { 3044 if (set_types(&types, id, &add, 0)) 3045 return -1; 3046 } 3047 3048 if (class_specified) { 3049 if (read_classes(&e_classes)) 3050 return -1; 3051 } else { 3052 cladatum = hashtab_search(policydbp->p_classes.table, 3053 "process"); 3054 if (!cladatum) { 3055 yyerror2("could not find process class for " 3056 "legacy role_transition statement"); 3057 return -1; 3058 } 3059 3060 if (ebitmap_set_bit(&e_classes, cladatum->s.value - 1, TRUE)) { 3061 yyerror("out of memory"); 3062 return -1; 3063 } 3064 } 3065 3066 id = (char *)queue_remove(id_queue); 3067 if (!id) { 3068 yyerror("no new role in transition definition?"); 3069 goto bad; 3070 } 3071 if (!is_id_in_scope(SYM_ROLES, id)) { 3072 yyerror2("role %s is not within scope", id); 3073 free(id); 3074 goto bad; 3075 } 3076 role = hashtab_search(policydbp->p_roles.table, id); 3077 if (!role) { 3078 yyerror2("unknown role %s used in transition definition", id); 3079 goto bad; 3080 } 3081 3082 if (role->flavor != ROLE_ROLE) { 3083 yyerror2("the new role %s must be a regular role", id); 3084 goto bad; 3085 } 3086 3087 /* This ebitmap business is just to ensure that there are not conflicting role_trans rules */ 3088 if (role_set_expand(&roles, &e_roles, policydbp, NULL, NULL)) 3089 goto bad; 3090 3091 if (type_set_expand(&types, &e_types, policydbp, 1)) 3092 goto bad; 3093 3094 ebitmap_for_each_bit(&e_roles, rnode, i) { 3095 if (!ebitmap_node_get_bit(rnode, i)) 3096 continue; 3097 ebitmap_for_each_bit(&e_types, tnode, j) { 3098 if (!ebitmap_node_get_bit(tnode, j)) 3099 continue; 3100 ebitmap_for_each_bit(&e_classes, cnode, k) { 3101 if (!ebitmap_node_get_bit(cnode, k)) 3102 continue; 3103 for (tr = policydbp->role_tr; tr; 3104 tr = tr->next) { 3105 if (tr->role == (i + 1) && 3106 tr->type == (j + 1) && 3107 tr->tclass == (k + 1)) { 3108 yyerror2("duplicate role " 3109 "transition for " 3110 "(%s,%s,%s)", 3111 role_val_to_name(i+1), 3112 policydbp->p_type_val_to_name[j], 3113 policydbp->p_class_val_to_name[k]); 3114 goto bad; 3115 } 3116 } 3117 3118 tr = malloc(sizeof(struct role_trans)); 3119 if (!tr) { 3120 yyerror("out of memory"); 3121 return -1; 3122 } 3123 memset(tr, 0, sizeof(struct role_trans)); 3124 tr->role = i + 1; 3125 tr->type = j + 1; 3126 tr->tclass = k + 1; 3127 tr->new_role = role->s.value; 3128 tr->next = policydbp->role_tr; 3129 policydbp->role_tr = tr; 3130 } 3131 } 3132 } 3133 /* Now add the real rule */ 3134 rule = malloc(sizeof(struct role_trans_rule)); 3135 if (!rule) { 3136 yyerror("out of memory"); 3137 return -1; 3138 } 3139 memset(rule, 0, sizeof(struct role_trans_rule)); 3140 rule->roles = roles; 3141 rule->types = types; 3142 rule->classes = e_classes; 3143 rule->new_role = role->s.value; 3144 3145 append_role_trans(rule); 3146 3147 ebitmap_destroy(&e_roles); 3148 ebitmap_destroy(&e_types); 3149 3150 return 0; 3151 3152 bad: 3153 return -1; 3154 } 3155 3156 int define_role_allow(void) 3157 { 3158 char *id; 3159 struct role_allow_rule *ra = 0; 3160 3161 if (pass == 1) { 3162 while ((id = queue_remove(id_queue))) 3163 free(id); 3164 while ((id = queue_remove(id_queue))) 3165 free(id); 3166 return 0; 3167 } 3168 3169 ra = malloc(sizeof(role_allow_rule_t)); 3170 if (!ra) { 3171 yyerror("out of memory"); 3172 return -1; 3173 } 3174 role_allow_rule_init(ra); 3175 3176 while ((id = queue_remove(id_queue))) { 3177 if (set_roles(&ra->roles, id)) { 3178 free(ra); 3179 return -1; 3180 } 3181 } 3182 3183 while ((id = queue_remove(id_queue))) { 3184 if (set_roles(&ra->new_roles, id)) { 3185 free(ra); 3186 return -1; 3187 } 3188 } 3189 3190 append_role_allow(ra); 3191 return 0; 3192 } 3193 3194 avrule_t *define_cond_filename_trans(void) 3195 { 3196 yyerror("type transitions with a filename not allowed inside " 3197 "conditionals\n"); 3198 return COND_ERR; 3199 } 3200 3201 int define_filename_trans(void) 3202 { 3203 char *id, *name = NULL; 3204 type_set_t stypes, ttypes; 3205 ebitmap_t e_stypes, e_ttypes; 3206 ebitmap_t e_tclasses; 3207 ebitmap_node_t *snode, *tnode, *cnode; 3208 filename_trans_t *ft; 3209 filename_trans_rule_t *ftr; 3210 type_datum_t *typdatum; 3211 uint32_t otype; 3212 unsigned int c, s, t; 3213 int add; 3214 3215 if (pass == 1) { 3216 /* stype */ 3217 while ((id = queue_remove(id_queue))) 3218 free(id); 3219 /* ttype */ 3220 while ((id = queue_remove(id_queue))) 3221 free(id); 3222 /* tclass */ 3223 while ((id = queue_remove(id_queue))) 3224 free(id); 3225 /* otype */ 3226 id = queue_remove(id_queue); 3227 free(id); 3228 /* name */ 3229 id = queue_remove(id_queue); 3230 free(id); 3231 return 0; 3232 } 3233 3234 3235 add = 1; 3236 type_set_init(&stypes); 3237 while ((id = queue_remove(id_queue))) { 3238 if (set_types(&stypes, id, &add, 0)) 3239 goto bad; 3240 } 3241 3242 add =1; 3243 type_set_init(&ttypes); 3244 while ((id = queue_remove(id_queue))) { 3245 if (set_types(&ttypes, id, &add, 0)) 3246 goto bad; 3247 } 3248 3249 ebitmap_init(&e_tclasses); 3250 if (read_classes(&e_tclasses)) 3251 goto bad; 3252 3253 id = (char *)queue_remove(id_queue); 3254 if (!id) { 3255 yyerror("no otype in transition definition?"); 3256 goto bad; 3257 } 3258 if (!is_id_in_scope(SYM_TYPES, id)) { 3259 yyerror2("type %s is not within scope", id); 3260 free(id); 3261 goto bad; 3262 } 3263 typdatum = hashtab_search(policydbp->p_types.table, id); 3264 if (!typdatum) { 3265 yyerror2("unknown type %s used in transition definition", id); 3266 goto bad; 3267 } 3268 free(id); 3269 otype = typdatum->s.value; 3270 3271 name = queue_remove(id_queue); 3272 if (!name) { 3273 yyerror("no pathname specified in filename_trans definition?"); 3274 goto bad; 3275 } 3276 3277 /* We expand the class set into seperate rules. We expand the types 3278 * just to make sure there are not duplicates. They will get turned 3279 * into seperate rules later */ 3280 ebitmap_init(&e_stypes); 3281 if (type_set_expand(&stypes, &e_stypes, policydbp, 1)) 3282 goto bad; 3283 3284 ebitmap_init(&e_ttypes); 3285 if (type_set_expand(&ttypes, &e_ttypes, policydbp, 1)) 3286 goto bad; 3287 3288 ebitmap_for_each_bit(&e_tclasses, cnode, c) { 3289 if (!ebitmap_node_get_bit(cnode, c)) 3290 continue; 3291 ebitmap_for_each_bit(&e_stypes, snode, s) { 3292 if (!ebitmap_node_get_bit(snode, s)) 3293 continue; 3294 ebitmap_for_each_bit(&e_ttypes, tnode, t) { 3295 if (!ebitmap_node_get_bit(tnode, t)) 3296 continue; 3297 3298 for (ft = policydbp->filename_trans; ft; ft = ft->next) { 3299 if (ft->stype == (s + 1) && 3300 ft->ttype == (t + 1) && 3301 ft->tclass == (c + 1) && 3302 !strcmp(ft->name, name)) { 3303 yyerror2("duplicate filename transition for: filename_trans %s %s %s:%s", 3304 name, 3305 policydbp->p_type_val_to_name[s], 3306 policydbp->p_type_val_to_name[t], 3307 policydbp->p_class_val_to_name[c]); 3308 goto bad; 3309 } 3310 } 3311 3312 ft = malloc(sizeof(*ft)); 3313 if (!ft) { 3314 yyerror("out of memory"); 3315 goto bad; 3316 } 3317 memset(ft, 0, sizeof(*ft)); 3318 3319 ft->next = policydbp->filename_trans; 3320 policydbp->filename_trans = ft; 3321 3322 ft->name = strdup(name); 3323 if (!ft->name) { 3324 yyerror("out of memory"); 3325 goto bad; 3326 } 3327 ft->stype = s + 1; 3328 ft->ttype = t + 1; 3329 ft->tclass = c + 1; 3330 ft->otype = otype; 3331 } 3332 } 3333 3334 /* Now add the real rule since we didn't find any duplicates */ 3335 ftr = malloc(sizeof(*ftr)); 3336 if (!ftr) { 3337 yyerror("out of memory"); 3338 goto bad; 3339 } 3340 filename_trans_rule_init(ftr); 3341 append_filename_trans(ftr); 3342 3343 ftr->name = strdup(name); 3344 if (type_set_cpy(&ftr->stypes, &stypes)) { 3345 yyerror("out of memory"); 3346 goto bad; 3347 } 3348 if (type_set_cpy(&ftr->ttypes, &ttypes)) { 3349 yyerror("out of memory"); 3350 goto bad; 3351 } 3352 ftr->tclass = c + 1; 3353 ftr->otype = otype; 3354 } 3355 3356 free(name); 3357 ebitmap_destroy(&e_stypes); 3358 ebitmap_destroy(&e_ttypes); 3359 ebitmap_destroy(&e_tclasses); 3360 3361 return 0; 3362 3363 bad: 3364 free(name); 3365 return -1; 3366 } 3367 3368 static constraint_expr_t *constraint_expr_clone(constraint_expr_t * expr) 3369 { 3370 constraint_expr_t *h = NULL, *l = NULL, *e, *newe; 3371 for (e = expr; e; e = e->next) { 3372 newe = malloc(sizeof(*newe)); 3373 if (!newe) 3374 goto oom; 3375 if (constraint_expr_init(newe) == -1) { 3376 free(newe); 3377 goto oom; 3378 } 3379 if (l) 3380 l->next = newe; 3381 else 3382 h = newe; 3383 l = newe; 3384 newe->expr_type = e->expr_type; 3385 newe->attr = e->attr; 3386 newe->op = e->op; 3387 if (newe->expr_type == CEXPR_NAMES) { 3388 if (newe->attr & CEXPR_TYPE) { 3389 if (type_set_cpy 3390 (newe->type_names, e->type_names)) 3391 goto oom; 3392 } else { 3393 if (ebitmap_cpy(&newe->names, &e->names)) 3394 goto oom; 3395 } 3396 } 3397 } 3398 3399 return h; 3400 oom: 3401 e = h; 3402 while (e) { 3403 l = e; 3404 e = e->next; 3405 constraint_expr_destroy(l); 3406 } 3407 return NULL; 3408 } 3409 3410 int define_constraint(constraint_expr_t * expr) 3411 { 3412 struct constraint_node *node; 3413 char *id; 3414 class_datum_t *cladatum; 3415 perm_datum_t *perdatum; 3416 ebitmap_t classmap; 3417 ebitmap_node_t *enode; 3418 constraint_expr_t *e; 3419 unsigned int i; 3420 int depth; 3421 unsigned char useexpr = 1; 3422 3423 if (pass == 1) { 3424 while ((id = queue_remove(id_queue))) 3425 free(id); 3426 while ((id = queue_remove(id_queue))) 3427 free(id); 3428 return 0; 3429 } 3430 3431 depth = -1; 3432 for (e = expr; e; e = e->next) { 3433 switch (e->expr_type) { 3434 case CEXPR_NOT: 3435 if (depth < 0) { 3436 yyerror("illegal constraint expression"); 3437 return -1; 3438 } 3439 break; 3440 case CEXPR_AND: 3441 case CEXPR_OR: 3442 if (depth < 1) { 3443 yyerror("illegal constraint expression"); 3444 return -1; 3445 } 3446 depth--; 3447 break; 3448 case CEXPR_ATTR: 3449 case CEXPR_NAMES: 3450 if (e->attr & CEXPR_XTARGET) { 3451 yyerror("illegal constraint expression"); 3452 return -1; /* only for validatetrans rules */ 3453 } 3454 if (depth == (CEXPR_MAXDEPTH - 1)) { 3455 yyerror("constraint expression is too deep"); 3456 return -1; 3457 } 3458 depth++; 3459 break; 3460 default: 3461 yyerror("illegal constraint expression"); 3462 return -1; 3463 } 3464 } 3465 if (depth != 0) { 3466 yyerror("illegal constraint expression"); 3467 return -1; 3468 } 3469 3470 ebitmap_init(&classmap); 3471 while ((id = queue_remove(id_queue))) { 3472 if (!is_id_in_scope(SYM_CLASSES, id)) { 3473 yyerror2("class %s is not within scope", id); 3474 free(id); 3475 return -1; 3476 } 3477 cladatum = 3478 (class_datum_t *) hashtab_search(policydbp->p_classes.table, 3479 (hashtab_key_t) id); 3480 if (!cladatum) { 3481 yyerror2("class %s is not defined", id); 3482 ebitmap_destroy(&classmap); 3483 free(id); 3484 return -1; 3485 } 3486 if (ebitmap_set_bit(&classmap, cladatum->s.value - 1, TRUE)) { 3487 yyerror("out of memory"); 3488 ebitmap_destroy(&classmap); 3489 free(id); 3490 return -1; 3491 } 3492 node = malloc(sizeof(struct constraint_node)); 3493 if (!node) { 3494 yyerror("out of memory"); 3495 free(node); 3496 return -1; 3497 } 3498 memset(node, 0, sizeof(constraint_node_t)); 3499 if (useexpr) { 3500 node->expr = expr; 3501 useexpr = 0; 3502 } else { 3503 node->expr = constraint_expr_clone(expr); 3504 } 3505 if (!node->expr) { 3506 yyerror("out of memory"); 3507 free(node); 3508 return -1; 3509 } 3510 node->permissions = 0; 3511 3512 node->next = cladatum->constraints; 3513 cladatum->constraints = node; 3514 3515 free(id); 3516 } 3517 3518 while ((id = queue_remove(id_queue))) { 3519 ebitmap_for_each_bit(&classmap, enode, i) { 3520 if (ebitmap_node_get_bit(enode, i)) { 3521 cladatum = policydbp->class_val_to_struct[i]; 3522 node = cladatum->constraints; 3523 3524 perdatum = 3525 (perm_datum_t *) hashtab_search(cladatum-> 3526 permissions. 3527 table, 3528 (hashtab_key_t) 3529 id); 3530 if (!perdatum) { 3531 if (cladatum->comdatum) { 3532 perdatum = 3533 (perm_datum_t *) 3534 hashtab_search(cladatum-> 3535 comdatum-> 3536 permissions. 3537 table, 3538 (hashtab_key_t) 3539 id); 3540 } 3541 if (!perdatum) { 3542 yyerror2("permission %s is not" 3543 " defined", id); 3544 free(id); 3545 ebitmap_destroy(&classmap); 3546 return -1; 3547 } 3548 } 3549 node->permissions |= 3550 (1 << (perdatum->s.value - 1)); 3551 } 3552 } 3553 free(id); 3554 } 3555 3556 ebitmap_destroy(&classmap); 3557 3558 return 0; 3559 } 3560 3561 int define_validatetrans(constraint_expr_t * expr) 3562 { 3563 struct constraint_node *node; 3564 char *id; 3565 class_datum_t *cladatum; 3566 ebitmap_t classmap; 3567 constraint_expr_t *e; 3568 int depth; 3569 unsigned char useexpr = 1; 3570 3571 if (pass == 1) { 3572 while ((id = queue_remove(id_queue))) 3573 free(id); 3574 return 0; 3575 } 3576 3577 depth = -1; 3578 for (e = expr; e; e = e->next) { 3579 switch (e->expr_type) { 3580 case CEXPR_NOT: 3581 if (depth < 0) { 3582 yyerror("illegal validatetrans expression"); 3583 return -1; 3584 } 3585 break; 3586 case CEXPR_AND: 3587 case CEXPR_OR: 3588 if (depth < 1) { 3589 yyerror("illegal validatetrans expression"); 3590 return -1; 3591 } 3592 depth--; 3593 break; 3594 case CEXPR_ATTR: 3595 case CEXPR_NAMES: 3596 if (depth == (CEXPR_MAXDEPTH - 1)) { 3597 yyerror("validatetrans expression is too deep"); 3598 return -1; 3599 } 3600 depth++; 3601 break; 3602 default: 3603 yyerror("illegal validatetrans expression"); 3604 return -1; 3605 } 3606 } 3607 if (depth != 0) { 3608 yyerror("illegal validatetrans expression"); 3609 return -1; 3610 } 3611 3612 ebitmap_init(&classmap); 3613 while ((id = queue_remove(id_queue))) { 3614 if (!is_id_in_scope(SYM_CLASSES, id)) { 3615 yyerror2("class %s is not within scope", id); 3616 free(id); 3617 return -1; 3618 } 3619 cladatum = 3620 (class_datum_t *) hashtab_search(policydbp->p_classes.table, 3621 (hashtab_key_t) id); 3622 if (!cladatum) { 3623 yyerror2("class %s is not defined", id); 3624 ebitmap_destroy(&classmap); 3625 free(id); 3626 return -1; 3627 } 3628 if (ebitmap_set_bit(&classmap, (cladatum->s.value - 1), TRUE)) { 3629 yyerror("out of memory"); 3630 ebitmap_destroy(&classmap); 3631 free(id); 3632 return -1; 3633 } 3634 3635 node = malloc(sizeof(struct constraint_node)); 3636 if (!node) { 3637 yyerror("out of memory"); 3638 return -1; 3639 } 3640 memset(node, 0, sizeof(constraint_node_t)); 3641 if (useexpr) { 3642 node->expr = expr; 3643 useexpr = 0; 3644 } else { 3645 node->expr = constraint_expr_clone(expr); 3646 } 3647 node->permissions = 0; 3648 3649 node->next = cladatum->validatetrans; 3650 cladatum->validatetrans = node; 3651 3652 free(id); 3653 } 3654 3655 ebitmap_destroy(&classmap); 3656 3657 return 0; 3658 } 3659 3660 uintptr_t define_cexpr(uint32_t expr_type, uintptr_t arg1, uintptr_t arg2) 3661 { 3662 struct constraint_expr *expr, *e1 = NULL, *e2; 3663 user_datum_t *user; 3664 role_datum_t *role; 3665 ebitmap_t negset; 3666 char *id; 3667 uint32_t val; 3668 int add = 1; 3669 3670 if (pass == 1) { 3671 if (expr_type == CEXPR_NAMES) { 3672 while ((id = queue_remove(id_queue))) 3673 free(id); 3674 } 3675 return 1; /* any non-NULL value */ 3676 } 3677 3678 if ((expr = malloc(sizeof(*expr))) == NULL || 3679 constraint_expr_init(expr) == -1) { 3680 yyerror("out of memory"); 3681 free(expr); 3682 return 0; 3683 } 3684 expr->expr_type = expr_type; 3685 3686 switch (expr_type) { 3687 case CEXPR_NOT: 3688 e1 = NULL; 3689 e2 = (struct constraint_expr *)arg1; 3690 while (e2) { 3691 e1 = e2; 3692 e2 = e2->next; 3693 } 3694 if (!e1 || e1->next) { 3695 yyerror("illegal constraint expression"); 3696 constraint_expr_destroy(expr); 3697 return 0; 3698 } 3699 e1->next = expr; 3700 return arg1; 3701 case CEXPR_AND: 3702 case CEXPR_OR: 3703 e1 = NULL; 3704 e2 = (struct constraint_expr *)arg1; 3705 while (e2) { 3706 e1 = e2; 3707 e2 = e2->next; 3708 } 3709 if (!e1 || e1->next) { 3710 yyerror("illegal constraint expression"); 3711 constraint_expr_destroy(expr); 3712 return 0; 3713 } 3714 e1->next = (struct constraint_expr *)arg2; 3715 3716 e1 = NULL; 3717 e2 = (struct constraint_expr *)arg2; 3718 while (e2) { 3719 e1 = e2; 3720 e2 = e2->next; 3721 } 3722 if (!e1 || e1->next) { 3723 yyerror("illegal constraint expression"); 3724 constraint_expr_destroy(expr); 3725 return 0; 3726 } 3727 e1->next = expr; 3728 return arg1; 3729 case CEXPR_ATTR: 3730 expr->attr = arg1; 3731 expr->op = arg2; 3732 return (uintptr_t) expr; 3733 case CEXPR_NAMES: 3734 add = 1; 3735 expr->attr = arg1; 3736 expr->op = arg2; 3737 ebitmap_init(&negset); 3738 while ((id = (char *)queue_remove(id_queue))) { 3739 if (expr->attr & CEXPR_USER) { 3740 if (!is_id_in_scope(SYM_USERS, id)) { 3741 yyerror2("user %s is not within scope", 3742 id); 3743 constraint_expr_destroy(expr); 3744 return 0; 3745 } 3746 user = 3747 (user_datum_t *) hashtab_search(policydbp-> 3748 p_users. 3749 table, 3750 (hashtab_key_t) 3751 id); 3752 if (!user) { 3753 yyerror2("unknown user %s", id); 3754 constraint_expr_destroy(expr); 3755 return 0; 3756 } 3757 val = user->s.value; 3758 } else if (expr->attr & CEXPR_ROLE) { 3759 if (!is_id_in_scope(SYM_ROLES, id)) { 3760 yyerror2("role %s is not within scope", 3761 id); 3762 constraint_expr_destroy(expr); 3763 return 0; 3764 } 3765 role = 3766 (role_datum_t *) hashtab_search(policydbp-> 3767 p_roles. 3768 table, 3769 (hashtab_key_t) 3770 id); 3771 if (!role) { 3772 yyerror2("unknown role %s", id); 3773 constraint_expr_destroy(expr); 3774 return 0; 3775 } 3776 val = role->s.value; 3777 } else if (expr->attr & CEXPR_TYPE) { 3778 if (set_types(expr->type_names, id, &add, 0)) { 3779 constraint_expr_destroy(expr); 3780 return 0; 3781 } 3782 continue; 3783 } else { 3784 yyerror("invalid constraint expression"); 3785 constraint_expr_destroy(expr); 3786 return 0; 3787 } 3788 if (ebitmap_set_bit(&expr->names, val - 1, TRUE)) { 3789 yyerror("out of memory"); 3790 ebitmap_destroy(&expr->names); 3791 constraint_expr_destroy(expr); 3792 return 0; 3793 } 3794 free(id); 3795 } 3796 ebitmap_destroy(&negset); 3797 return (uintptr_t) expr; 3798 default: 3799 break; 3800 } 3801 3802 yyerror("invalid constraint expression"); 3803 constraint_expr_destroy(expr); 3804 return 0; 3805 } 3806 3807 int define_conditional(cond_expr_t * expr, avrule_t * t, avrule_t * f) 3808 { 3809 cond_expr_t *e; 3810 int depth; 3811 cond_node_t cn, *cn_old; 3812 3813 /* expression cannot be NULL */ 3814 if (!expr) { 3815 yyerror("illegal conditional expression"); 3816 return -1; 3817 } 3818 if (!t) { 3819 if (!f) { 3820 /* empty is fine, destroy expression and return */ 3821 cond_expr_destroy(expr); 3822 return 0; 3823 } 3824 /* Invert */ 3825 t = f; 3826 f = 0; 3827 expr = define_cond_expr(COND_NOT, expr, 0); 3828 if (!expr) { 3829 yyerror("unable to invert"); 3830 return -1; 3831 } 3832 } 3833 3834 /* verify expression */ 3835 depth = -1; 3836 for (e = expr; e; e = e->next) { 3837 switch (e->expr_type) { 3838 case COND_NOT: 3839 if (depth < 0) { 3840 yyerror 3841 ("illegal conditional expression; Bad NOT"); 3842 return -1; 3843 } 3844 break; 3845 case COND_AND: 3846 case COND_OR: 3847 case COND_XOR: 3848 case COND_EQ: 3849 case COND_NEQ: 3850 if (depth < 1) { 3851 yyerror 3852 ("illegal conditional expression; Bad binary op"); 3853 return -1; 3854 } 3855 depth--; 3856 break; 3857 case COND_BOOL: 3858 if (depth == (COND_EXPR_MAXDEPTH - 1)) { 3859 yyerror 3860 ("conditional expression is like totally too deep"); 3861 return -1; 3862 } 3863 depth++; 3864 break; 3865 default: 3866 yyerror("illegal conditional expression"); 3867 return -1; 3868 } 3869 } 3870 if (depth != 0) { 3871 yyerror("illegal conditional expression"); 3872 return -1; 3873 } 3874 3875 /* use tmp conditional node to partially build new node */ 3876 memset(&cn, 0, sizeof(cn)); 3877 cn.expr = expr; 3878 cn.avtrue_list = t; 3879 cn.avfalse_list = f; 3880 3881 /* normalize/precompute expression */ 3882 if (cond_normalize_expr(policydbp, &cn) < 0) { 3883 yyerror("problem normalizing conditional expression"); 3884 return -1; 3885 } 3886 3887 /* get the existing conditional node, or create a new one */ 3888 cn_old = get_current_cond_list(&cn); 3889 if (!cn_old) { 3890 return -1; 3891 } 3892 3893 append_cond_list(&cn); 3894 3895 /* note that there is no check here for duplicate rules, nor 3896 * check that rule already exists in base -- that will be 3897 * handled during conditional expansion, in expand.c */ 3898 3899 cn.avtrue_list = NULL; 3900 cn.avfalse_list = NULL; 3901 cond_node_destroy(&cn); 3902 3903 return 0; 3904 } 3905 3906 cond_expr_t *define_cond_expr(uint32_t expr_type, void *arg1, void *arg2) 3907 { 3908 struct cond_expr *expr, *e1 = NULL, *e2; 3909 cond_bool_datum_t *bool_var; 3910 char *id; 3911 3912 /* expressions are handled in the second pass */ 3913 if (pass == 1) { 3914 if (expr_type == COND_BOOL) { 3915 while ((id = queue_remove(id_queue))) { 3916 free(id); 3917 } 3918 } 3919 return (cond_expr_t *) 1; /* any non-NULL value */ 3920 } 3921 3922 /* create a new expression struct */ 3923 expr = malloc(sizeof(struct cond_expr)); 3924 if (!expr) { 3925 yyerror("out of memory"); 3926 return NULL; 3927 } 3928 memset(expr, 0, sizeof(cond_expr_t)); 3929 expr->expr_type = expr_type; 3930 3931 /* create the type asked for */ 3932 switch (expr_type) { 3933 case COND_NOT: 3934 e1 = NULL; 3935 e2 = (struct cond_expr *)arg1; 3936 while (e2) { 3937 e1 = e2; 3938 e2 = e2->next; 3939 } 3940 if (!e1 || e1->next) { 3941 yyerror("illegal conditional NOT expression"); 3942 free(expr); 3943 return NULL; 3944 } 3945 e1->next = expr; 3946 return (struct cond_expr *)arg1; 3947 case COND_AND: 3948 case COND_OR: 3949 case COND_XOR: 3950 case COND_EQ: 3951 case COND_NEQ: 3952 e1 = NULL; 3953 e2 = (struct cond_expr *)arg1; 3954 while (e2) { 3955 e1 = e2; 3956 e2 = e2->next; 3957 } 3958 if (!e1 || e1->next) { 3959 yyerror 3960 ("illegal left side of conditional binary op expression"); 3961 free(expr); 3962 return NULL; 3963 } 3964 e1->next = (struct cond_expr *)arg2; 3965 3966 e1 = NULL; 3967 e2 = (struct cond_expr *)arg2; 3968 while (e2) { 3969 e1 = e2; 3970 e2 = e2->next; 3971 } 3972 if (!e1 || e1->next) { 3973 yyerror 3974 ("illegal right side of conditional binary op expression"); 3975 free(expr); 3976 return NULL; 3977 } 3978 e1->next = expr; 3979 return (struct cond_expr *)arg1; 3980 case COND_BOOL: 3981 id = (char *)queue_remove(id_queue); 3982 if (!id) { 3983 yyerror("bad conditional; expected boolean id"); 3984 free(id); 3985 free(expr); 3986 return NULL; 3987 } 3988 if (!is_id_in_scope(SYM_BOOLS, id)) { 3989 yyerror2("boolean %s is not within scope", id); 3990 free(id); 3991 free(expr); 3992 return NULL; 3993 } 3994 bool_var = 3995 (cond_bool_datum_t *) hashtab_search(policydbp->p_bools. 3996 table, 3997 (hashtab_key_t) id); 3998 if (!bool_var) { 3999 yyerror2("unknown boolean %s in conditional expression", 4000 id); 4001 free(expr); 4002 free(id); 4003 return NULL; 4004 } 4005 expr->bool = bool_var->s.value; 4006 free(id); 4007 return expr; 4008 default: 4009 yyerror("illegal conditional expression"); 4010 free(expr); 4011 return NULL; 4012 } 4013 } 4014 4015 static int set_user_roles(role_set_t * set, char *id) 4016 { 4017 role_datum_t *r; 4018 unsigned int i; 4019 ebitmap_node_t *node; 4020 4021 if (strcmp(id, "*") == 0) { 4022 free(id); 4023 yyerror("* is not allowed in user declarations"); 4024 return -1; 4025 } 4026 4027 if (strcmp(id, "~") == 0) { 4028 free(id); 4029 yyerror("~ is not allowed in user declarations"); 4030 return -1; 4031 } 4032 4033 if (!is_id_in_scope(SYM_ROLES, id)) { 4034 yyerror2("role %s is not within scope", id); 4035 free(id); 4036 return -1; 4037 } 4038 r = hashtab_search(policydbp->p_roles.table, id); 4039 if (!r) { 4040 yyerror2("unknown role %s", id); 4041 free(id); 4042 return -1; 4043 } 4044 4045 /* set the role and every role it dominates */ 4046 ebitmap_for_each_bit(&r->dominates, node, i) { 4047 if (ebitmap_node_get_bit(node, i)) 4048 if (ebitmap_set_bit(&set->roles, i, TRUE)) 4049 goto oom; 4050 } 4051 free(id); 4052 return 0; 4053 oom: 4054 yyerror("out of memory"); 4055 return -1; 4056 } 4057 4058 static int parse_categories(char *id, level_datum_t * levdatum, ebitmap_t * cats) 4059 { 4060 cat_datum_t *cdatum; 4061 int range_start, range_end, i; 4062 4063 if (id_has_dot(id)) { 4064 char *id_start = id; 4065 char *id_end = strchr(id, '.'); 4066 4067 *(id_end++) = '\0'; 4068 4069 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 4070 (hashtab_key_t) 4071 id_start); 4072 if (!cdatum) { 4073 yyerror2("unknown category %s", id_start); 4074 return -1; 4075 } 4076 range_start = cdatum->s.value - 1; 4077 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 4078 (hashtab_key_t) id_end); 4079 if (!cdatum) { 4080 yyerror2("unknown category %s", id_end); 4081 return -1; 4082 } 4083 range_end = cdatum->s.value - 1; 4084 4085 if (range_end < range_start) { 4086 yyerror2("category range is invalid"); 4087 return -1; 4088 } 4089 } else { 4090 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 4091 (hashtab_key_t) id); 4092 if (!cdatum) { 4093 yyerror2("unknown category %s", id); 4094 return -1; 4095 } 4096 range_start = range_end = cdatum->s.value - 1; 4097 } 4098 4099 for (i = range_start; i <= range_end; i++) { 4100 if (!ebitmap_get_bit(&levdatum->level->cat, i)) { 4101 uint32_t level_value = levdatum->level->sens - 1; 4102 policydb_index_others(NULL, policydbp, 0); 4103 yyerror2("category %s can not be associated " 4104 "with level %s", 4105 policydbp->p_cat_val_to_name[i], 4106 policydbp->p_sens_val_to_name[level_value]); 4107 return -1; 4108 } 4109 if (ebitmap_set_bit(cats, i, TRUE)) { 4110 yyerror("out of memory"); 4111 return -1; 4112 } 4113 } 4114 4115 return 0; 4116 } 4117 4118 static int parse_semantic_categories(char *id, level_datum_t * levdatum __attribute__ ((unused)), 4119 mls_semantic_cat_t ** cats) 4120 { 4121 cat_datum_t *cdatum; 4122 mls_semantic_cat_t *newcat; 4123 unsigned int range_start, range_end; 4124 4125 if (id_has_dot(id)) { 4126 char *id_start = id; 4127 char *id_end = strchr(id, '.'); 4128 4129 *(id_end++) = '\0'; 4130 4131 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 4132 (hashtab_key_t) 4133 id_start); 4134 if (!cdatum) { 4135 yyerror2("unknown category %s", id_start); 4136 return -1; 4137 } 4138 range_start = cdatum->s.value; 4139 4140 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 4141 (hashtab_key_t) id_end); 4142 if (!cdatum) { 4143 yyerror2("unknown category %s", id_end); 4144 return -1; 4145 } 4146 range_end = cdatum->s.value; 4147 } else { 4148 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 4149 (hashtab_key_t) id); 4150 if (!cdatum) { 4151 yyerror2("unknown category %s", id); 4152 return -1; 4153 } 4154 range_start = range_end = cdatum->s.value; 4155 } 4156 4157 newcat = (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t)); 4158 if (!newcat) { 4159 yyerror("out of memory"); 4160 return -1; 4161 } 4162 4163 mls_semantic_cat_init(newcat); 4164 newcat->next = *cats; 4165 newcat->low = range_start; 4166 newcat->high = range_end; 4167 4168 *cats = newcat; 4169 4170 return 0; 4171 } 4172 4173 int define_user(void) 4174 { 4175 char *id; 4176 user_datum_t *usrdatum; 4177 level_datum_t *levdatum; 4178 int l; 4179 4180 if (pass == 1) { 4181 while ((id = queue_remove(id_queue))) 4182 free(id); 4183 if (mlspol) { 4184 while ((id = queue_remove(id_queue))) 4185 free(id); 4186 id = queue_remove(id_queue); 4187 free(id); 4188 for (l = 0; l < 2; l++) { 4189 while ((id = queue_remove(id_queue))) { 4190 free(id); 4191 } 4192 id = queue_remove(id_queue); 4193 if (!id) 4194 break; 4195 free(id); 4196 } 4197 } 4198 return 0; 4199 } 4200 4201 if ((usrdatum = declare_user()) == NULL) { 4202 return -1; 4203 } 4204 4205 while ((id = queue_remove(id_queue))) { 4206 if (set_user_roles(&usrdatum->roles, id)) 4207 continue; 4208 } 4209 4210 if (mlspol) { 4211 id = queue_remove(id_queue); 4212 if (!id) { 4213 yyerror("no default level specified for user"); 4214 return -1; 4215 } 4216 4217 levdatum = (level_datum_t *) 4218 hashtab_search(policydbp->p_levels.table, 4219 (hashtab_key_t) id); 4220 if (!levdatum) { 4221 yyerror2("unknown sensitivity %s used in user" 4222 " level definition", id); 4223 free(id); 4224 return -1; 4225 } 4226 free(id); 4227 4228 usrdatum->dfltlevel.sens = levdatum->level->sens; 4229 4230 while ((id = queue_remove(id_queue))) { 4231 if (parse_semantic_categories(id, levdatum, 4232 &usrdatum->dfltlevel.cat)) { 4233 free(id); 4234 return -1; 4235 } 4236 free(id); 4237 } 4238 4239 id = queue_remove(id_queue); 4240 4241 for (l = 0; l < 2; l++) { 4242 levdatum = (level_datum_t *) 4243 hashtab_search(policydbp->p_levels.table, 4244 (hashtab_key_t) id); 4245 if (!levdatum) { 4246 yyerror2("unknown sensitivity %s used in user" 4247 " range definition", id); 4248 free(id); 4249 return -1; 4250 } 4251 free(id); 4252 4253 usrdatum->range.level[l].sens = levdatum->level->sens; 4254 4255 while ((id = queue_remove(id_queue))) { 4256 if (parse_semantic_categories(id, levdatum, 4257 &usrdatum->range.level[l].cat)) { 4258 free(id); 4259 return -1; 4260 } 4261 free(id); 4262 } 4263 4264 id = queue_remove(id_queue); 4265 if (!id) 4266 break; 4267 } 4268 4269 if (l == 0) { 4270 if (mls_semantic_level_cpy(&usrdatum->range.level[1], 4271 &usrdatum->range.level[0])) { 4272 yyerror("out of memory"); 4273 return -1; 4274 } 4275 } 4276 } 4277 return 0; 4278 } 4279 4280 static int parse_security_context(context_struct_t * c) 4281 { 4282 char *id; 4283 role_datum_t *role; 4284 type_datum_t *typdatum; 4285 user_datum_t *usrdatum; 4286 level_datum_t *levdatum; 4287 int l; 4288 4289 if (pass == 1) { 4290 id = queue_remove(id_queue); 4291 free(id); /* user */ 4292 id = queue_remove(id_queue); 4293 free(id); /* role */ 4294 id = queue_remove(id_queue); 4295 free(id); /* type */ 4296 if (mlspol) { 4297 id = queue_remove(id_queue); 4298 free(id); 4299 for (l = 0; l < 2; l++) { 4300 while ((id = queue_remove(id_queue))) { 4301 free(id); 4302 } 4303 id = queue_remove(id_queue); 4304 if (!id) 4305 break; 4306 free(id); 4307 } 4308 } 4309 return 0; 4310 } 4311 4312 /* check context c to make sure ok to dereference c later */ 4313 if (c == NULL) { 4314 yyerror("null context pointer!"); 4315 return -1; 4316 } 4317 4318 context_init(c); 4319 4320 /* extract the user */ 4321 id = queue_remove(id_queue); 4322 if (!id) { 4323 yyerror("no effective user?"); 4324 goto bad; 4325 } 4326 if (!is_id_in_scope(SYM_USERS, id)) { 4327 yyerror2("user %s is not within scope", id); 4328 free(id); 4329 goto bad; 4330 } 4331 usrdatum = (user_datum_t *) hashtab_search(policydbp->p_users.table, 4332 (hashtab_key_t) id); 4333 if (!usrdatum) { 4334 yyerror2("user %s is not defined", id); 4335 free(id); 4336 goto bad; 4337 } 4338 c->user = usrdatum->s.value; 4339 4340 /* no need to keep the user name */ 4341 free(id); 4342 4343 /* extract the role */ 4344 id = (char *)queue_remove(id_queue); 4345 if (!id) { 4346 yyerror("no role name for sid context definition?"); 4347 return -1; 4348 } 4349 if (!is_id_in_scope(SYM_ROLES, id)) { 4350 yyerror2("role %s is not within scope", id); 4351 free(id); 4352 return -1; 4353 } 4354 role = (role_datum_t *) hashtab_search(policydbp->p_roles.table, 4355 (hashtab_key_t) id); 4356 if (!role) { 4357 yyerror2("role %s is not defined", id); 4358 free(id); 4359 return -1; 4360 } 4361 c->role = role->s.value; 4362 4363 /* no need to keep the role name */ 4364 free(id); 4365 4366 /* extract the type */ 4367 id = (char *)queue_remove(id_queue); 4368 if (!id) { 4369 yyerror("no type name for sid context definition?"); 4370 return -1; 4371 } 4372 if (!is_id_in_scope(SYM_TYPES, id)) { 4373 yyerror2("type %s is not within scope", id); 4374 free(id); 4375 return -1; 4376 } 4377 typdatum = (type_datum_t *) hashtab_search(policydbp->p_types.table, 4378 (hashtab_key_t) id); 4379 if (!typdatum || typdatum->flavor == TYPE_ATTRIB) { 4380 yyerror2("type %s is not defined or is an attribute", id); 4381 free(id); 4382 return -1; 4383 } 4384 c->type = typdatum->s.value; 4385 4386 /* no need to keep the type name */ 4387 free(id); 4388 4389 if (mlspol) { 4390 /* extract the low sensitivity */ 4391 id = (char *)queue_head(id_queue); 4392 if (!id) { 4393 yyerror("no sensitivity name for sid context" 4394 " definition?"); 4395 return -1; 4396 } 4397 4398 id = (char *)queue_remove(id_queue); 4399 for (l = 0; l < 2; l++) { 4400 levdatum = (level_datum_t *) 4401 hashtab_search(policydbp->p_levels.table, 4402 (hashtab_key_t) id); 4403 if (!levdatum) { 4404 yyerror2("Sensitivity %s is not defined", id); 4405 free(id); 4406 return -1; 4407 } 4408 free(id); 4409 c->range.level[l].sens = levdatum->level->sens; 4410 4411 /* extract low category set */ 4412 while ((id = queue_remove(id_queue))) { 4413 if (parse_categories(id, levdatum, 4414 &c->range.level[l].cat)) { 4415 free(id); 4416 return -1; 4417 } 4418 free(id); 4419 } 4420 4421 /* extract high sensitivity */ 4422 id = (char *)queue_remove(id_queue); 4423 if (!id) 4424 break; 4425 } 4426 4427 if (l == 0) { 4428 c->range.level[1].sens = c->range.level[0].sens; 4429 if (ebitmap_cpy(&c->range.level[1].cat, 4430 &c->range.level[0].cat)) { 4431 4432 yyerror("out of memory"); 4433 goto bad; 4434 } 4435 } 4436 } 4437 4438 if (!policydb_context_isvalid(policydbp, c)) { 4439 yyerror("invalid security context"); 4440 goto bad; 4441 } 4442 return 0; 4443 4444 bad: 4445 context_destroy(c); 4446 4447 return -1; 4448 } 4449 4450 int define_initial_sid_context(void) 4451 { 4452 char *id; 4453 ocontext_t *c, *head; 4454 4455 if (pass == 1) { 4456 id = (char *)queue_remove(id_queue); 4457 free(id); 4458 parse_security_context(NULL); 4459 return 0; 4460 } 4461 4462 id = (char *)queue_remove(id_queue); 4463 if (!id) { 4464 yyerror("no sid name for SID context definition?"); 4465 return -1; 4466 } 4467 head = policydbp->ocontexts[OCON_ISID]; 4468 for (c = head; c; c = c->next) { 4469 if (!strcmp(id, c->u.name)) 4470 break; 4471 } 4472 4473 if (!c) { 4474 yyerror2("SID %s is not defined", id); 4475 free(id); 4476 return -1; 4477 } 4478 if (c->context[0].user) { 4479 yyerror2("The context for SID %s is multiply defined", id); 4480 free(id); 4481 return -1; 4482 } 4483 /* no need to keep the sid name */ 4484 free(id); 4485 4486 if (parse_security_context(&c->context[0])) 4487 return -1; 4488 4489 return 0; 4490 } 4491 4492 int define_fs_context(unsigned int major, unsigned int minor) 4493 { 4494 ocontext_t *newc, *c, *head; 4495 4496 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 4497 yyerror("fscon not supported for target"); 4498 return -1; 4499 } 4500 4501 if (pass == 1) { 4502 parse_security_context(NULL); 4503 parse_security_context(NULL); 4504 return 0; 4505 } 4506 4507 newc = (ocontext_t *) malloc(sizeof(ocontext_t)); 4508 if (!newc) { 4509 yyerror("out of memory"); 4510 return -1; 4511 } 4512 memset(newc, 0, sizeof(ocontext_t)); 4513 4514 newc->u.name = (char *)malloc(6); 4515 if (!newc->u.name) { 4516 yyerror("out of memory"); 4517 free(newc); 4518 return -1; 4519 } 4520 sprintf(newc->u.name, "%02x:%02x", major, minor); 4521 4522 if (parse_security_context(&newc->context[0])) { 4523 free(newc->u.name); 4524 free(newc); 4525 return -1; 4526 } 4527 if (parse_security_context(&newc->context[1])) { 4528 context_destroy(&newc->context[0]); 4529 free(newc->u.name); 4530 free(newc); 4531 return -1; 4532 } 4533 head = policydbp->ocontexts[OCON_FS]; 4534 4535 for (c = head; c; c = c->next) { 4536 if (!strcmp(newc->u.name, c->u.name)) { 4537 yyerror2("duplicate entry for file system %s", 4538 newc->u.name); 4539 context_destroy(&newc->context[0]); 4540 context_destroy(&newc->context[1]); 4541 free(newc->u.name); 4542 free(newc); 4543 return -1; 4544 } 4545 } 4546 4547 newc->next = head; 4548 policydbp->ocontexts[OCON_FS] = newc; 4549 4550 return 0; 4551 } 4552 4553 int define_pirq_context(unsigned int pirq) 4554 { 4555 ocontext_t *newc, *c, *l, *head; 4556 char *id; 4557 4558 if (policydbp->target_platform != SEPOL_TARGET_XEN) { 4559 yyerror("pirqcon not supported for target"); 4560 return -1; 4561 } 4562 4563 if (pass == 1) { 4564 id = (char *) queue_remove(id_queue); 4565 free(id); 4566 parse_security_context(NULL); 4567 return 0; 4568 } 4569 4570 newc = malloc(sizeof(ocontext_t)); 4571 if (!newc) { 4572 yyerror("out of memory"); 4573 return -1; 4574 } 4575 memset(newc, 0, sizeof(ocontext_t)); 4576 4577 newc->u.pirq = pirq; 4578 4579 if (parse_security_context(&newc->context[0])) { 4580 free(newc); 4581 return -1; 4582 } 4583 4584 head = policydbp->ocontexts[OCON_XEN_PIRQ]; 4585 for (l = NULL, c = head; c; l = c, c = c->next) { 4586 unsigned int pirq2; 4587 4588 pirq2 = c->u.pirq; 4589 if (pirq == pirq2) { 4590 yyerror2("duplicate pirqcon entry for %d ", pirq); 4591 goto bad; 4592 } 4593 } 4594 4595 if (l) 4596 l->next = newc; 4597 else 4598 policydbp->ocontexts[OCON_XEN_PIRQ] = newc; 4599 4600 return 0; 4601 4602 bad: 4603 free(newc); 4604 return -1; 4605 } 4606 4607 int define_iomem_context(uint64_t low, uint64_t high) 4608 { 4609 ocontext_t *newc, *c, *l, *head; 4610 char *id; 4611 4612 if (policydbp->target_platform != SEPOL_TARGET_XEN) { 4613 yyerror("iomemcon not supported for target"); 4614 return -1; 4615 } 4616 4617 if (pass == 1) { 4618 id = (char *)queue_remove(id_queue); 4619 free(id); 4620 parse_security_context(NULL); 4621 return 0; 4622 } 4623 4624 newc = malloc(sizeof(ocontext_t)); 4625 if (!newc) { 4626 yyerror("out of memory"); 4627 return -1; 4628 } 4629 memset(newc, 0, sizeof(ocontext_t)); 4630 4631 newc->u.iomem.low_iomem = low; 4632 newc->u.iomem.high_iomem = high; 4633 4634 if (low > high) { 4635 yyerror2("low memory 0x%"PRIx64" exceeds high memory 0x%"PRIx64"", low, high); 4636 free(newc); 4637 return -1; 4638 } 4639 4640 if (parse_security_context(&newc->context[0])) { 4641 free(newc); 4642 return -1; 4643 } 4644 4645 head = policydbp->ocontexts[OCON_XEN_IOMEM]; 4646 for (l = NULL, c = head; c; l = c, c = c->next) { 4647 uint64_t low2, high2; 4648 4649 low2 = c->u.iomem.low_iomem; 4650 high2 = c->u.iomem.high_iomem; 4651 if (low <= high2 && low2 <= high) { 4652 yyerror2("iomemcon entry for 0x%"PRIx64"-0x%"PRIx64" overlaps with " 4653 "earlier entry 0x%"PRIx64"-0x%"PRIx64"", low, high, 4654 low2, high2); 4655 goto bad; 4656 } 4657 } 4658 4659 if (l) 4660 l->next = newc; 4661 else 4662 policydbp->ocontexts[OCON_XEN_IOMEM] = newc; 4663 4664 return 0; 4665 4666 bad: 4667 free(newc); 4668 return -1; 4669 } 4670 4671 int define_ioport_context(unsigned long low, unsigned long high) 4672 { 4673 ocontext_t *newc, *c, *l, *head; 4674 char *id; 4675 4676 if (policydbp->target_platform != SEPOL_TARGET_XEN) { 4677 yyerror("ioportcon not supported for target"); 4678 return -1; 4679 } 4680 4681 if (pass == 1) { 4682 id = (char *)queue_remove(id_queue); 4683 free(id); 4684 parse_security_context(NULL); 4685 return 0; 4686 } 4687 4688 newc = malloc(sizeof(ocontext_t)); 4689 if (!newc) { 4690 yyerror("out of memory"); 4691 return -1; 4692 } 4693 memset(newc, 0, sizeof(ocontext_t)); 4694 4695 newc->u.ioport.low_ioport = low; 4696 newc->u.ioport.high_ioport = high; 4697 4698 if (low > high) { 4699 yyerror2("low ioport 0x%lx exceeds high ioport 0x%lx", low, high); 4700 free(newc); 4701 return -1; 4702 } 4703 4704 if (parse_security_context(&newc->context[0])) { 4705 free(newc); 4706 return -1; 4707 } 4708 4709 head = policydbp->ocontexts[OCON_XEN_IOPORT]; 4710 for (l = NULL, c = head; c; l = c, c = c->next) { 4711 uint32_t low2, high2; 4712 4713 low2 = c->u.ioport.low_ioport; 4714 high2 = c->u.ioport.high_ioport; 4715 if (low <= high2 && low2 <= high) { 4716 yyerror2("ioportcon entry for 0x%lx-0x%lx overlaps with" 4717 "earlier entry 0x%x-0x%x", low, high, 4718 low2, high2); 4719 goto bad; 4720 } 4721 } 4722 4723 if (l) 4724 l->next = newc; 4725 else 4726 policydbp->ocontexts[OCON_XEN_IOPORT] = newc; 4727 4728 return 0; 4729 4730 bad: 4731 free(newc); 4732 return -1; 4733 } 4734 4735 int define_pcidevice_context(unsigned long device) 4736 { 4737 ocontext_t *newc, *c, *l, *head; 4738 char *id; 4739 4740 if (policydbp->target_platform != SEPOL_TARGET_XEN) { 4741 yyerror("pcidevicecon not supported for target"); 4742 return -1; 4743 } 4744 4745 if (pass == 1) { 4746 id = (char *) queue_remove(id_queue); 4747 free(id); 4748 parse_security_context(NULL); 4749 return 0; 4750 } 4751 4752 newc = malloc(sizeof(ocontext_t)); 4753 if (!newc) { 4754 yyerror("out of memory"); 4755 return -1; 4756 } 4757 memset(newc, 0, sizeof(ocontext_t)); 4758 4759 newc->u.device = device; 4760 4761 if (parse_security_context(&newc->context[0])) { 4762 free(newc); 4763 return -1; 4764 } 4765 4766 head = policydbp->ocontexts[OCON_XEN_PCIDEVICE]; 4767 for (l = NULL, c = head; c; l = c, c = c->next) { 4768 unsigned int device2; 4769 4770 device2 = c->u.device; 4771 if (device == device2) { 4772 yyerror2("duplicate pcidevicecon entry for 0x%lx", 4773 device); 4774 goto bad; 4775 } 4776 } 4777 4778 if (l) 4779 l->next = newc; 4780 else 4781 policydbp->ocontexts[OCON_XEN_PCIDEVICE] = newc; 4782 4783 return 0; 4784 4785 bad: 4786 free(newc); 4787 return -1; 4788 } 4789 4790 int define_devicetree_context() 4791 { 4792 ocontext_t *newc, *c, *l, *head; 4793 4794 if (policydbp->target_platform != SEPOL_TARGET_XEN) { 4795 yyerror("devicetreecon not supported for target"); 4796 return -1; 4797 } 4798 4799 if (pass == 1) { 4800 free(queue_remove(id_queue)); 4801 parse_security_context(NULL); 4802 return 0; 4803 } 4804 4805 newc = malloc(sizeof(ocontext_t)); 4806 if (!newc) { 4807 yyerror("out of memory"); 4808 return -1; 4809 } 4810 memset(newc, 0, sizeof(ocontext_t)); 4811 4812 newc->u.name = (char *)queue_remove(id_queue); 4813 if (!newc->u.name) { 4814 free(newc); 4815 return -1; 4816 } 4817 4818 if (parse_security_context(&newc->context[0])) { 4819 free(newc->u.name); 4820 free(newc); 4821 return -1; 4822 } 4823 4824 head = policydbp->ocontexts[OCON_XEN_DEVICETREE]; 4825 for (l = NULL, c = head; c; l = c, c = c->next) { 4826 if (strcmp(newc->u.name, c->u.name) == 0) { 4827 yyerror2("duplicate devicetree entry for '%s'", newc->u.name); 4828 goto bad; 4829 } 4830 } 4831 4832 if (l) 4833 l->next = newc; 4834 else 4835 policydbp->ocontexts[OCON_XEN_DEVICETREE] = newc; 4836 4837 return 0; 4838 4839 bad: 4840 free(newc->u.name); 4841 free(newc); 4842 return -1; 4843 } 4844 4845 int define_port_context(unsigned int low, unsigned int high) 4846 { 4847 ocontext_t *newc, *c, *l, *head; 4848 unsigned int protocol; 4849 char *id; 4850 4851 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 4852 yyerror("portcon not supported for target"); 4853 return -1; 4854 } 4855 4856 if (pass == 1) { 4857 id = (char *)queue_remove(id_queue); 4858 free(id); 4859 parse_security_context(NULL); 4860 return 0; 4861 } 4862 4863 newc = malloc(sizeof(ocontext_t)); 4864 if (!newc) { 4865 yyerror("out of memory"); 4866 return -1; 4867 } 4868 memset(newc, 0, sizeof(ocontext_t)); 4869 4870 id = (char *)queue_remove(id_queue); 4871 if (!id) { 4872 free(newc); 4873 return -1; 4874 } 4875 if ((strcmp(id, "tcp") == 0) || (strcmp(id, "TCP") == 0)) { 4876 protocol = IPPROTO_TCP; 4877 } else if ((strcmp(id, "udp") == 0) || (strcmp(id, "UDP") == 0)) { 4878 protocol = IPPROTO_UDP; 4879 } else { 4880 yyerror2("unrecognized protocol %s", id); 4881 free(newc); 4882 return -1; 4883 } 4884 4885 newc->u.port.protocol = protocol; 4886 newc->u.port.low_port = low; 4887 newc->u.port.high_port = high; 4888 4889 if (low > high) { 4890 yyerror2("low port %d exceeds high port %d", low, high); 4891 free(newc); 4892 return -1; 4893 } 4894 4895 if (parse_security_context(&newc->context[0])) { 4896 free(newc); 4897 return -1; 4898 } 4899 4900 /* Preserve the matching order specified in the configuration. */ 4901 head = policydbp->ocontexts[OCON_PORT]; 4902 for (l = NULL, c = head; c; l = c, c = c->next) { 4903 unsigned int prot2, low2, high2; 4904 4905 prot2 = c->u.port.protocol; 4906 low2 = c->u.port.low_port; 4907 high2 = c->u.port.high_port; 4908 if (protocol != prot2) 4909 continue; 4910 if (low == low2 && high == high2) { 4911 yyerror2("duplicate portcon entry for %s %d-%d ", id, 4912 low, high); 4913 goto bad; 4914 } 4915 if (low2 <= low && high2 >= high) { 4916 yyerror2("portcon entry for %s %d-%d hidden by earlier " 4917 "entry for %d-%d", id, low, high, low2, high2); 4918 goto bad; 4919 } 4920 } 4921 4922 if (l) 4923 l->next = newc; 4924 else 4925 policydbp->ocontexts[OCON_PORT] = newc; 4926 4927 return 0; 4928 4929 bad: 4930 free(newc); 4931 return -1; 4932 } 4933 4934 int define_netif_context(void) 4935 { 4936 ocontext_t *newc, *c, *head; 4937 4938 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 4939 yyerror("netifcon not supported for target"); 4940 return -1; 4941 } 4942 4943 if (pass == 1) { 4944 free(queue_remove(id_queue)); 4945 parse_security_context(NULL); 4946 parse_security_context(NULL); 4947 return 0; 4948 } 4949 4950 newc = (ocontext_t *) malloc(sizeof(ocontext_t)); 4951 if (!newc) { 4952 yyerror("out of memory"); 4953 return -1; 4954 } 4955 memset(newc, 0, sizeof(ocontext_t)); 4956 4957 newc->u.name = (char *)queue_remove(id_queue); 4958 if (!newc->u.name) { 4959 free(newc); 4960 return -1; 4961 } 4962 if (parse_security_context(&newc->context[0])) { 4963 free(newc->u.name); 4964 free(newc); 4965 return -1; 4966 } 4967 if (parse_security_context(&newc->context[1])) { 4968 context_destroy(&newc->context[0]); 4969 free(newc->u.name); 4970 free(newc); 4971 return -1; 4972 } 4973 head = policydbp->ocontexts[OCON_NETIF]; 4974 4975 for (c = head; c; c = c->next) { 4976 if (!strcmp(newc->u.name, c->u.name)) { 4977 yyerror2("duplicate entry for network interface %s", 4978 newc->u.name); 4979 context_destroy(&newc->context[0]); 4980 context_destroy(&newc->context[1]); 4981 free(newc->u.name); 4982 free(newc); 4983 return -1; 4984 } 4985 } 4986 4987 newc->next = head; 4988 policydbp->ocontexts[OCON_NETIF] = newc; 4989 return 0; 4990 } 4991 4992 int define_ipv4_node_context() 4993 { 4994 char *id; 4995 int rc = 0; 4996 struct in_addr addr, mask; 4997 ocontext_t *newc, *c, *l, *head; 4998 4999 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 5000 yyerror("nodecon not supported for target"); 5001 return -1; 5002 } 5003 5004 if (pass == 1) { 5005 free(queue_remove(id_queue)); 5006 free(queue_remove(id_queue)); 5007 parse_security_context(NULL); 5008 goto out; 5009 } 5010 5011 id = queue_remove(id_queue); 5012 if (!id) { 5013 yyerror("failed to read ipv4 address"); 5014 rc = -1; 5015 goto out; 5016 } 5017 5018 rc = inet_pton(AF_INET, id, &addr); 5019 free(id); 5020 if (rc < 1) { 5021 yyerror("failed to parse ipv4 address"); 5022 if (rc == 0) 5023 rc = -1; 5024 goto out; 5025 } 5026 5027 id = queue_remove(id_queue); 5028 if (!id) { 5029 yyerror("failed to read ipv4 address"); 5030 rc = -1; 5031 goto out; 5032 } 5033 5034 rc = inet_pton(AF_INET, id, &mask); 5035 free(id); 5036 if (rc < 1) { 5037 yyerror("failed to parse ipv4 mask"); 5038 if (rc == 0) 5039 rc = -1; 5040 goto out; 5041 } 5042 5043 newc = malloc(sizeof(ocontext_t)); 5044 if (!newc) { 5045 yyerror("out of memory"); 5046 rc = -1; 5047 goto out; 5048 } 5049 5050 memset(newc, 0, sizeof(ocontext_t)); 5051 newc->u.node.addr = addr.s_addr; 5052 newc->u.node.mask = mask.s_addr; 5053 5054 if (parse_security_context(&newc->context[0])) { 5055 free(newc); 5056 return -1; 5057 } 5058 5059 /* Create order of most specific to least retaining 5060 the order specified in the configuration. */ 5061 head = policydbp->ocontexts[OCON_NODE]; 5062 for (l = NULL, c = head; c; l = c, c = c->next) { 5063 if (newc->u.node.mask > c->u.node.mask) 5064 break; 5065 } 5066 5067 newc->next = c; 5068 5069 if (l) 5070 l->next = newc; 5071 else 5072 policydbp->ocontexts[OCON_NODE] = newc; 5073 rc = 0; 5074 out: 5075 return rc; 5076 } 5077 5078 int define_ipv6_node_context(void) 5079 { 5080 char *id; 5081 int rc = 0; 5082 struct in6_addr addr, mask; 5083 ocontext_t *newc, *c, *l, *head; 5084 5085 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 5086 yyerror("nodecon not supported for target"); 5087 return -1; 5088 } 5089 5090 if (pass == 1) { 5091 free(queue_remove(id_queue)); 5092 free(queue_remove(id_queue)); 5093 parse_security_context(NULL); 5094 goto out; 5095 } 5096 5097 id = queue_remove(id_queue); 5098 if (!id) { 5099 yyerror("failed to read ipv6 address"); 5100 rc = -1; 5101 goto out; 5102 } 5103 5104 rc = inet_pton(AF_INET6, id, &addr); 5105 free(id); 5106 if (rc < 1) { 5107 yyerror("failed to parse ipv6 address"); 5108 if (rc == 0) 5109 rc = -1; 5110 goto out; 5111 } 5112 5113 id = queue_remove(id_queue); 5114 if (!id) { 5115 yyerror("failed to read ipv6 address"); 5116 rc = -1; 5117 goto out; 5118 } 5119 5120 rc = inet_pton(AF_INET6, id, &mask); 5121 free(id); 5122 if (rc < 1) { 5123 yyerror("failed to parse ipv6 mask"); 5124 if (rc == 0) 5125 rc = -1; 5126 goto out; 5127 } 5128 5129 newc = malloc(sizeof(ocontext_t)); 5130 if (!newc) { 5131 yyerror("out of memory"); 5132 rc = -1; 5133 goto out; 5134 } 5135 5136 memset(newc, 0, sizeof(ocontext_t)); 5137 5138 #ifdef DARWIN 5139 memcpy(&newc->u.node6.addr[0], &addr.s6_addr[0], 16); 5140 memcpy(&newc->u.node6.mask[0], &mask.s6_addr[0], 16); 5141 #else 5142 memcpy(&newc->u.node6.addr[0], &addr.s6_addr32[0], 16); 5143 memcpy(&newc->u.node6.mask[0], &mask.s6_addr32[0], 16); 5144 #endif 5145 5146 if (parse_security_context(&newc->context[0])) { 5147 free(newc); 5148 rc = -1; 5149 goto out; 5150 } 5151 5152 /* Create order of most specific to least retaining 5153 the order specified in the configuration. */ 5154 head = policydbp->ocontexts[OCON_NODE6]; 5155 for (l = NULL, c = head; c; l = c, c = c->next) { 5156 if (memcmp(&newc->u.node6.mask, &c->u.node6.mask, 16) > 0) 5157 break; 5158 } 5159 5160 newc->next = c; 5161 5162 if (l) 5163 l->next = newc; 5164 else 5165 policydbp->ocontexts[OCON_NODE6] = newc; 5166 5167 rc = 0; 5168 out: 5169 return rc; 5170 } 5171 5172 int define_fs_use(int behavior) 5173 { 5174 ocontext_t *newc, *c, *head; 5175 5176 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 5177 yyerror("fsuse not supported for target"); 5178 return -1; 5179 } 5180 5181 if (pass == 1) { 5182 free(queue_remove(id_queue)); 5183 parse_security_context(NULL); 5184 return 0; 5185 } 5186 5187 newc = (ocontext_t *) malloc(sizeof(ocontext_t)); 5188 if (!newc) { 5189 yyerror("out of memory"); 5190 return -1; 5191 } 5192 memset(newc, 0, sizeof(ocontext_t)); 5193 5194 newc->u.name = (char *)queue_remove(id_queue); 5195 if (!newc->u.name) { 5196 free(newc); 5197 return -1; 5198 } 5199 newc->v.behavior = behavior; 5200 if (parse_security_context(&newc->context[0])) { 5201 free(newc->u.name); 5202 free(newc); 5203 return -1; 5204 } 5205 5206 head = policydbp->ocontexts[OCON_FSUSE]; 5207 5208 for (c = head; c; c = c->next) { 5209 if (!strcmp(newc->u.name, c->u.name)) { 5210 yyerror2("duplicate fs_use entry for filesystem type %s", 5211 newc->u.name); 5212 context_destroy(&newc->context[0]); 5213 free(newc->u.name); 5214 free(newc); 5215 return -1; 5216 } 5217 } 5218 5219 newc->next = head; 5220 policydbp->ocontexts[OCON_FSUSE] = newc; 5221 return 0; 5222 } 5223 5224 int define_genfs_context_helper(char *fstype, int has_type) 5225 { 5226 struct genfs *genfs_p, *genfs, *newgenfs; 5227 ocontext_t *newc, *c, *head, *p; 5228 char *type = NULL; 5229 int len, len2; 5230 5231 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 5232 yyerror("genfs not supported for target"); 5233 return -1; 5234 } 5235 5236 if (pass == 1) { 5237 free(fstype); 5238 free(queue_remove(id_queue)); 5239 if (has_type) 5240 free(queue_remove(id_queue)); 5241 parse_security_context(NULL); 5242 return 0; 5243 } 5244 5245 for (genfs_p = NULL, genfs = policydbp->genfs; 5246 genfs; genfs_p = genfs, genfs = genfs->next) { 5247 if (strcmp(fstype, genfs->fstype) <= 0) 5248 break; 5249 } 5250 5251 if (!genfs || strcmp(fstype, genfs->fstype)) { 5252 newgenfs = malloc(sizeof(struct genfs)); 5253 if (!newgenfs) { 5254 yyerror("out of memory"); 5255 return -1; 5256 } 5257 memset(newgenfs, 0, sizeof(struct genfs)); 5258 newgenfs->fstype = fstype; 5259 newgenfs->next = genfs; 5260 if (genfs_p) 5261 genfs_p->next = newgenfs; 5262 else 5263 policydbp->genfs = newgenfs; 5264 genfs = newgenfs; 5265 } 5266 5267 newc = (ocontext_t *) malloc(sizeof(ocontext_t)); 5268 if (!newc) { 5269 yyerror("out of memory"); 5270 return -1; 5271 } 5272 memset(newc, 0, sizeof(ocontext_t)); 5273 5274 newc->u.name = (char *)queue_remove(id_queue); 5275 if (!newc->u.name) 5276 goto fail; 5277 if (has_type) { 5278 type = (char *)queue_remove(id_queue); 5279 if (!type) 5280 goto fail; 5281 if (type[1] != 0) { 5282 yyerror2("invalid type %s", type); 5283 goto fail; 5284 } 5285 switch (type[0]) { 5286 case 'b': 5287 newc->v.sclass = SECCLASS_BLK_FILE; 5288 break; 5289 case 'c': 5290 newc->v.sclass = SECCLASS_CHR_FILE; 5291 break; 5292 case 'd': 5293 newc->v.sclass = SECCLASS_DIR; 5294 break; 5295 case 'p': 5296 newc->v.sclass = SECCLASS_FIFO_FILE; 5297 break; 5298 case 'l': 5299 newc->v.sclass = SECCLASS_LNK_FILE; 5300 break; 5301 case 's': 5302 newc->v.sclass = SECCLASS_SOCK_FILE; 5303 break; 5304 case '-': 5305 newc->v.sclass = SECCLASS_FILE; 5306 break; 5307 default: 5308 yyerror2("invalid type %s", type); 5309 goto fail; 5310 } 5311 } 5312 if (parse_security_context(&newc->context[0])) 5313 goto fail; 5314 5315 head = genfs->head; 5316 5317 for (p = NULL, c = head; c; p = c, c = c->next) { 5318 if (!strcmp(newc->u.name, c->u.name) && 5319 (!newc->v.sclass || !c->v.sclass 5320 || newc->v.sclass == c->v.sclass)) { 5321 yyerror2("duplicate entry for genfs entry (%s, %s)", 5322 fstype, newc->u.name); 5323 goto fail; 5324 } 5325 len = strlen(newc->u.name); 5326 len2 = strlen(c->u.name); 5327 if (len > len2) 5328 break; 5329 } 5330 5331 newc->next = c; 5332 if (p) 5333 p->next = newc; 5334 else 5335 genfs->head = newc; 5336 return 0; 5337 fail: 5338 if (type) 5339 free(type); 5340 context_destroy(&newc->context[0]); 5341 if (fstype) 5342 free(fstype); 5343 if (newc->u.name) 5344 free(newc->u.name); 5345 free(newc); 5346 return -1; 5347 } 5348 5349 int define_genfs_context(int has_type) 5350 { 5351 return define_genfs_context_helper(queue_remove(id_queue), has_type); 5352 } 5353 5354 int define_range_trans(int class_specified) 5355 { 5356 char *id; 5357 level_datum_t *levdatum = 0; 5358 class_datum_t *cladatum; 5359 range_trans_rule_t *rule; 5360 int l, add = 1; 5361 5362 if (!mlspol) { 5363 yyerror("range_transition rule in non-MLS configuration"); 5364 return -1; 5365 } 5366 5367 if (pass == 1) { 5368 while ((id = queue_remove(id_queue))) 5369 free(id); 5370 while ((id = queue_remove(id_queue))) 5371 free(id); 5372 if (class_specified) 5373 while ((id = queue_remove(id_queue))) 5374 free(id); 5375 id = queue_remove(id_queue); 5376 free(id); 5377 for (l = 0; l < 2; l++) { 5378 while ((id = queue_remove(id_queue))) { 5379 free(id); 5380 } 5381 id = queue_remove(id_queue); 5382 if (!id) 5383 break; 5384 free(id); 5385 } 5386 return 0; 5387 } 5388 5389 rule = malloc(sizeof(struct range_trans_rule)); 5390 if (!rule) { 5391 yyerror("out of memory"); 5392 return -1; 5393 } 5394 range_trans_rule_init(rule); 5395 5396 while ((id = queue_remove(id_queue))) { 5397 if (set_types(&rule->stypes, id, &add, 0)) 5398 goto out; 5399 } 5400 add = 1; 5401 while ((id = queue_remove(id_queue))) { 5402 if (set_types(&rule->ttypes, id, &add, 0)) 5403 goto out; 5404 } 5405 5406 if (class_specified) { 5407 if (read_classes(&rule->tclasses)) 5408 goto out; 5409 } else { 5410 cladatum = hashtab_search(policydbp->p_classes.table, 5411 "process"); 5412 if (!cladatum) { 5413 yyerror2("could not find process class for " 5414 "legacy range_transition statement"); 5415 goto out; 5416 } 5417 5418 if (ebitmap_set_bit(&rule->tclasses, cladatum->s.value - 1, TRUE)) { 5419 yyerror("out of memory"); 5420 goto out; 5421 } 5422 } 5423 5424 id = (char *)queue_remove(id_queue); 5425 if (!id) { 5426 yyerror("no range in range_transition definition?"); 5427 goto out; 5428 } 5429 for (l = 0; l < 2; l++) { 5430 levdatum = hashtab_search(policydbp->p_levels.table, id); 5431 if (!levdatum) { 5432 yyerror2("unknown level %s used in range_transition " 5433 "definition", id); 5434 free(id); 5435 goto out; 5436 } 5437 free(id); 5438 5439 rule->trange.level[l].sens = levdatum->level->sens; 5440 5441 while ((id = queue_remove(id_queue))) { 5442 if (parse_semantic_categories(id, levdatum, 5443 &rule->trange.level[l].cat)) { 5444 free(id); 5445 goto out; 5446 } 5447 free(id); 5448 } 5449 5450 id = (char *)queue_remove(id_queue); 5451 if (!id) 5452 break; 5453 } 5454 if (l == 0) { 5455 if (mls_semantic_level_cpy(&rule->trange.level[1], 5456 &rule->trange.level[0])) { 5457 yyerror("out of memory"); 5458 goto out; 5459 } 5460 } 5461 5462 append_range_trans(rule); 5463 return 0; 5464 5465 out: 5466 range_trans_rule_destroy(rule); 5467 free(rule); 5468 return -1; 5469 } 5470 5471 /* FLASK */ 5472