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