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 330static int read_classes(ebitmap_t *e_classes) 331{ 332 char *id; 333 class_datum_t *cladatum; 334 335 while ((id = queue_remove(id_queue))) { 336 if (!is_id_in_scope(SYM_CLASSES, id)) { 337 yyerror2("class %s is not within scope", id); 338 return -1; 339 } 340 cladatum = hashtab_search(policydbp->p_classes.table, id); 341 if (!cladatum) { 342 yyerror2("unknown class %s", id); 343 return -1; 344 } 345 if (ebitmap_set_bit(e_classes, cladatum->s.value - 1, TRUE)) { 346 yyerror("Out of memory"); 347 return -1; 348 } 349 free(id); 350 } 351 return 0; 352} 353 354int define_default_user(int which) 355{ 356 char *id; 357 class_datum_t *cladatum; 358 359 if (pass == 1) { 360 while ((id = queue_remove(id_queue))) 361 free(id); 362 return 0; 363 } 364 365 while ((id = queue_remove(id_queue))) { 366 if (!is_id_in_scope(SYM_CLASSES, id)) { 367 yyerror2("class %s is not within scope", id); 368 return -1; 369 } 370 cladatum = hashtab_search(policydbp->p_classes.table, id); 371 if (!cladatum) { 372 yyerror2("unknown class %s", id); 373 return -1; 374 } 375 if (cladatum->default_user && cladatum->default_user != which) { 376 yyerror2("conflicting default user information for class %s", id); 377 return -1; 378 } 379 cladatum->default_user = which; 380 free(id); 381 } 382 383 return 0; 384} 385 386int define_default_role(int which) 387{ 388 char *id; 389 class_datum_t *cladatum; 390 391 if (pass == 1) { 392 while ((id = queue_remove(id_queue))) 393 free(id); 394 return 0; 395 } 396 397 while ((id = queue_remove(id_queue))) { 398 if (!is_id_in_scope(SYM_CLASSES, id)) { 399 yyerror2("class %s is not within scope", id); 400 return -1; 401 } 402 cladatum = hashtab_search(policydbp->p_classes.table, id); 403 if (!cladatum) { 404 yyerror2("unknown class %s", id); 405 return -1; 406 } 407 if (cladatum->default_role && cladatum->default_role != which) { 408 yyerror2("conflicting default role information for class %s", id); 409 return -1; 410 } 411 cladatum->default_role = which; 412 free(id); 413 } 414 415 return 0; 416} 417 418int define_default_range(int which) 419{ 420 char *id; 421 class_datum_t *cladatum; 422 423 if (pass == 1) { 424 while ((id = queue_remove(id_queue))) 425 free(id); 426 return 0; 427 } 428 429 while ((id = queue_remove(id_queue))) { 430 if (!is_id_in_scope(SYM_CLASSES, id)) { 431 yyerror2("class %s is not within scope", id); 432 return -1; 433 } 434 cladatum = hashtab_search(policydbp->p_classes.table, id); 435 if (!cladatum) { 436 yyerror2("unknown class %s", id); 437 return -1; 438 } 439 if (cladatum->default_range && cladatum->default_range != which) { 440 yyerror2("conflicting default range information for class %s", id); 441 return -1; 442 } 443 cladatum->default_range = which; 444 free(id); 445 } 446 447 return 0; 448} 449 450int define_common_perms(void) 451{ 452 char *id = 0, *perm = 0; 453 common_datum_t *comdatum = 0; 454 perm_datum_t *perdatum = 0; 455 int ret; 456 457 if (pass == 2) { 458 while ((id = queue_remove(id_queue))) 459 free(id); 460 return 0; 461 } 462 463 id = (char *)queue_remove(id_queue); 464 if (!id) { 465 yyerror("no common name for common perm definition?"); 466 return -1; 467 } 468 comdatum = hashtab_search(policydbp->p_commons.table, id); 469 if (comdatum) { 470 yyerror2("duplicate declaration for common %s\n", id); 471 return -1; 472 } 473 comdatum = (common_datum_t *) malloc(sizeof(common_datum_t)); 474 if (!comdatum) { 475 yyerror("out of memory"); 476 goto bad; 477 } 478 memset(comdatum, 0, sizeof(common_datum_t)); 479 ret = hashtab_insert(policydbp->p_commons.table, 480 (hashtab_key_t) id, (hashtab_datum_t) comdatum); 481 482 if (ret == SEPOL_EEXIST) { 483 yyerror("duplicate common definition"); 484 goto bad; 485 } 486 if (ret == SEPOL_ENOMEM) { 487 yyerror("hash table overflow"); 488 goto bad; 489 } 490 comdatum->s.value = policydbp->p_commons.nprim + 1; 491 if (symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE)) { 492 yyerror("out of memory"); 493 goto bad; 494 } 495 policydbp->p_commons.nprim++; 496 while ((perm = queue_remove(id_queue))) { 497 perdatum = (perm_datum_t *) malloc(sizeof(perm_datum_t)); 498 if (!perdatum) { 499 yyerror("out of memory"); 500 goto bad_perm; 501 } 502 memset(perdatum, 0, sizeof(perm_datum_t)); 503 perdatum->s.value = comdatum->permissions.nprim + 1; 504 505 if (perdatum->s.value > (sizeof(sepol_access_vector_t) * 8)) { 506 yyerror 507 ("too many permissions to fit in an access vector"); 508 goto bad_perm; 509 } 510 ret = hashtab_insert(comdatum->permissions.table, 511 (hashtab_key_t) perm, 512 (hashtab_datum_t) perdatum); 513 514 if (ret == SEPOL_EEXIST) { 515 yyerror2("duplicate permission %s in common %s", perm, 516 id); 517 goto bad_perm; 518 } 519 if (ret == SEPOL_ENOMEM) { 520 yyerror("hash table overflow"); 521 goto bad_perm; 522 } 523 comdatum->permissions.nprim++; 524 } 525 526 return 0; 527 528 bad: 529 if (id) 530 free(id); 531 if (comdatum) 532 free(comdatum); 533 return -1; 534 535 bad_perm: 536 if (perm) 537 free(perm); 538 if (perdatum) 539 free(perdatum); 540 return -1; 541} 542 543int define_av_perms(int inherits) 544{ 545 char *id; 546 class_datum_t *cladatum; 547 common_datum_t *comdatum; 548 perm_datum_t *perdatum = 0, *perdatum2 = 0; 549 int ret; 550 551 if (pass == 2) { 552 while ((id = queue_remove(id_queue))) 553 free(id); 554 return 0; 555 } 556 557 id = (char *)queue_remove(id_queue); 558 if (!id) { 559 yyerror("no tclass name for av perm definition?"); 560 return -1; 561 } 562 cladatum = (class_datum_t *) hashtab_search(policydbp->p_classes.table, 563 (hashtab_key_t) id); 564 if (!cladatum) { 565 yyerror2("class %s is not defined", id); 566 goto bad; 567 } 568 free(id); 569 570 if (cladatum->comdatum || cladatum->permissions.nprim) { 571 yyerror("duplicate access vector definition"); 572 return -1; 573 } 574 if (symtab_init(&cladatum->permissions, PERM_SYMTAB_SIZE)) { 575 yyerror("out of memory"); 576 return -1; 577 } 578 if (inherits) { 579 id = (char *)queue_remove(id_queue); 580 if (!id) { 581 yyerror 582 ("no inherits name for access vector definition?"); 583 return -1; 584 } 585 comdatum = 586 (common_datum_t *) hashtab_search(policydbp->p_commons. 587 table, 588 (hashtab_key_t) id); 589 590 if (!comdatum) { 591 yyerror2("common %s is not defined", id); 592 goto bad; 593 } 594 cladatum->comkey = id; 595 cladatum->comdatum = comdatum; 596 597 /* 598 * Class-specific permissions start with values 599 * after the last common permission. 600 */ 601 cladatum->permissions.nprim += comdatum->permissions.nprim; 602 } 603 while ((id = queue_remove(id_queue))) { 604 perdatum = (perm_datum_t *) malloc(sizeof(perm_datum_t)); 605 if (!perdatum) { 606 yyerror("out of memory"); 607 goto bad; 608 } 609 memset(perdatum, 0, sizeof(perm_datum_t)); 610 perdatum->s.value = ++cladatum->permissions.nprim; 611 612 if (perdatum->s.value > (sizeof(sepol_access_vector_t) * 8)) { 613 yyerror 614 ("too many permissions to fit in an access vector"); 615 goto bad; 616 } 617 if (inherits) { 618 /* 619 * Class-specific permissions and 620 * common permissions exist in the same 621 * name space. 622 */ 623 perdatum2 = 624 (perm_datum_t *) hashtab_search(cladatum->comdatum-> 625 permissions.table, 626 (hashtab_key_t) id); 627 if (perdatum2) { 628 yyerror2("permission %s conflicts with an " 629 "inherited permission", id); 630 goto bad; 631 } 632 } 633 ret = hashtab_insert(cladatum->permissions.table, 634 (hashtab_key_t) id, 635 (hashtab_datum_t) perdatum); 636 637 if (ret == SEPOL_EEXIST) { 638 yyerror2("duplicate permission %s", id); 639 goto bad; 640 } 641 if (ret == SEPOL_ENOMEM) { 642 yyerror("hash table overflow"); 643 goto bad; 644 } 645 if (add_perm_to_class(perdatum->s.value, cladatum->s.value)) { 646 yyerror("out of memory"); 647 goto bad; 648 } 649 } 650 651 return 0; 652 653 bad: 654 if (id) 655 free(id); 656 if (perdatum) 657 free(perdatum); 658 return -1; 659} 660 661int define_sens(void) 662{ 663 char *id; 664 mls_level_t *level = 0; 665 level_datum_t *datum = 0, *aliasdatum = 0; 666 int ret; 667 uint32_t value; /* dummy variable -- its value is never used */ 668 669 if (!mlspol) { 670 yyerror("sensitivity definition in non-MLS configuration"); 671 return -1; 672 } 673 674 if (pass == 2) { 675 while ((id = queue_remove(id_queue))) 676 free(id); 677 return 0; 678 } 679 680 id = (char *)queue_remove(id_queue); 681 if (!id) { 682 yyerror("no sensitivity name for sensitivity definition?"); 683 return -1; 684 } 685 if (id_has_dot(id)) { 686 yyerror("sensitivity identifiers may not contain periods"); 687 goto bad; 688 } 689 level = (mls_level_t *) malloc(sizeof(mls_level_t)); 690 if (!level) { 691 yyerror("out of memory"); 692 goto bad; 693 } 694 mls_level_init(level); 695 level->sens = 0; /* actual value set in define_dominance */ 696 ebitmap_init(&level->cat); /* actual value set in define_level */ 697 698 datum = (level_datum_t *) malloc(sizeof(level_datum_t)); 699 if (!datum) { 700 yyerror("out of memory"); 701 goto bad; 702 } 703 level_datum_init(datum); 704 datum->isalias = FALSE; 705 datum->level = level; 706 707 ret = declare_symbol(SYM_LEVELS, id, datum, &value, &value); 708 switch (ret) { 709 case -3:{ 710 yyerror("Out of memory!"); 711 goto bad; 712 } 713 case -2:{ 714 yyerror("duplicate declaration of sensitivity level"); 715 goto bad; 716 } 717 case -1:{ 718 yyerror("could not declare sensitivity level here"); 719 goto bad; 720 } 721 case 0: 722 case 1:{ 723 break; 724 } 725 default:{ 726 assert(0); /* should never get here */ 727 } 728 } 729 730 while ((id = queue_remove(id_queue))) { 731 if (id_has_dot(id)) { 732 yyerror("sensitivity aliases may not contain periods"); 733 goto bad_alias; 734 } 735 aliasdatum = (level_datum_t *) malloc(sizeof(level_datum_t)); 736 if (!aliasdatum) { 737 yyerror("out of memory"); 738 goto bad_alias; 739 } 740 level_datum_init(aliasdatum); 741 aliasdatum->isalias = TRUE; 742 aliasdatum->level = level; 743 744 ret = declare_symbol(SYM_LEVELS, id, aliasdatum, NULL, &value); 745 switch (ret) { 746 case -3:{ 747 yyerror("Out of memory!"); 748 goto bad_alias; 749 } 750 case -2:{ 751 yyerror 752 ("duplicate declaration of sensitivity alias"); 753 goto bad_alias; 754 } 755 case -1:{ 756 yyerror 757 ("could not declare sensitivity alias here"); 758 goto bad_alias; 759 } 760 case 0: 761 case 1:{ 762 break; 763 } 764 default:{ 765 assert(0); /* should never get here */ 766 } 767 } 768 } 769 770 return 0; 771 772 bad: 773 if (id) 774 free(id); 775 if (level) 776 free(level); 777 if (datum) { 778 level_datum_destroy(datum); 779 free(datum); 780 } 781 return -1; 782 783 bad_alias: 784 if (id) 785 free(id); 786 if (aliasdatum) { 787 level_datum_destroy(aliasdatum); 788 free(aliasdatum); 789 } 790 return -1; 791} 792 793int define_dominance(void) 794{ 795 level_datum_t *datum; 796 int order; 797 char *id; 798 799 if (!mlspol) { 800 yyerror("dominance definition in non-MLS configuration"); 801 return -1; 802 } 803 804 if (pass == 2) { 805 while ((id = queue_remove(id_queue))) 806 free(id); 807 return 0; 808 } 809 810 order = 0; 811 while ((id = (char *)queue_remove(id_queue))) { 812 datum = 813 (level_datum_t *) hashtab_search(policydbp->p_levels.table, 814 (hashtab_key_t) id); 815 if (!datum) { 816 yyerror2("unknown sensitivity %s used in dominance " 817 "definition", id); 818 free(id); 819 return -1; 820 } 821 if (datum->level->sens != 0) { 822 yyerror2("sensitivity %s occurs multiply in dominance " 823 "definition", id); 824 free(id); 825 return -1; 826 } 827 datum->level->sens = ++order; 828 829 /* no need to keep sensitivity name */ 830 free(id); 831 } 832 833 if (order != policydbp->p_levels.nprim) { 834 yyerror 835 ("all sensitivities must be specified in dominance definition"); 836 return -1; 837 } 838 return 0; 839} 840 841int define_category(void) 842{ 843 char *id; 844 cat_datum_t *datum = 0, *aliasdatum = 0; 845 int ret; 846 uint32_t value; 847 848 if (!mlspol) { 849 yyerror("category definition in non-MLS configuration"); 850 return -1; 851 } 852 853 if (pass == 2) { 854 while ((id = queue_remove(id_queue))) 855 free(id); 856 return 0; 857 } 858 859 id = (char *)queue_remove(id_queue); 860 if (!id) { 861 yyerror("no category name for category definition?"); 862 return -1; 863 } 864 if (id_has_dot(id)) { 865 yyerror("category identifiers may not contain periods"); 866 goto bad; 867 } 868 datum = (cat_datum_t *) malloc(sizeof(cat_datum_t)); 869 if (!datum) { 870 yyerror("out of memory"); 871 goto bad; 872 } 873 cat_datum_init(datum); 874 datum->isalias = FALSE; 875 876 ret = declare_symbol(SYM_CATS, id, datum, &value, &value); 877 switch (ret) { 878 case -3:{ 879 yyerror("Out of memory!"); 880 goto bad; 881 } 882 case -2:{ 883 yyerror("duplicate declaration of category"); 884 goto bad; 885 } 886 case -1:{ 887 yyerror("could not declare category here"); 888 goto bad; 889 } 890 case 0: 891 case 1:{ 892 break; 893 } 894 default:{ 895 assert(0); /* should never get here */ 896 } 897 } 898 datum->s.value = value; 899 900 while ((id = queue_remove(id_queue))) { 901 if (id_has_dot(id)) { 902 yyerror("category aliases may not contain periods"); 903 goto bad_alias; 904 } 905 aliasdatum = (cat_datum_t *) malloc(sizeof(cat_datum_t)); 906 if (!aliasdatum) { 907 yyerror("out of memory"); 908 goto bad_alias; 909 } 910 cat_datum_init(aliasdatum); 911 aliasdatum->isalias = TRUE; 912 aliasdatum->s.value = datum->s.value; 913 914 ret = 915 declare_symbol(SYM_CATS, id, aliasdatum, NULL, 916 &datum->s.value); 917 switch (ret) { 918 case -3:{ 919 yyerror("Out of memory!"); 920 goto bad_alias; 921 } 922 case -2:{ 923 yyerror 924 ("duplicate declaration of category aliases"); 925 goto bad_alias; 926 } 927 case -1:{ 928 yyerror 929 ("could not declare category aliases here"); 930 goto bad_alias; 931 } 932 case 0: 933 case 1:{ 934 break; 935 } 936 default:{ 937 assert(0); /* should never get here */ 938 } 939 } 940 } 941 942 return 0; 943 944 bad: 945 if (id) 946 free(id); 947 if (datum) { 948 cat_datum_destroy(datum); 949 free(datum); 950 } 951 return -1; 952 953 bad_alias: 954 if (id) 955 free(id); 956 if (aliasdatum) { 957 cat_datum_destroy(aliasdatum); 958 free(aliasdatum); 959 } 960 return -1; 961} 962 963static int clone_level(hashtab_key_t key, hashtab_datum_t datum, void *arg) 964{ 965 level_datum_t *levdatum = (level_datum_t *) datum; 966 mls_level_t *level = (mls_level_t *) arg, *newlevel; 967 968 if (levdatum->level == level) { 969 levdatum->defined = 1; 970 if (!levdatum->isalias) 971 return 0; 972 newlevel = (mls_level_t *) malloc(sizeof(mls_level_t)); 973 if (!newlevel) 974 return -1; 975 if (mls_level_cpy(newlevel, level)) { 976 free(newlevel); 977 return -1; 978 } 979 levdatum->level = newlevel; 980 } 981 return 0; 982} 983 984int define_level(void) 985{ 986 char *id; 987 level_datum_t *levdatum; 988 989 if (!mlspol) { 990 yyerror("level definition in non-MLS configuration"); 991 return -1; 992 } 993 994 if (pass == 2) { 995 while ((id = queue_remove(id_queue))) 996 free(id); 997 return 0; 998 } 999 1000 id = (char *)queue_remove(id_queue); 1001 if (!id) { 1002 yyerror("no level name for level definition?"); 1003 return -1; 1004 } 1005 levdatum = (level_datum_t *) hashtab_search(policydbp->p_levels.table, 1006 (hashtab_key_t) id); 1007 if (!levdatum) { 1008 yyerror2("unknown sensitivity %s used in level definition", id); 1009 free(id); 1010 return -1; 1011 } 1012 if (ebitmap_length(&levdatum->level->cat)) { 1013 yyerror2("sensitivity %s used in multiple level definitions", 1014 id); 1015 free(id); 1016 return -1; 1017 } 1018 free(id); 1019 1020 levdatum->defined = 1; 1021 1022 while ((id = queue_remove(id_queue))) { 1023 cat_datum_t *cdatum; 1024 int range_start, range_end, i; 1025 1026 if (id_has_dot(id)) { 1027 char *id_start = id; 1028 char *id_end = strchr(id, '.'); 1029 1030 *(id_end++) = '\0'; 1031 1032 cdatum = 1033 (cat_datum_t *) hashtab_search(policydbp->p_cats. 1034 table, 1035 (hashtab_key_t) 1036 id_start); 1037 if (!cdatum) { 1038 yyerror2("unknown category %s", id_start); 1039 free(id); 1040 return -1; 1041 } 1042 range_start = cdatum->s.value - 1; 1043 cdatum = 1044 (cat_datum_t *) hashtab_search(policydbp->p_cats. 1045 table, 1046 (hashtab_key_t) 1047 id_end); 1048 if (!cdatum) { 1049 yyerror2("unknown category %s", id_end); 1050 free(id); 1051 return -1; 1052 } 1053 range_end = cdatum->s.value - 1; 1054 1055 if (range_end < range_start) { 1056 yyerror2("category range is invalid"); 1057 free(id); 1058 return -1; 1059 } 1060 } else { 1061 cdatum = 1062 (cat_datum_t *) hashtab_search(policydbp->p_cats. 1063 table, 1064 (hashtab_key_t) id); 1065 range_start = range_end = cdatum->s.value - 1; 1066 } 1067 1068 for (i = range_start; i <= range_end; i++) { 1069 if (ebitmap_set_bit(&levdatum->level->cat, i, TRUE)) { 1070 yyerror("out of memory"); 1071 free(id); 1072 return -1; 1073 } 1074 } 1075 1076 free(id); 1077 } 1078 1079 if (hashtab_map 1080 (policydbp->p_levels.table, clone_level, levdatum->level)) { 1081 yyerror("out of memory"); 1082 return -1; 1083 } 1084 1085 return 0; 1086} 1087 1088int define_attrib(void) 1089{ 1090 if (pass == 2) { 1091 free(queue_remove(id_queue)); 1092 return 0; 1093 } 1094 1095 if (declare_type(TRUE, TRUE) == NULL) { 1096 return -1; 1097 } 1098 return 0; 1099} 1100 1101static int add_aliases_to_type(type_datum_t * type) 1102{ 1103 char *id; 1104 type_datum_t *aliasdatum = NULL; 1105 int ret; 1106 while ((id = queue_remove(id_queue))) { 1107 if (id_has_dot(id)) { 1108 free(id); 1109 yyerror 1110 ("type alias identifiers may not contain periods"); 1111 return -1; 1112 } 1113 aliasdatum = (type_datum_t *) malloc(sizeof(type_datum_t)); 1114 if (!aliasdatum) { 1115 free(id); 1116 yyerror("Out of memory!"); 1117 return -1; 1118 } 1119 memset(aliasdatum, 0, sizeof(type_datum_t)); 1120 aliasdatum->s.value = type->s.value; 1121 1122 ret = declare_symbol(SYM_TYPES, id, aliasdatum, 1123 NULL, &aliasdatum->s.value); 1124 switch (ret) { 1125 case -3:{ 1126 yyerror("Out of memory!"); 1127 goto cleanup; 1128 } 1129 case -2:{ 1130 yyerror2("duplicate declaration of alias %s", 1131 id); 1132 goto cleanup; 1133 } 1134 case -1:{ 1135 yyerror("could not declare alias here"); 1136 goto cleanup; 1137 } 1138 case 0: break; 1139 case 1:{ 1140 /* ret == 1 means the alias was required and therefore already 1141 * has a value. Set it up as an alias with a different primary. */ 1142 type_datum_destroy(aliasdatum); 1143 free(aliasdatum); 1144 1145 aliasdatum = hashtab_search(policydbp->symtab[SYM_TYPES].table, id); 1146 assert(aliasdatum); 1147 1148 aliasdatum->primary = type->s.value; 1149 aliasdatum->flavor = TYPE_ALIAS; 1150 1151 break; 1152 } 1153 default:{ 1154 assert(0); /* should never get here */ 1155 } 1156 } 1157 } 1158 return 0; 1159 cleanup: 1160 free(id); 1161 type_datum_destroy(aliasdatum); 1162 free(aliasdatum); 1163 return -1; 1164} 1165 1166int define_typealias(void) 1167{ 1168 char *id; 1169 type_datum_t *t; 1170 1171 if (pass == 2) { 1172 while ((id = queue_remove(id_queue))) 1173 free(id); 1174 return 0; 1175 } 1176 1177 id = (char *)queue_remove(id_queue); 1178 if (!id) { 1179 yyerror("no type name for typealias definition?"); 1180 return -1; 1181 } 1182 1183 if (!is_id_in_scope(SYM_TYPES, id)) { 1184 yyerror2("type %s is not within scope", id); 1185 free(id); 1186 return -1; 1187 } 1188 t = hashtab_search(policydbp->p_types.table, id); 1189 if (!t || t->flavor == TYPE_ATTRIB) { 1190 yyerror2("unknown type %s, or it was already declared as an " 1191 "attribute", id); 1192 free(id); 1193 return -1; 1194 } 1195 return add_aliases_to_type(t); 1196} 1197 1198int define_typeattribute(void) 1199{ 1200 char *id; 1201 type_datum_t *t, *attr; 1202 1203 if (pass == 2) { 1204 while ((id = queue_remove(id_queue))) 1205 free(id); 1206 return 0; 1207 } 1208 1209 id = (char *)queue_remove(id_queue); 1210 if (!id) { 1211 yyerror("no type name for typeattribute definition?"); 1212 return -1; 1213 } 1214 1215 if (!is_id_in_scope(SYM_TYPES, id)) { 1216 yyerror2("type %s is not within scope", id); 1217 free(id); 1218 return -1; 1219 } 1220 t = hashtab_search(policydbp->p_types.table, id); 1221 if (!t || t->flavor == TYPE_ATTRIB) { 1222 yyerror2("unknown type %s", id); 1223 free(id); 1224 return -1; 1225 } 1226 1227 while ((id = queue_remove(id_queue))) { 1228 if (!is_id_in_scope(SYM_TYPES, id)) { 1229 yyerror2("attribute %s is not within scope", id); 1230 free(id); 1231 return -1; 1232 } 1233 attr = hashtab_search(policydbp->p_types.table, id); 1234 if (!attr) { 1235 /* treat it as a fatal error */ 1236 yyerror2("attribute %s is not declared", id); 1237 free(id); 1238 return -1; 1239 } 1240 1241 if (attr->flavor != TYPE_ATTRIB) { 1242 yyerror2("%s is a type, not an attribute", id); 1243 free(id); 1244 return -1; 1245 } 1246 1247 if ((attr = get_local_type(id, attr->s.value, 1)) == NULL) { 1248 yyerror("Out of memory!"); 1249 return -1; 1250 } 1251 1252 if (ebitmap_set_bit(&attr->types, (t->s.value - 1), TRUE)) { 1253 yyerror("out of memory"); 1254 return -1; 1255 } 1256 } 1257 1258 return 0; 1259} 1260 1261static int define_typebounds_helper(char *bounds_id, char *type_id) 1262{ 1263 type_datum_t *bounds, *type; 1264 1265 if (!is_id_in_scope(SYM_TYPES, bounds_id)) { 1266 yyerror2("type %s is not within scope", bounds_id); 1267 return -1; 1268 } 1269 1270 bounds = hashtab_search(policydbp->p_types.table, bounds_id); 1271 if (!bounds || bounds->flavor == TYPE_ATTRIB) { 1272 yyerror2("hoge unknown type %s", bounds_id); 1273 return -1; 1274 } 1275 1276 if (!is_id_in_scope(SYM_TYPES, type_id)) { 1277 yyerror2("type %s is not within scope", type_id); 1278 return -1; 1279 } 1280 1281 type = hashtab_search(policydbp->p_types.table, type_id); 1282 if (!type || type->flavor == TYPE_ATTRIB) { 1283 yyerror2("type %s is not declared", type_id); 1284 return -1; 1285 } 1286 1287 if (type->flavor == TYPE_TYPE && !type->primary) { 1288 type = policydbp->type_val_to_struct[type->s.value - 1]; 1289 } else if (type->flavor == TYPE_ALIAS) { 1290 type = policydbp->type_val_to_struct[type->primary - 1]; 1291 } 1292 1293 if (!type->bounds) 1294 type->bounds = bounds->s.value; 1295 else if (type->bounds != bounds->s.value) { 1296 yyerror2("type %s has inconsistent master {%s,%s}", 1297 type_id, 1298 policydbp->p_type_val_to_name[type->bounds - 1], 1299 policydbp->p_type_val_to_name[bounds->s.value - 1]); 1300 return -1; 1301 } 1302 1303 return 0; 1304} 1305 1306int define_typebounds(void) 1307{ 1308 char *bounds, *id; 1309 1310 if (pass == 1) { 1311 while ((id = queue_remove(id_queue))) 1312 free(id); 1313 return 0; 1314 } 1315 1316 bounds = (char *) queue_remove(id_queue); 1317 if (!bounds) { 1318 yyerror("no type name for typebounds definition?"); 1319 return -1; 1320 } 1321 1322 while ((id = queue_remove(id_queue))) { 1323 if (define_typebounds_helper(bounds, id)) 1324 return -1; 1325 free(id); 1326 } 1327 free(bounds); 1328 1329 return 0; 1330} 1331 1332int define_type(int alias) 1333{ 1334 char *id; 1335 type_datum_t *datum, *attr; 1336 1337 if (pass == 2) { 1338 /* 1339 * If type name contains ".", we have to define boundary 1340 * relationship implicitly to keep compatibility with 1341 * old name based hierarchy. 1342 */ 1343 if ((id = queue_remove(id_queue))) { 1344 char *bounds, *delim; 1345 1346 if ((delim = strrchr(id, '.')) 1347 && (bounds = strdup(id))) { 1348 bounds[(size_t)(delim - id)] = '\0'; 1349 1350 if (define_typebounds_helper(bounds, id)) 1351 return -1; 1352 free(bounds); 1353 } 1354 free(id); 1355 } 1356 1357 if (alias) { 1358 while ((id = queue_remove(id_queue))) 1359 free(id); 1360 } 1361 1362 while ((id = queue_remove(id_queue))) 1363 free(id); 1364 return 0; 1365 } 1366 1367 if ((datum = declare_type(TRUE, FALSE)) == NULL) { 1368 return -1; 1369 } 1370 1371 if (alias) { 1372 if (add_aliases_to_type(datum) == -1) { 1373 return -1; 1374 } 1375 } 1376 1377 while ((id = queue_remove(id_queue))) { 1378 if (!is_id_in_scope(SYM_TYPES, id)) { 1379 yyerror2("attribute %s is not within scope", id); 1380 free(id); 1381 return -1; 1382 } 1383 attr = hashtab_search(policydbp->p_types.table, id); 1384 if (!attr) { 1385 /* treat it as a fatal error */ 1386 yyerror2("attribute %s is not declared", id); 1387 return -1; 1388 } 1389 1390 if (attr->flavor != TYPE_ATTRIB) { 1391 yyerror2("%s is a type, not an attribute", id); 1392 return -1; 1393 } 1394 1395 if ((attr = get_local_type(id, attr->s.value, 1)) == NULL) { 1396 yyerror("Out of memory!"); 1397 return -1; 1398 } 1399 1400 if (ebitmap_set_bit(&attr->types, datum->s.value - 1, TRUE)) { 1401 yyerror("Out of memory"); 1402 return -1; 1403 } 1404 } 1405 1406 return 0; 1407} 1408 1409struct val_to_name { 1410 unsigned int val; 1411 char *name; 1412}; 1413 1414/* Adds a type, given by its textual name, to a typeset. If *add is 1415 0, then add the type to the negative set; otherwise if *add is 1 1416 then add it to the positive side. */ 1417static int set_types(type_set_t * set, char *id, int *add, char starallowed) 1418{ 1419 type_datum_t *t; 1420 1421 if (strcmp(id, "*") == 0) { 1422 if (!starallowed) { 1423 yyerror("* not allowed in this type of rule"); 1424 return -1; 1425 } 1426 /* set TYPE_STAR flag */ 1427 set->flags = TYPE_STAR; 1428 free(id); 1429 *add = 1; 1430 return 0; 1431 } 1432 1433 if (strcmp(id, "~") == 0) { 1434 if (!starallowed) { 1435 yyerror("~ not allowed in this type of rule"); 1436 return -1; 1437 } 1438 /* complement the set */ 1439 set->flags = TYPE_COMP; 1440 free(id); 1441 *add = 1; 1442 return 0; 1443 } 1444 1445 if (strcmp(id, "-") == 0) { 1446 *add = 0; 1447 free(id); 1448 return 0; 1449 } 1450 1451 if (!is_id_in_scope(SYM_TYPES, id)) { 1452 yyerror2("type %s is not within scope", id); 1453 free(id); 1454 return -1; 1455 } 1456 t = hashtab_search(policydbp->p_types.table, id); 1457 if (!t) { 1458 yyerror2("unknown type %s", id); 1459 free(id); 1460 return -1; 1461 } 1462 1463 if (*add == 0) { 1464 if (ebitmap_set_bit(&set->negset, t->s.value - 1, TRUE)) 1465 goto oom; 1466 } else { 1467 if (ebitmap_set_bit(&set->types, t->s.value - 1, TRUE)) 1468 goto oom; 1469 } 1470 free(id); 1471 *add = 1; 1472 return 0; 1473 oom: 1474 yyerror("Out of memory"); 1475 free(id); 1476 return -1; 1477} 1478 1479int define_compute_type_helper(int which, avrule_t ** rule) 1480{ 1481 char *id; 1482 type_datum_t *datum; 1483 ebitmap_t tclasses; 1484 ebitmap_node_t *node; 1485 avrule_t *avrule; 1486 class_perm_node_t *perm; 1487 int i, add = 1; 1488 1489 avrule = malloc(sizeof(avrule_t)); 1490 if (!avrule) { 1491 yyerror("out of memory"); 1492 return -1; 1493 } 1494 avrule_init(avrule); 1495 avrule->specified = which; 1496 avrule->line = policydb_lineno; 1497 1498 while ((id = queue_remove(id_queue))) { 1499 if (set_types(&avrule->stypes, id, &add, 0)) 1500 goto bad; 1501 } 1502 add = 1; 1503 while ((id = queue_remove(id_queue))) { 1504 if (set_types(&avrule->ttypes, id, &add, 0)) 1505 goto bad; 1506 } 1507 1508 ebitmap_init(&tclasses); 1509 if (read_classes(&tclasses)) 1510 goto bad; 1511 1512 id = (char *)queue_remove(id_queue); 1513 if (!id) { 1514 yyerror("no newtype?"); 1515 goto bad; 1516 } 1517 if (!is_id_in_scope(SYM_TYPES, id)) { 1518 yyerror2("type %s is not within scope", id); 1519 free(id); 1520 goto bad; 1521 } 1522 datum = (type_datum_t *) hashtab_search(policydbp->p_types.table, 1523 (hashtab_key_t) id); 1524 if (!datum || datum->flavor == TYPE_ATTRIB) { 1525 yyerror2("unknown type %s", id); 1526 goto bad; 1527 } 1528 1529 ebitmap_for_each_bit(&tclasses, node, i) { 1530 if (ebitmap_node_get_bit(node, i)) { 1531 perm = malloc(sizeof(class_perm_node_t)); 1532 if (!perm) { 1533 yyerror("out of memory"); 1534 goto bad; 1535 } 1536 class_perm_node_init(perm); 1537 perm->class = i + 1; 1538 perm->data = datum->s.value; 1539 perm->next = avrule->perms; 1540 avrule->perms = perm; 1541 } 1542 } 1543 ebitmap_destroy(&tclasses); 1544 1545 *rule = avrule; 1546 return 0; 1547 1548 bad: 1549 avrule_destroy(avrule); 1550 free(avrule); 1551 return -1; 1552} 1553 1554int define_compute_type(int which) 1555{ 1556 char *id; 1557 avrule_t *avrule; 1558 1559 if (pass == 1) { 1560 while ((id = queue_remove(id_queue))) 1561 free(id); 1562 while ((id = queue_remove(id_queue))) 1563 free(id); 1564 while ((id = queue_remove(id_queue))) 1565 free(id); 1566 id = queue_remove(id_queue); 1567 free(id); 1568 return 0; 1569 } 1570 1571 if (define_compute_type_helper(which, &avrule)) 1572 return -1; 1573 1574 append_avrule(avrule); 1575 return 0; 1576} 1577 1578avrule_t *define_cond_compute_type(int which) 1579{ 1580 char *id; 1581 avrule_t *avrule; 1582 1583 if (pass == 1) { 1584 while ((id = queue_remove(id_queue))) 1585 free(id); 1586 while ((id = queue_remove(id_queue))) 1587 free(id); 1588 while ((id = queue_remove(id_queue))) 1589 free(id); 1590 id = queue_remove(id_queue); 1591 free(id); 1592 return (avrule_t *) 1; 1593 } 1594 1595 if (define_compute_type_helper(which, &avrule)) 1596 return COND_ERR; 1597 1598 return avrule; 1599} 1600 1601int define_bool_tunable(int is_tunable) 1602{ 1603 char *id, *bool_value; 1604 cond_bool_datum_t *datum; 1605 int ret; 1606 uint32_t value; 1607 1608 if (pass == 2) { 1609 while ((id = queue_remove(id_queue))) 1610 free(id); 1611 return 0; 1612 } 1613 1614 id = (char *)queue_remove(id_queue); 1615 if (!id) { 1616 yyerror("no identifier for bool definition?"); 1617 return -1; 1618 } 1619 if (id_has_dot(id)) { 1620 free(id); 1621 yyerror("boolean identifiers may not contain periods"); 1622 return -1; 1623 } 1624 datum = (cond_bool_datum_t *) malloc(sizeof(cond_bool_datum_t)); 1625 if (!datum) { 1626 yyerror("out of memory"); 1627 free(id); 1628 return -1; 1629 } 1630 memset(datum, 0, sizeof(cond_bool_datum_t)); 1631 if (is_tunable) 1632 datum->flags |= COND_BOOL_FLAGS_TUNABLE; 1633 ret = declare_symbol(SYM_BOOLS, id, datum, &value, &value); 1634 switch (ret) { 1635 case -3:{ 1636 yyerror("Out of memory!"); 1637 goto cleanup; 1638 } 1639 case -2:{ 1640 yyerror2("duplicate declaration of boolean %s", id); 1641 goto cleanup; 1642 } 1643 case -1:{ 1644 yyerror("could not declare boolean here"); 1645 goto cleanup; 1646 } 1647 case 0: 1648 case 1:{ 1649 break; 1650 } 1651 default:{ 1652 assert(0); /* should never get here */ 1653 } 1654 } 1655 datum->s.value = value; 1656 1657 bool_value = (char *)queue_remove(id_queue); 1658 if (!bool_value) { 1659 yyerror("no default value for bool definition?"); 1660 free(id); 1661 return -1; 1662 } 1663 1664 datum->state = (int)(bool_value[0] == 'T') ? 1 : 0; 1665 return 0; 1666 cleanup: 1667 cond_destroy_bool(id, datum, NULL); 1668 return -1; 1669} 1670 1671avrule_t *define_cond_pol_list(avrule_t * avlist, avrule_t * sl) 1672{ 1673 if (pass == 1) { 1674 /* return something so we get through pass 1 */ 1675 return (avrule_t *) 1; 1676 } 1677 1678 if (sl == NULL) { 1679 /* This is a require block, return previous list */ 1680 return avlist; 1681 } 1682 1683 /* prepend the new avlist to the pre-existing one */ 1684 sl->next = avlist; 1685 return sl; 1686} 1687 1688int define_te_avtab_helper(int which, avrule_t ** rule) 1689{ 1690 char *id; 1691 class_datum_t *cladatum; 1692 perm_datum_t *perdatum = NULL; 1693 class_perm_node_t *perms, *tail = NULL, *cur_perms = NULL; 1694 ebitmap_t tclasses; 1695 ebitmap_node_t *node; 1696 avrule_t *avrule; 1697 unsigned int i; 1698 int add = 1, ret = 0; 1699 int suppress = 0; 1700 1701 avrule = (avrule_t *) malloc(sizeof(avrule_t)); 1702 if (!avrule) { 1703 yyerror("memory error"); 1704 ret = -1; 1705 goto out; 1706 } 1707 avrule_init(avrule); 1708 avrule->specified = which; 1709 avrule->line = policydb_lineno; 1710 1711 while ((id = queue_remove(id_queue))) { 1712 if (set_types 1713 (&avrule->stypes, id, &add, 1714 which == AVRULE_NEVERALLOW ? 1 : 0)) { 1715 ret = -1; 1716 goto out; 1717 } 1718 } 1719 add = 1; 1720 while ((id = queue_remove(id_queue))) { 1721 if (strcmp(id, "self") == 0) { 1722 free(id); 1723 avrule->flags |= RULE_SELF; 1724 continue; 1725 } 1726 if (set_types 1727 (&avrule->ttypes, id, &add, 1728 which == AVRULE_NEVERALLOW ? 1 : 0)) { 1729 ret = -1; 1730 goto out; 1731 } 1732 } 1733 1734 ebitmap_init(&tclasses); 1735 ret = read_classes(&tclasses); 1736 if (ret) 1737 goto out; 1738 1739 perms = NULL; 1740 ebitmap_for_each_bit(&tclasses, node, i) { 1741 if (!ebitmap_node_get_bit(node, i)) 1742 continue; 1743 cur_perms = 1744 (class_perm_node_t *) malloc(sizeof(class_perm_node_t)); 1745 if (!cur_perms) { 1746 yyerror("out of memory"); 1747 ret = -1; 1748 goto out; 1749 } 1750 class_perm_node_init(cur_perms); 1751 cur_perms->class = i + 1; 1752 if (!perms) 1753 perms = cur_perms; 1754 if (tail) 1755 tail->next = cur_perms; 1756 tail = cur_perms; 1757 } 1758 1759 while ((id = queue_remove(id_queue))) { 1760 cur_perms = perms; 1761 ebitmap_for_each_bit(&tclasses, node, i) { 1762 if (!ebitmap_node_get_bit(node, i)) 1763 continue; 1764 cladatum = policydbp->class_val_to_struct[i]; 1765 1766 if (strcmp(id, "*") == 0) { 1767 /* set all permissions in the class */ 1768 cur_perms->data = ~0U; 1769 goto next; 1770 } 1771 1772 if (strcmp(id, "~") == 0) { 1773 /* complement the set */ 1774 if (which == AVRULE_DONTAUDIT) 1775 yywarn("dontaudit rule with a ~?"); 1776 cur_perms->data = ~cur_perms->data; 1777 goto next; 1778 } 1779 1780 perdatum = 1781 hashtab_search(cladatum->permissions.table, id); 1782 if (!perdatum) { 1783 if (cladatum->comdatum) { 1784 perdatum = 1785 hashtab_search(cladatum->comdatum-> 1786 permissions.table, 1787 id); 1788 } 1789 } 1790 if (!perdatum) { 1791 if (!suppress) 1792 yyerror2("permission %s is not defined" 1793 " for class %s", id, 1794 policydbp->p_class_val_to_name[i]); 1795 continue; 1796 } else 1797 if (!is_perm_in_scope 1798 (id, policydbp->p_class_val_to_name[i])) { 1799 if (!suppress) { 1800 yyerror2("permission %s of class %s is" 1801 " not within scope", id, 1802 policydbp->p_class_val_to_name[i]); 1803 } 1804 continue; 1805 } else { 1806 cur_perms->data |= 1U << (perdatum->s.value - 1); 1807 } 1808 next: 1809 cur_perms = cur_perms->next; 1810 } 1811 1812 free(id); 1813 } 1814 1815 ebitmap_destroy(&tclasses); 1816 1817 avrule->perms = perms; 1818 *rule = avrule; 1819 1820 out: 1821 return ret; 1822 1823} 1824 1825avrule_t *define_cond_te_avtab(int which) 1826{ 1827 char *id; 1828 avrule_t *avrule; 1829 int i; 1830 1831 if (pass == 1) { 1832 for (i = 0; i < 4; i++) { 1833 while ((id = queue_remove(id_queue))) 1834 free(id); 1835 } 1836 return (avrule_t *) 1; /* any non-NULL value */ 1837 } 1838 1839 if (define_te_avtab_helper(which, &avrule)) 1840 return COND_ERR; 1841 1842 return avrule; 1843} 1844 1845int define_te_avtab(int which) 1846{ 1847 char *id; 1848 avrule_t *avrule; 1849 int i; 1850 1851 if (pass == 1) { 1852 for (i = 0; i < 4; i++) { 1853 while ((id = queue_remove(id_queue))) 1854 free(id); 1855 } 1856 return 0; 1857 } 1858 1859 if (define_te_avtab_helper(which, &avrule)) 1860 return -1; 1861 1862 /* append this avrule to the end of the current rules list */ 1863 append_avrule(avrule); 1864 return 0; 1865} 1866 1867/* The role-types rule is no longer used to declare regular role or 1868 * role attribute, but solely aimed for declaring role-types associations. 1869 */ 1870int define_role_types(void) 1871{ 1872 role_datum_t *role; 1873 char *id; 1874 int add = 1; 1875 1876 if (pass == 1) { 1877 while ((id = queue_remove(id_queue))) 1878 free(id); 1879 return 0; 1880 } 1881 1882 id = (char *)queue_remove(id_queue); 1883 if (!id) { 1884 yyerror("no role name for role-types rule?"); 1885 return -1; 1886 } 1887 1888 if (!is_id_in_scope(SYM_ROLES, id)) { 1889 yyerror2("role %s is not within scope", id); 1890 free(id); 1891 return -1; 1892 } 1893 1894 role = hashtab_search(policydbp->p_roles.table, id); 1895 if (!role) { 1896 yyerror2("unknown role %s", id); 1897 free(id); 1898 return -1; 1899 } 1900 1901 while ((id = queue_remove(id_queue))) { 1902 if (set_types(&role->types, id, &add, 0)) 1903 return -1; 1904 } 1905 1906 return 0; 1907} 1908 1909int define_attrib_role(void) 1910{ 1911 if (pass == 2) { 1912 free(queue_remove(id_queue)); 1913 return 0; 1914 } 1915 1916 /* Declare a role attribute */ 1917 if (declare_role(TRUE) == NULL) 1918 return -1; 1919 1920 return 0; 1921} 1922 1923int define_role_attr(void) 1924{ 1925 char *id; 1926 role_datum_t *r, *attr; 1927 1928 if (pass == 2) { 1929 while ((id = queue_remove(id_queue))) 1930 free(id); 1931 return 0; 1932 } 1933 1934 /* Declare a regular role */ 1935 if ((r = declare_role(FALSE)) == NULL) 1936 return -1; 1937 1938 while ((id = queue_remove(id_queue))) { 1939 if (!is_id_in_scope(SYM_ROLES, id)) { 1940 yyerror2("attribute %s is not within scope", id); 1941 free(id); 1942 return -1; 1943 } 1944 attr = hashtab_search(policydbp->p_roles.table, id); 1945 if (!attr) { 1946 /* treat it as a fatal error */ 1947 yyerror2("role attribute %s is not declared", id); 1948 free(id); 1949 return -1; 1950 } 1951 1952 if (attr->flavor != ROLE_ATTRIB) { 1953 yyerror2("%s is a regular role, not an attribute", id); 1954 free(id); 1955 return -1; 1956 } 1957 1958 if ((attr = get_local_role(id, attr->s.value, 1)) == NULL) { 1959 yyerror("Out of memory!"); 1960 return -1; 1961 } 1962 1963 if (ebitmap_set_bit(&attr->roles, (r->s.value - 1), TRUE)) { 1964 yyerror("out of memory"); 1965 return -1; 1966 } 1967 } 1968 1969 return 0; 1970} 1971 1972int define_roleattribute(void) 1973{ 1974 char *id; 1975 role_datum_t *r, *attr; 1976 1977 if (pass == 2) { 1978 while ((id = queue_remove(id_queue))) 1979 free(id); 1980 return 0; 1981 } 1982 1983 id = (char *)queue_remove(id_queue); 1984 if (!id) { 1985 yyerror("no role name for roleattribute definition?"); 1986 return -1; 1987 } 1988 1989 if (!is_id_in_scope(SYM_ROLES, id)) { 1990 yyerror2("role %s is not within scope", id); 1991 free(id); 1992 return -1; 1993 } 1994 r = hashtab_search(policydbp->p_roles.table, id); 1995 /* We support adding one role attribute into another */ 1996 if (!r) { 1997 yyerror2("unknown role %s", id); 1998 free(id); 1999 return -1; 2000 } 2001 2002 while ((id = queue_remove(id_queue))) { 2003 if (!is_id_in_scope(SYM_ROLES, id)) { 2004 yyerror2("attribute %s is not within scope", id); 2005 free(id); 2006 return -1; 2007 } 2008 attr = hashtab_search(policydbp->p_roles.table, id); 2009 if (!attr) { 2010 /* treat it as a fatal error */ 2011 yyerror2("role attribute %s is not declared", id); 2012 free(id); 2013 return -1; 2014 } 2015 2016 if (attr->flavor != ROLE_ATTRIB) { 2017 yyerror2("%s is a regular role, not an attribute", id); 2018 free(id); 2019 return -1; 2020 } 2021 2022 if ((attr = get_local_role(id, attr->s.value, 1)) == NULL) { 2023 yyerror("Out of memory!"); 2024 return -1; 2025 } 2026 2027 if (ebitmap_set_bit(&attr->roles, (r->s.value - 1), TRUE)) { 2028 yyerror("out of memory"); 2029 return -1; 2030 } 2031 } 2032 2033 return 0; 2034} 2035 2036role_datum_t *merge_roles_dom(role_datum_t * r1, role_datum_t * r2) 2037{ 2038 role_datum_t *new; 2039 2040 if (pass == 1) { 2041 return (role_datum_t *) 1; /* any non-NULL value */ 2042 } 2043 2044 new = malloc(sizeof(role_datum_t)); 2045 if (!new) { 2046 yyerror("out of memory"); 2047 return NULL; 2048 } 2049 memset(new, 0, sizeof(role_datum_t)); 2050 new->s.value = 0; /* temporary role */ 2051 if (ebitmap_or(&new->dominates, &r1->dominates, &r2->dominates)) { 2052 yyerror("out of memory"); 2053 free(new); 2054 return NULL; 2055 } 2056 if (ebitmap_or(&new->types.types, &r1->types.types, &r2->types.types)) { 2057 yyerror("out of memory"); 2058 free(new); 2059 return NULL; 2060 } 2061 if (!r1->s.value) { 2062 /* free intermediate result */ 2063 type_set_destroy(&r1->types); 2064 ebitmap_destroy(&r1->dominates); 2065 free(r1); 2066 } 2067 if (!r2->s.value) { 2068 /* free intermediate result */ 2069 yyerror("right hand role is temporary?"); 2070 type_set_destroy(&r2->types); 2071 ebitmap_destroy(&r2->dominates); 2072 free(r2); 2073 } 2074 return new; 2075} 2076 2077/* This function eliminates the ordering dependency of role dominance rule */ 2078static int dominate_role_recheck(hashtab_key_t key, hashtab_datum_t datum, 2079 void *arg) 2080{ 2081 role_datum_t *rdp = (role_datum_t *) arg; 2082 role_datum_t *rdatum = (role_datum_t *) datum; 2083 ebitmap_node_t *node; 2084 int i; 2085 2086 /* Don't bother to process against self role */ 2087 if (rdatum->s.value == rdp->s.value) 2088 return 0; 2089 2090 /* If a dominating role found */ 2091 if (ebitmap_get_bit(&(rdatum->dominates), rdp->s.value - 1)) { 2092 ebitmap_t types; 2093 ebitmap_init(&types); 2094 if (type_set_expand(&rdp->types, &types, policydbp, 1)) { 2095 ebitmap_destroy(&types); 2096 return -1; 2097 } 2098 /* raise types and dominates from dominated role */ 2099 ebitmap_for_each_bit(&rdp->dominates, node, i) { 2100 if (ebitmap_node_get_bit(node, i)) 2101 if (ebitmap_set_bit 2102 (&rdatum->dominates, i, TRUE)) 2103 goto oom; 2104 } 2105 ebitmap_for_each_bit(&types, node, i) { 2106 if (ebitmap_node_get_bit(node, i)) 2107 if (ebitmap_set_bit 2108 (&rdatum->types.types, i, TRUE)) 2109 goto oom; 2110 } 2111 ebitmap_destroy(&types); 2112 } 2113 2114 /* go through all the roles */ 2115 return 0; 2116 oom: 2117 yyerror("Out of memory"); 2118 return -1; 2119} 2120 2121role_datum_t *define_role_dom(role_datum_t * r) 2122{ 2123 role_datum_t *role; 2124 char *role_id; 2125 ebitmap_node_t *node; 2126 unsigned int i; 2127 int ret; 2128 2129 if (pass == 1) { 2130 role_id = queue_remove(id_queue); 2131 free(role_id); 2132 return (role_datum_t *) 1; /* any non-NULL value */ 2133 } 2134 2135 yywarn("Role dominance has been deprecated"); 2136 2137 role_id = queue_remove(id_queue); 2138 if (!is_id_in_scope(SYM_ROLES, role_id)) { 2139 yyerror2("role %s is not within scope", role_id); 2140 free(role_id); 2141 return NULL; 2142 } 2143 role = (role_datum_t *) hashtab_search(policydbp->p_roles.table, 2144 role_id); 2145 if (!role) { 2146 role = (role_datum_t *) malloc(sizeof(role_datum_t)); 2147 if (!role) { 2148 yyerror("out of memory"); 2149 free(role_id); 2150 return NULL; 2151 } 2152 memset(role, 0, sizeof(role_datum_t)); 2153 ret = 2154 declare_symbol(SYM_ROLES, (hashtab_key_t) role_id, 2155 (hashtab_datum_t) role, &role->s.value, 2156 &role->s.value); 2157 switch (ret) { 2158 case -3:{ 2159 yyerror("Out of memory!"); 2160 goto cleanup; 2161 } 2162 case -2:{ 2163 yyerror2("duplicate declaration of role %s", 2164 role_id); 2165 goto cleanup; 2166 } 2167 case -1:{ 2168 yyerror("could not declare role here"); 2169 goto cleanup; 2170 } 2171 case 0: 2172 case 1:{ 2173 break; 2174 } 2175 default:{ 2176 assert(0); /* should never get here */ 2177 } 2178 } 2179 if (ebitmap_set_bit(&role->dominates, role->s.value - 1, TRUE)) { 2180 yyerror("Out of memory!"); 2181 goto cleanup; 2182 } 2183 } 2184 if (r) { 2185 ebitmap_t types; 2186 ebitmap_init(&types); 2187 ebitmap_for_each_bit(&r->dominates, node, i) { 2188 if (ebitmap_node_get_bit(node, i)) 2189 if (ebitmap_set_bit(&role->dominates, i, TRUE)) 2190 goto oom; 2191 } 2192 if (type_set_expand(&r->types, &types, policydbp, 1)) { 2193 ebitmap_destroy(&types); 2194 return NULL; 2195 } 2196 ebitmap_for_each_bit(&types, node, i) { 2197 if (ebitmap_node_get_bit(node, i)) 2198 if (ebitmap_set_bit 2199 (&role->types.types, i, TRUE)) 2200 goto oom; 2201 } 2202 ebitmap_destroy(&types); 2203 if (!r->s.value) { 2204 /* free intermediate result */ 2205 type_set_destroy(&r->types); 2206 ebitmap_destroy(&r->dominates); 2207 free(r); 2208 } 2209 /* 2210 * Now go through all the roles and escalate this role's 2211 * dominates and types if a role dominates this role. 2212 */ 2213 hashtab_map(policydbp->p_roles.table, 2214 dominate_role_recheck, role); 2215 } 2216 return role; 2217 cleanup: 2218 free(role_id); 2219 role_datum_destroy(role); 2220 free(role); 2221 return NULL; 2222 oom: 2223 yyerror("Out of memory"); 2224 goto cleanup; 2225} 2226 2227static int role_val_to_name_helper(hashtab_key_t key, hashtab_datum_t datum, 2228 void *p) 2229{ 2230 struct val_to_name *v = p; 2231 role_datum_t *roldatum; 2232 2233 roldatum = (role_datum_t *) datum; 2234 2235 if (v->val == roldatum->s.value) { 2236 v->name = key; 2237 return 1; 2238 } 2239 2240 return 0; 2241} 2242 2243static char *role_val_to_name(unsigned int val) 2244{ 2245 struct val_to_name v; 2246 int rc; 2247 2248 v.val = val; 2249 rc = hashtab_map(policydbp->p_roles.table, role_val_to_name_helper, &v); 2250 if (rc) 2251 return v.name; 2252 return NULL; 2253} 2254 2255static int set_roles(role_set_t * set, char *id) 2256{ 2257 role_datum_t *r; 2258 2259 if (strcmp(id, "*") == 0) { 2260 free(id); 2261 yyerror("* is not allowed for role sets"); 2262 return -1; 2263 } 2264 2265 if (strcmp(id, "~") == 0) { 2266 free(id); 2267 yyerror("~ is not allowed for role sets"); 2268 return -1; 2269 } 2270 if (!is_id_in_scope(SYM_ROLES, id)) { 2271 yyerror2("role %s is not within scope", id); 2272 free(id); 2273 return -1; 2274 } 2275 r = hashtab_search(policydbp->p_roles.table, id); 2276 if (!r) { 2277 yyerror2("unknown role %s", id); 2278 free(id); 2279 return -1; 2280 } 2281 2282 if (ebitmap_set_bit(&set->roles, r->s.value - 1, TRUE)) { 2283 yyerror("out of memory"); 2284 free(id); 2285 return -1; 2286 } 2287 free(id); 2288 return 0; 2289} 2290 2291int define_role_trans(int class_specified) 2292{ 2293 char *id; 2294 role_datum_t *role; 2295 role_set_t roles; 2296 type_set_t types; 2297 class_datum_t *cladatum; 2298 ebitmap_t e_types, e_roles, e_classes; 2299 ebitmap_node_t *tnode, *rnode, *cnode; 2300 struct role_trans *tr = NULL; 2301 struct role_trans_rule *rule = NULL; 2302 unsigned int i, j, k; 2303 int add = 1; 2304 2305 if (pass == 1) { 2306 while ((id = queue_remove(id_queue))) 2307 free(id); 2308 while ((id = queue_remove(id_queue))) 2309 free(id); 2310 if (class_specified) 2311 while ((id = queue_remove(id_queue))) 2312 free(id); 2313 id = queue_remove(id_queue); 2314 free(id); 2315 return 0; 2316 } 2317 2318 role_set_init(&roles); 2319 ebitmap_init(&e_roles); 2320 type_set_init(&types); 2321 ebitmap_init(&e_types); 2322 ebitmap_init(&e_classes); 2323 2324 while ((id = queue_remove(id_queue))) { 2325 if (set_roles(&roles, id)) 2326 return -1; 2327 } 2328 add = 1; 2329 while ((id = queue_remove(id_queue))) { 2330 if (set_types(&types, id, &add, 0)) 2331 return -1; 2332 } 2333 2334 if (class_specified) { 2335 if (read_classes(&e_classes)) 2336 return -1; 2337 } else { 2338 cladatum = hashtab_search(policydbp->p_classes.table, 2339 "process"); 2340 if (!cladatum) { 2341 yyerror2("could not find process class for " 2342 "legacy role_transition statement"); 2343 return -1; 2344 } 2345 2346 if (ebitmap_set_bit(&e_classes, cladatum->s.value - 1, TRUE)) { 2347 yyerror("out of memory"); 2348 return -1; 2349 } 2350 } 2351 2352 id = (char *)queue_remove(id_queue); 2353 if (!id) { 2354 yyerror("no new role in transition definition?"); 2355 goto bad; 2356 } 2357 if (!is_id_in_scope(SYM_ROLES, id)) { 2358 yyerror2("role %s is not within scope", id); 2359 free(id); 2360 goto bad; 2361 } 2362 role = hashtab_search(policydbp->p_roles.table, id); 2363 if (!role) { 2364 yyerror2("unknown role %s used in transition definition", id); 2365 goto bad; 2366 } 2367 2368 if (role->flavor != ROLE_ROLE) { 2369 yyerror2("the new role %s must be a regular role", id); 2370 goto bad; 2371 } 2372 2373 /* This ebitmap business is just to ensure that there are not conflicting role_trans rules */ 2374 if (role_set_expand(&roles, &e_roles, policydbp, NULL, NULL)) 2375 goto bad; 2376 2377 if (type_set_expand(&types, &e_types, policydbp, 1)) 2378 goto bad; 2379 2380 ebitmap_for_each_bit(&e_roles, rnode, i) { 2381 if (!ebitmap_node_get_bit(rnode, i)) 2382 continue; 2383 ebitmap_for_each_bit(&e_types, tnode, j) { 2384 if (!ebitmap_node_get_bit(tnode, j)) 2385 continue; 2386 ebitmap_for_each_bit(&e_classes, cnode, k) { 2387 if (!ebitmap_node_get_bit(cnode, k)) 2388 continue; 2389 for (tr = policydbp->role_tr; tr; 2390 tr = tr->next) { 2391 if (tr->role == (i + 1) && 2392 tr->type == (j + 1) && 2393 tr->tclass == (k + 1)) { 2394 yyerror2("duplicate role " 2395 "transition for " 2396 "(%s,%s,%s)", 2397 role_val_to_name(i+1), 2398 policydbp->p_type_val_to_name[j], 2399 policydbp->p_class_val_to_name[k]); 2400 goto bad; 2401 } 2402 } 2403 2404 tr = malloc(sizeof(struct role_trans)); 2405 if (!tr) { 2406 yyerror("out of memory"); 2407 return -1; 2408 } 2409 memset(tr, 0, sizeof(struct role_trans)); 2410 tr->role = i + 1; 2411 tr->type = j + 1; 2412 tr->tclass = k + 1; 2413 tr->new_role = role->s.value; 2414 tr->next = policydbp->role_tr; 2415 policydbp->role_tr = tr; 2416 } 2417 } 2418 } 2419 /* Now add the real rule */ 2420 rule = malloc(sizeof(struct role_trans_rule)); 2421 if (!rule) { 2422 yyerror("out of memory"); 2423 return -1; 2424 } 2425 memset(rule, 0, sizeof(struct role_trans_rule)); 2426 rule->roles = roles; 2427 rule->types = types; 2428 rule->classes = e_classes; 2429 rule->new_role = role->s.value; 2430 2431 append_role_trans(rule); 2432 2433 ebitmap_destroy(&e_roles); 2434 ebitmap_destroy(&e_types); 2435 2436 return 0; 2437 2438 bad: 2439 return -1; 2440} 2441 2442int define_role_allow(void) 2443{ 2444 char *id; 2445 struct role_allow_rule *ra = 0; 2446 2447 if (pass == 1) { 2448 while ((id = queue_remove(id_queue))) 2449 free(id); 2450 while ((id = queue_remove(id_queue))) 2451 free(id); 2452 return 0; 2453 } 2454 2455 ra = malloc(sizeof(role_allow_rule_t)); 2456 if (!ra) { 2457 yyerror("out of memory"); 2458 return -1; 2459 } 2460 role_allow_rule_init(ra); 2461 2462 while ((id = queue_remove(id_queue))) { 2463 if (set_roles(&ra->roles, id)) { 2464 free(ra); 2465 return -1; 2466 } 2467 } 2468 2469 while ((id = queue_remove(id_queue))) { 2470 if (set_roles(&ra->new_roles, id)) { 2471 free(ra); 2472 return -1; 2473 } 2474 } 2475 2476 append_role_allow(ra); 2477 return 0; 2478} 2479 2480avrule_t *define_cond_filename_trans(void) 2481{ 2482 yyerror("type transitions with a filename not allowed inside " 2483 "conditionals\n"); 2484 return COND_ERR; 2485} 2486 2487int define_filename_trans(void) 2488{ 2489 char *id, *name = NULL; 2490 type_set_t stypes, ttypes; 2491 ebitmap_t e_stypes, e_ttypes; 2492 ebitmap_t e_tclasses; 2493 ebitmap_node_t *snode, *tnode, *cnode; 2494 filename_trans_t *ft; 2495 filename_trans_rule_t *ftr; 2496 type_datum_t *typdatum; 2497 uint32_t otype; 2498 unsigned int c, s, t; 2499 int add; 2500 2501 if (pass == 1) { 2502 /* stype */ 2503 while ((id = queue_remove(id_queue))) 2504 free(id); 2505 /* ttype */ 2506 while ((id = queue_remove(id_queue))) 2507 free(id); 2508 /* tclass */ 2509 while ((id = queue_remove(id_queue))) 2510 free(id); 2511 /* otype */ 2512 id = queue_remove(id_queue); 2513 free(id); 2514 /* name */ 2515 id = queue_remove(id_queue); 2516 free(id); 2517 return 0; 2518 } 2519 2520 2521 add = 1; 2522 type_set_init(&stypes); 2523 while ((id = queue_remove(id_queue))) { 2524 if (set_types(&stypes, id, &add, 0)) 2525 goto bad; 2526 } 2527 2528 add =1; 2529 type_set_init(&ttypes); 2530 while ((id = queue_remove(id_queue))) { 2531 if (set_types(&ttypes, id, &add, 0)) 2532 goto bad; 2533 } 2534 2535 ebitmap_init(&e_tclasses); 2536 if (read_classes(&e_tclasses)) 2537 goto bad; 2538 2539 id = (char *)queue_remove(id_queue); 2540 if (!id) { 2541 yyerror("no otype in transition definition?"); 2542 goto bad; 2543 } 2544 if (!is_id_in_scope(SYM_TYPES, id)) { 2545 yyerror2("type %s is not within scope", id); 2546 free(id); 2547 goto bad; 2548 } 2549 typdatum = hashtab_search(policydbp->p_types.table, id); 2550 if (!typdatum) { 2551 yyerror2("unknown type %s used in transition definition", id); 2552 goto bad; 2553 } 2554 free(id); 2555 otype = typdatum->s.value; 2556 2557 name = queue_remove(id_queue); 2558 if (!name) { 2559 yyerror("no pathname specified in filename_trans definition?"); 2560 goto bad; 2561 } 2562 2563 /* We expand the class set into seperate rules. We expand the types 2564 * just to make sure there are not duplicates. They will get turned 2565 * into seperate rules later */ 2566 ebitmap_init(&e_stypes); 2567 if (type_set_expand(&stypes, &e_stypes, policydbp, 1)) 2568 goto bad; 2569 2570 ebitmap_init(&e_ttypes); 2571 if (type_set_expand(&ttypes, &e_ttypes, policydbp, 1)) 2572 goto bad; 2573 2574 ebitmap_for_each_bit(&e_tclasses, cnode, c) { 2575 if (!ebitmap_node_get_bit(cnode, c)) 2576 continue; 2577 ebitmap_for_each_bit(&e_stypes, snode, s) { 2578 if (!ebitmap_node_get_bit(snode, s)) 2579 continue; 2580 ebitmap_for_each_bit(&e_ttypes, tnode, t) { 2581 if (!ebitmap_node_get_bit(tnode, t)) 2582 continue; 2583 2584 for (ft = policydbp->filename_trans; ft; ft = ft->next) { 2585 if (ft->stype == (s + 1) && 2586 ft->ttype == (t + 1) && 2587 ft->tclass == (c + 1) && 2588 !strcmp(ft->name, name)) { 2589 yyerror2("duplicate filename transition for: filename_trans %s %s %s:%s", 2590 name, 2591 policydbp->p_type_val_to_name[s], 2592 policydbp->p_type_val_to_name[t], 2593 policydbp->p_class_val_to_name[c]); 2594 goto bad; 2595 } 2596 } 2597 2598 ft = malloc(sizeof(*ft)); 2599 if (!ft) { 2600 yyerror("out of memory"); 2601 goto bad; 2602 } 2603 memset(ft, 0, sizeof(*ft)); 2604 2605 ft->next = policydbp->filename_trans; 2606 policydbp->filename_trans = ft; 2607 2608 ft->name = strdup(name); 2609 if (!ft->name) { 2610 yyerror("out of memory"); 2611 goto bad; 2612 } 2613 ft->stype = s + 1; 2614 ft->ttype = t + 1; 2615 ft->tclass = c + 1; 2616 ft->otype = otype; 2617 } 2618 } 2619 2620 /* Now add the real rule since we didn't find any duplicates */ 2621 ftr = malloc(sizeof(*ftr)); 2622 if (!ftr) { 2623 yyerror("out of memory"); 2624 goto bad; 2625 } 2626 filename_trans_rule_init(ftr); 2627 append_filename_trans(ftr); 2628 2629 ftr->name = strdup(name); 2630 ftr->stypes = stypes; 2631 ftr->ttypes = ttypes; 2632 ftr->tclass = c + 1; 2633 ftr->otype = otype; 2634 } 2635 2636 free(name); 2637 ebitmap_destroy(&e_stypes); 2638 ebitmap_destroy(&e_ttypes); 2639 ebitmap_destroy(&e_tclasses); 2640 2641 return 0; 2642 2643bad: 2644 free(name); 2645 return -1; 2646} 2647 2648static constraint_expr_t *constraint_expr_clone(constraint_expr_t * expr) 2649{ 2650 constraint_expr_t *h = NULL, *l = NULL, *e, *newe; 2651 for (e = expr; e; e = e->next) { 2652 newe = malloc(sizeof(*newe)); 2653 if (!newe) 2654 goto oom; 2655 if (constraint_expr_init(newe) == -1) { 2656 free(newe); 2657 goto oom; 2658 } 2659 if (l) 2660 l->next = newe; 2661 else 2662 h = newe; 2663 l = newe; 2664 newe->expr_type = e->expr_type; 2665 newe->attr = e->attr; 2666 newe->op = e->op; 2667 if (newe->expr_type == CEXPR_NAMES) { 2668 if (newe->attr & CEXPR_TYPE) { 2669 if (type_set_cpy 2670 (newe->type_names, e->type_names)) 2671 goto oom; 2672 } else { 2673 if (ebitmap_cpy(&newe->names, &e->names)) 2674 goto oom; 2675 } 2676 } 2677 } 2678 2679 return h; 2680 oom: 2681 e = h; 2682 while (e) { 2683 l = e; 2684 e = e->next; 2685 constraint_expr_destroy(l); 2686 } 2687 return NULL; 2688} 2689 2690int define_constraint(constraint_expr_t * expr) 2691{ 2692 struct constraint_node *node; 2693 char *id; 2694 class_datum_t *cladatum; 2695 perm_datum_t *perdatum; 2696 ebitmap_t classmap; 2697 ebitmap_node_t *enode; 2698 constraint_expr_t *e; 2699 unsigned int i; 2700 int depth; 2701 unsigned char useexpr = 1; 2702 2703 if (pass == 1) { 2704 while ((id = queue_remove(id_queue))) 2705 free(id); 2706 while ((id = queue_remove(id_queue))) 2707 free(id); 2708 return 0; 2709 } 2710 2711 depth = -1; 2712 for (e = expr; e; e = e->next) { 2713 switch (e->expr_type) { 2714 case CEXPR_NOT: 2715 if (depth < 0) { 2716 yyerror("illegal constraint expression"); 2717 return -1; 2718 } 2719 break; 2720 case CEXPR_AND: 2721 case CEXPR_OR: 2722 if (depth < 1) { 2723 yyerror("illegal constraint expression"); 2724 return -1; 2725 } 2726 depth--; 2727 break; 2728 case CEXPR_ATTR: 2729 case CEXPR_NAMES: 2730 if (e->attr & CEXPR_XTARGET) { 2731 yyerror("illegal constraint expression"); 2732 return -1; /* only for validatetrans rules */ 2733 } 2734 if (depth == (CEXPR_MAXDEPTH - 1)) { 2735 yyerror("constraint expression is too deep"); 2736 return -1; 2737 } 2738 depth++; 2739 break; 2740 default: 2741 yyerror("illegal constraint expression"); 2742 return -1; 2743 } 2744 } 2745 if (depth != 0) { 2746 yyerror("illegal constraint expression"); 2747 return -1; 2748 } 2749 2750 ebitmap_init(&classmap); 2751 while ((id = queue_remove(id_queue))) { 2752 if (!is_id_in_scope(SYM_CLASSES, id)) { 2753 yyerror2("class %s is not within scope", id); 2754 free(id); 2755 return -1; 2756 } 2757 cladatum = 2758 (class_datum_t *) hashtab_search(policydbp->p_classes.table, 2759 (hashtab_key_t) id); 2760 if (!cladatum) { 2761 yyerror2("class %s is not defined", id); 2762 ebitmap_destroy(&classmap); 2763 free(id); 2764 return -1; 2765 } 2766 if (ebitmap_set_bit(&classmap, cladatum->s.value - 1, TRUE)) { 2767 yyerror("out of memory"); 2768 ebitmap_destroy(&classmap); 2769 free(id); 2770 return -1; 2771 } 2772 node = malloc(sizeof(struct constraint_node)); 2773 if (!node) { 2774 yyerror("out of memory"); 2775 return -1; 2776 } 2777 memset(node, 0, sizeof(constraint_node_t)); 2778 if (useexpr) { 2779 node->expr = expr; 2780 useexpr = 0; 2781 } else { 2782 node->expr = constraint_expr_clone(expr); 2783 } 2784 if (!node->expr) { 2785 yyerror("out of memory"); 2786 free(node); 2787 return -1; 2788 } 2789 node->permissions = 0; 2790 2791 node->next = cladatum->constraints; 2792 cladatum->constraints = node; 2793 2794 free(id); 2795 } 2796 2797 while ((id = queue_remove(id_queue))) { 2798 ebitmap_for_each_bit(&classmap, enode, i) { 2799 if (ebitmap_node_get_bit(enode, i)) { 2800 cladatum = policydbp->class_val_to_struct[i]; 2801 node = cladatum->constraints; 2802 2803 perdatum = 2804 (perm_datum_t *) hashtab_search(cladatum-> 2805 permissions. 2806 table, 2807 (hashtab_key_t) 2808 id); 2809 if (!perdatum) { 2810 if (cladatum->comdatum) { 2811 perdatum = 2812 (perm_datum_t *) 2813 hashtab_search(cladatum-> 2814 comdatum-> 2815 permissions. 2816 table, 2817 (hashtab_key_t) 2818 id); 2819 } 2820 if (!perdatum) { 2821 yyerror2("permission %s is not" 2822 " defined", id); 2823 free(id); 2824 ebitmap_destroy(&classmap); 2825 return -1; 2826 } 2827 } 2828 node->permissions |= 2829 (1 << (perdatum->s.value - 1)); 2830 } 2831 } 2832 free(id); 2833 } 2834 2835 ebitmap_destroy(&classmap); 2836 2837 return 0; 2838} 2839 2840int define_validatetrans(constraint_expr_t * expr) 2841{ 2842 struct constraint_node *node; 2843 char *id; 2844 class_datum_t *cladatum; 2845 ebitmap_t classmap; 2846 constraint_expr_t *e; 2847 int depth; 2848 unsigned char useexpr = 1; 2849 2850 if (pass == 1) { 2851 while ((id = queue_remove(id_queue))) 2852 free(id); 2853 return 0; 2854 } 2855 2856 depth = -1; 2857 for (e = expr; e; e = e->next) { 2858 switch (e->expr_type) { 2859 case CEXPR_NOT: 2860 if (depth < 0) { 2861 yyerror("illegal validatetrans expression"); 2862 return -1; 2863 } 2864 break; 2865 case CEXPR_AND: 2866 case CEXPR_OR: 2867 if (depth < 1) { 2868 yyerror("illegal validatetrans expression"); 2869 return -1; 2870 } 2871 depth--; 2872 break; 2873 case CEXPR_ATTR: 2874 case CEXPR_NAMES: 2875 if (depth == (CEXPR_MAXDEPTH - 1)) { 2876 yyerror("validatetrans expression is too deep"); 2877 return -1; 2878 } 2879 depth++; 2880 break; 2881 default: 2882 yyerror("illegal validatetrans expression"); 2883 return -1; 2884 } 2885 } 2886 if (depth != 0) { 2887 yyerror("illegal validatetrans expression"); 2888 return -1; 2889 } 2890 2891 ebitmap_init(&classmap); 2892 while ((id = queue_remove(id_queue))) { 2893 if (!is_id_in_scope(SYM_CLASSES, id)) { 2894 yyerror2("class %s is not within scope", id); 2895 free(id); 2896 return -1; 2897 } 2898 cladatum = 2899 (class_datum_t *) hashtab_search(policydbp->p_classes.table, 2900 (hashtab_key_t) id); 2901 if (!cladatum) { 2902 yyerror2("class %s is not defined", id); 2903 ebitmap_destroy(&classmap); 2904 free(id); 2905 return -1; 2906 } 2907 if (ebitmap_set_bit(&classmap, (cladatum->s.value - 1), TRUE)) { 2908 yyerror("out of memory"); 2909 ebitmap_destroy(&classmap); 2910 free(id); 2911 return -1; 2912 } 2913 2914 node = malloc(sizeof(struct constraint_node)); 2915 if (!node) { 2916 yyerror("out of memory"); 2917 return -1; 2918 } 2919 memset(node, 0, sizeof(constraint_node_t)); 2920 if (useexpr) { 2921 node->expr = expr; 2922 useexpr = 0; 2923 } else { 2924 node->expr = constraint_expr_clone(expr); 2925 } 2926 node->permissions = 0; 2927 2928 node->next = cladatum->validatetrans; 2929 cladatum->validatetrans = node; 2930 2931 free(id); 2932 } 2933 2934 ebitmap_destroy(&classmap); 2935 2936 return 0; 2937} 2938 2939uintptr_t define_cexpr(uint32_t expr_type, uintptr_t arg1, uintptr_t arg2) 2940{ 2941 struct constraint_expr *expr, *e1 = NULL, *e2; 2942 user_datum_t *user; 2943 role_datum_t *role; 2944 ebitmap_t negset; 2945 char *id; 2946 uint32_t val; 2947 int add = 1; 2948 2949 if (pass == 1) { 2950 if (expr_type == CEXPR_NAMES) { 2951 while ((id = queue_remove(id_queue))) 2952 free(id); 2953 } 2954 return 1; /* any non-NULL value */ 2955 } 2956 2957 if ((expr = malloc(sizeof(*expr))) == NULL || 2958 constraint_expr_init(expr) == -1) { 2959 yyerror("out of memory"); 2960 free(expr); 2961 return 0; 2962 } 2963 expr->expr_type = expr_type; 2964 2965 switch (expr_type) { 2966 case CEXPR_NOT: 2967 e1 = NULL; 2968 e2 = (struct constraint_expr *)arg1; 2969 while (e2) { 2970 e1 = e2; 2971 e2 = e2->next; 2972 } 2973 if (!e1 || e1->next) { 2974 yyerror("illegal constraint expression"); 2975 constraint_expr_destroy(expr); 2976 return 0; 2977 } 2978 e1->next = expr; 2979 return arg1; 2980 case CEXPR_AND: 2981 case CEXPR_OR: 2982 e1 = NULL; 2983 e2 = (struct constraint_expr *)arg1; 2984 while (e2) { 2985 e1 = e2; 2986 e2 = e2->next; 2987 } 2988 if (!e1 || e1->next) { 2989 yyerror("illegal constraint expression"); 2990 constraint_expr_destroy(expr); 2991 return 0; 2992 } 2993 e1->next = (struct constraint_expr *)arg2; 2994 2995 e1 = NULL; 2996 e2 = (struct constraint_expr *)arg2; 2997 while (e2) { 2998 e1 = e2; 2999 e2 = e2->next; 3000 } 3001 if (!e1 || e1->next) { 3002 yyerror("illegal constraint expression"); 3003 constraint_expr_destroy(expr); 3004 return 0; 3005 } 3006 e1->next = expr; 3007 return arg1; 3008 case CEXPR_ATTR: 3009 expr->attr = arg1; 3010 expr->op = arg2; 3011 return (uintptr_t) expr; 3012 case CEXPR_NAMES: 3013 add = 1; 3014 expr->attr = arg1; 3015 expr->op = arg2; 3016 ebitmap_init(&negset); 3017 while ((id = (char *)queue_remove(id_queue))) { 3018 if (expr->attr & CEXPR_USER) { 3019 if (!is_id_in_scope(SYM_USERS, id)) { 3020 yyerror2("user %s is not within scope", 3021 id); 3022 constraint_expr_destroy(expr); 3023 return 0; 3024 } 3025 user = 3026 (user_datum_t *) hashtab_search(policydbp-> 3027 p_users. 3028 table, 3029 (hashtab_key_t) 3030 id); 3031 if (!user) { 3032 yyerror2("unknown user %s", id); 3033 constraint_expr_destroy(expr); 3034 return 0; 3035 } 3036 val = user->s.value; 3037 } else if (expr->attr & CEXPR_ROLE) { 3038 if (!is_id_in_scope(SYM_ROLES, id)) { 3039 yyerror2("role %s is not within scope", 3040 id); 3041 constraint_expr_destroy(expr); 3042 return 0; 3043 } 3044 role = 3045 (role_datum_t *) hashtab_search(policydbp-> 3046 p_roles. 3047 table, 3048 (hashtab_key_t) 3049 id); 3050 if (!role) { 3051 yyerror2("unknown role %s", id); 3052 constraint_expr_destroy(expr); 3053 return 0; 3054 } 3055 val = role->s.value; 3056 } else if (expr->attr & CEXPR_TYPE) { 3057 if (set_types(expr->type_names, id, &add, 0)) { 3058 constraint_expr_destroy(expr); 3059 return 0; 3060 } 3061 continue; 3062 } else { 3063 yyerror("invalid constraint expression"); 3064 constraint_expr_destroy(expr); 3065 return 0; 3066 } 3067 if (ebitmap_set_bit(&expr->names, val - 1, TRUE)) { 3068 yyerror("out of memory"); 3069 ebitmap_destroy(&expr->names); 3070 constraint_expr_destroy(expr); 3071 return 0; 3072 } 3073 free(id); 3074 } 3075 ebitmap_destroy(&negset); 3076 return (uintptr_t) expr; 3077 default: 3078 yyerror("invalid constraint expression"); 3079 constraint_expr_destroy(expr); 3080 return 0; 3081 } 3082 3083 yyerror("invalid constraint expression"); 3084 free(expr); 3085 return 0; 3086} 3087 3088int define_conditional(cond_expr_t * expr, avrule_t * t, avrule_t * f) 3089{ 3090 cond_expr_t *e; 3091 int depth; 3092 cond_node_t cn, *cn_old; 3093 3094 /* expression cannot be NULL */ 3095 if (!expr) { 3096 yyerror("illegal conditional expression"); 3097 return -1; 3098 } 3099 if (!t) { 3100 if (!f) { 3101 /* empty is fine, destroy expression and return */ 3102 cond_expr_destroy(expr); 3103 return 0; 3104 } 3105 /* Invert */ 3106 t = f; 3107 f = 0; 3108 expr = define_cond_expr(COND_NOT, expr, 0); 3109 if (!expr) { 3110 yyerror("unable to invert"); 3111 return -1; 3112 } 3113 } 3114 3115 /* verify expression */ 3116 depth = -1; 3117 for (e = expr; e; e = e->next) { 3118 switch (e->expr_type) { 3119 case COND_NOT: 3120 if (depth < 0) { 3121 yyerror 3122 ("illegal conditional expression; Bad NOT"); 3123 return -1; 3124 } 3125 break; 3126 case COND_AND: 3127 case COND_OR: 3128 case COND_XOR: 3129 case COND_EQ: 3130 case COND_NEQ: 3131 if (depth < 1) { 3132 yyerror 3133 ("illegal conditional expression; Bad binary op"); 3134 return -1; 3135 } 3136 depth--; 3137 break; 3138 case COND_BOOL: 3139 if (depth == (COND_EXPR_MAXDEPTH - 1)) { 3140 yyerror 3141 ("conditional expression is like totally too deep"); 3142 return -1; 3143 } 3144 depth++; 3145 break; 3146 default: 3147 yyerror("illegal conditional expression"); 3148 return -1; 3149 } 3150 } 3151 if (depth != 0) { 3152 yyerror("illegal conditional expression"); 3153 return -1; 3154 } 3155 3156 /* use tmp conditional node to partially build new node */ 3157 memset(&cn, 0, sizeof(cn)); 3158 cn.expr = expr; 3159 cn.avtrue_list = t; 3160 cn.avfalse_list = f; 3161 3162 /* normalize/precompute expression */ 3163 if (cond_normalize_expr(policydbp, &cn) < 0) { 3164 yyerror("problem normalizing conditional expression"); 3165 return -1; 3166 } 3167 3168 /* get the existing conditional node, or create a new one */ 3169 cn_old = get_current_cond_list(&cn); 3170 if (!cn_old) { 3171 return -1; 3172 } 3173 3174 append_cond_list(&cn); 3175 3176 /* note that there is no check here for duplicate rules, nor 3177 * check that rule already exists in base -- that will be 3178 * handled during conditional expansion, in expand.c */ 3179 3180 cn.avtrue_list = NULL; 3181 cn.avfalse_list = NULL; 3182 cond_node_destroy(&cn); 3183 3184 return 0; 3185} 3186 3187cond_expr_t *define_cond_expr(uint32_t expr_type, void *arg1, void *arg2) 3188{ 3189 struct cond_expr *expr, *e1 = NULL, *e2; 3190 cond_bool_datum_t *bool_var; 3191 char *id; 3192 3193 /* expressions are handled in the second pass */ 3194 if (pass == 1) { 3195 if (expr_type == COND_BOOL) { 3196 while ((id = queue_remove(id_queue))) { 3197 free(id); 3198 } 3199 } 3200 return (cond_expr_t *) 1; /* any non-NULL value */ 3201 } 3202 3203 /* create a new expression struct */ 3204 expr = malloc(sizeof(struct cond_expr)); 3205 if (!expr) { 3206 yyerror("out of memory"); 3207 return NULL; 3208 } 3209 memset(expr, 0, sizeof(cond_expr_t)); 3210 expr->expr_type = expr_type; 3211 3212 /* create the type asked for */ 3213 switch (expr_type) { 3214 case COND_NOT: 3215 e1 = NULL; 3216 e2 = (struct cond_expr *)arg1; 3217 while (e2) { 3218 e1 = e2; 3219 e2 = e2->next; 3220 } 3221 if (!e1 || e1->next) { 3222 yyerror("illegal conditional NOT expression"); 3223 free(expr); 3224 return NULL; 3225 } 3226 e1->next = expr; 3227 return (struct cond_expr *)arg1; 3228 case COND_AND: 3229 case COND_OR: 3230 case COND_XOR: 3231 case COND_EQ: 3232 case COND_NEQ: 3233 e1 = NULL; 3234 e2 = (struct cond_expr *)arg1; 3235 while (e2) { 3236 e1 = e2; 3237 e2 = e2->next; 3238 } 3239 if (!e1 || e1->next) { 3240 yyerror 3241 ("illegal left side of conditional binary op expression"); 3242 free(expr); 3243 return NULL; 3244 } 3245 e1->next = (struct cond_expr *)arg2; 3246 3247 e1 = NULL; 3248 e2 = (struct cond_expr *)arg2; 3249 while (e2) { 3250 e1 = e2; 3251 e2 = e2->next; 3252 } 3253 if (!e1 || e1->next) { 3254 yyerror 3255 ("illegal right side of conditional binary op expression"); 3256 free(expr); 3257 return NULL; 3258 } 3259 e1->next = expr; 3260 return (struct cond_expr *)arg1; 3261 case COND_BOOL: 3262 id = (char *)queue_remove(id_queue); 3263 if (!id) { 3264 yyerror("bad conditional; expected boolean id"); 3265 free(id); 3266 free(expr); 3267 return NULL; 3268 } 3269 if (!is_id_in_scope(SYM_BOOLS, id)) { 3270 yyerror2("boolean %s is not within scope", id); 3271 free(id); 3272 free(expr); 3273 return NULL; 3274 } 3275 bool_var = 3276 (cond_bool_datum_t *) hashtab_search(policydbp->p_bools. 3277 table, 3278 (hashtab_key_t) id); 3279 if (!bool_var) { 3280 yyerror2("unknown boolean %s in conditional expression", 3281 id); 3282 free(expr); 3283 free(id); 3284 return NULL; 3285 } 3286 expr->bool = bool_var->s.value; 3287 free(id); 3288 return expr; 3289 default: 3290 yyerror("illegal conditional expression"); 3291 free(expr); 3292 return NULL; 3293 } 3294} 3295 3296static int set_user_roles(role_set_t * set, char *id) 3297{ 3298 role_datum_t *r; 3299 unsigned int i; 3300 ebitmap_node_t *node; 3301 3302 if (strcmp(id, "*") == 0) { 3303 free(id); 3304 yyerror("* is not allowed in user declarations"); 3305 return -1; 3306 } 3307 3308 if (strcmp(id, "~") == 0) { 3309 free(id); 3310 yyerror("~ is not allowed in user declarations"); 3311 return -1; 3312 } 3313 3314 if (!is_id_in_scope(SYM_ROLES, id)) { 3315 yyerror2("role %s is not within scope", id); 3316 free(id); 3317 return -1; 3318 } 3319 r = hashtab_search(policydbp->p_roles.table, id); 3320 if (!r) { 3321 yyerror2("unknown role %s", id); 3322 free(id); 3323 return -1; 3324 } 3325 3326 /* set the role and every role it dominates */ 3327 ebitmap_for_each_bit(&r->dominates, node, i) { 3328 if (ebitmap_node_get_bit(node, i)) 3329 if (ebitmap_set_bit(&set->roles, i, TRUE)) 3330 goto oom; 3331 } 3332 free(id); 3333 return 0; 3334 oom: 3335 yyerror("out of memory"); 3336 return -1; 3337} 3338 3339static int parse_categories(char *id, level_datum_t * levdatum, ebitmap_t * cats) 3340{ 3341 cat_datum_t *cdatum; 3342 int range_start, range_end, i; 3343 3344 if (id_has_dot(id)) { 3345 char *id_start = id; 3346 char *id_end = strchr(id, '.'); 3347 3348 *(id_end++) = '\0'; 3349 3350 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 3351 (hashtab_key_t) 3352 id_start); 3353 if (!cdatum) { 3354 yyerror2("unknown category %s", id_start); 3355 return -1; 3356 } 3357 range_start = cdatum->s.value - 1; 3358 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 3359 (hashtab_key_t) id_end); 3360 if (!cdatum) { 3361 yyerror2("unknown category %s", id_end); 3362 return -1; 3363 } 3364 range_end = cdatum->s.value - 1; 3365 3366 if (range_end < range_start) { 3367 yyerror2("category range is invalid"); 3368 return -1; 3369 } 3370 } else { 3371 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 3372 (hashtab_key_t) id); 3373 if (!cdatum) { 3374 yyerror2("unknown category %s", id); 3375 return -1; 3376 } 3377 range_start = range_end = cdatum->s.value - 1; 3378 } 3379 3380 for (i = range_start; i <= range_end; i++) { 3381 if (!ebitmap_get_bit(&levdatum->level->cat, i)) { 3382 uint32_t level_value = levdatum->level->sens - 1; 3383 policydb_index_others(NULL, policydbp, 0); 3384 yyerror2("category %s can not be associated " 3385 "with level %s", 3386 policydbp->p_cat_val_to_name[i], 3387 policydbp->p_sens_val_to_name[level_value]); 3388 return -1; 3389 } 3390 if (ebitmap_set_bit(cats, i, TRUE)) { 3391 yyerror("out of memory"); 3392 return -1; 3393 } 3394 } 3395 3396 return 0; 3397} 3398 3399static int parse_semantic_categories(char *id, level_datum_t * levdatum, 3400 mls_semantic_cat_t ** cats) 3401{ 3402 cat_datum_t *cdatum; 3403 mls_semantic_cat_t *newcat; 3404 unsigned int range_start, range_end; 3405 3406 if (id_has_dot(id)) { 3407 char *id_start = id; 3408 char *id_end = strchr(id, '.'); 3409 3410 *(id_end++) = '\0'; 3411 3412 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 3413 (hashtab_key_t) 3414 id_start); 3415 if (!cdatum) { 3416 yyerror2("unknown category %s", id_start); 3417 return -1; 3418 } 3419 range_start = cdatum->s.value; 3420 3421 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 3422 (hashtab_key_t) id_end); 3423 if (!cdatum) { 3424 yyerror2("unknown category %s", id_end); 3425 return -1; 3426 } 3427 range_end = cdatum->s.value; 3428 } else { 3429 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 3430 (hashtab_key_t) id); 3431 if (!cdatum) { 3432 yyerror2("unknown category %s", id); 3433 return -1; 3434 } 3435 range_start = range_end = cdatum->s.value; 3436 } 3437 3438 newcat = (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t)); 3439 if (!newcat) { 3440 yyerror("out of memory"); 3441 return -1; 3442 } 3443 3444 mls_semantic_cat_init(newcat); 3445 newcat->next = *cats; 3446 newcat->low = range_start; 3447 newcat->high = range_end; 3448 3449 *cats = newcat; 3450 3451 return 0; 3452} 3453 3454int define_user(void) 3455{ 3456 char *id; 3457 user_datum_t *usrdatum; 3458 level_datum_t *levdatum; 3459 int l; 3460 3461 if (pass == 1) { 3462 while ((id = queue_remove(id_queue))) 3463 free(id); 3464 if (mlspol) { 3465 while ((id = queue_remove(id_queue))) 3466 free(id); 3467 id = queue_remove(id_queue); 3468 free(id); 3469 for (l = 0; l < 2; l++) { 3470 while ((id = queue_remove(id_queue))) { 3471 free(id); 3472 } 3473 id = queue_remove(id_queue); 3474 if (!id) 3475 break; 3476 free(id); 3477 } 3478 } 3479 return 0; 3480 } 3481 3482 if ((usrdatum = declare_user()) == NULL) { 3483 return -1; 3484 } 3485 3486 while ((id = queue_remove(id_queue))) { 3487 if (set_user_roles(&usrdatum->roles, id)) 3488 continue; 3489 } 3490 3491 if (mlspol) { 3492 id = queue_remove(id_queue); 3493 if (!id) { 3494 yyerror("no default level specified for user"); 3495 return -1; 3496 } 3497 3498 levdatum = (level_datum_t *) 3499 hashtab_search(policydbp->p_levels.table, 3500 (hashtab_key_t) id); 3501 if (!levdatum) { 3502 yyerror2("unknown sensitivity %s used in user" 3503 " level definition", id); 3504 free(id); 3505 return -1; 3506 } 3507 free(id); 3508 3509 usrdatum->dfltlevel.sens = levdatum->level->sens; 3510 3511 while ((id = queue_remove(id_queue))) { 3512 if (parse_semantic_categories(id, levdatum, 3513 &usrdatum->dfltlevel.cat)) { 3514 free(id); 3515 return -1; 3516 } 3517 free(id); 3518 } 3519 3520 id = queue_remove(id_queue); 3521 3522 for (l = 0; l < 2; l++) { 3523 levdatum = (level_datum_t *) 3524 hashtab_search(policydbp->p_levels.table, 3525 (hashtab_key_t) id); 3526 if (!levdatum) { 3527 yyerror2("unknown sensitivity %s used in user" 3528 " range definition", id); 3529 free(id); 3530 return -1; 3531 } 3532 free(id); 3533 3534 usrdatum->range.level[l].sens = levdatum->level->sens; 3535 3536 while ((id = queue_remove(id_queue))) { 3537 if (parse_semantic_categories(id, levdatum, 3538 &usrdatum->range.level[l].cat)) { 3539 free(id); 3540 return -1; 3541 } 3542 free(id); 3543 } 3544 3545 id = queue_remove(id_queue); 3546 if (!id) 3547 break; 3548 } 3549 3550 if (l == 0) { 3551 if (mls_semantic_level_cpy(&usrdatum->range.level[1], 3552 &usrdatum->range.level[0])) { 3553 yyerror("out of memory"); 3554 return -1; 3555 } 3556 } 3557 } 3558 return 0; 3559} 3560 3561static int parse_security_context(context_struct_t * c) 3562{ 3563 char *id; 3564 role_datum_t *role; 3565 type_datum_t *typdatum; 3566 user_datum_t *usrdatum; 3567 level_datum_t *levdatum; 3568 int l; 3569 3570 if (pass == 1) { 3571 id = queue_remove(id_queue); 3572 free(id); /* user */ 3573 id = queue_remove(id_queue); 3574 free(id); /* role */ 3575 id = queue_remove(id_queue); 3576 free(id); /* type */ 3577 if (mlspol) { 3578 id = queue_remove(id_queue); 3579 free(id); 3580 for (l = 0; l < 2; l++) { 3581 while ((id = queue_remove(id_queue))) { 3582 free(id); 3583 } 3584 id = queue_remove(id_queue); 3585 if (!id) 3586 break; 3587 free(id); 3588 } 3589 } 3590 return 0; 3591 } 3592 3593 /* check context c to make sure ok to dereference c later */ 3594 if (c == NULL) { 3595 yyerror("null context pointer!"); 3596 return -1; 3597 } 3598 3599 context_init(c); 3600 3601 /* extract the user */ 3602 id = queue_remove(id_queue); 3603 if (!id) { 3604 yyerror("no effective user?"); 3605 goto bad; 3606 } 3607 if (!is_id_in_scope(SYM_USERS, id)) { 3608 yyerror2("user %s is not within scope", id); 3609 free(id); 3610 goto bad; 3611 } 3612 usrdatum = (user_datum_t *) hashtab_search(policydbp->p_users.table, 3613 (hashtab_key_t) id); 3614 if (!usrdatum) { 3615 yyerror2("user %s is not defined", id); 3616 free(id); 3617 goto bad; 3618 } 3619 c->user = usrdatum->s.value; 3620 3621 /* no need to keep the user name */ 3622 free(id); 3623 3624 /* extract the role */ 3625 id = (char *)queue_remove(id_queue); 3626 if (!id) { 3627 yyerror("no role name for sid context definition?"); 3628 return -1; 3629 } 3630 if (!is_id_in_scope(SYM_ROLES, id)) { 3631 yyerror2("role %s is not within scope", id); 3632 free(id); 3633 return -1; 3634 } 3635 role = (role_datum_t *) hashtab_search(policydbp->p_roles.table, 3636 (hashtab_key_t) id); 3637 if (!role) { 3638 yyerror2("role %s is not defined", id); 3639 free(id); 3640 return -1; 3641 } 3642 c->role = role->s.value; 3643 3644 /* no need to keep the role name */ 3645 free(id); 3646 3647 /* extract the type */ 3648 id = (char *)queue_remove(id_queue); 3649 if (!id) { 3650 yyerror("no type name for sid context definition?"); 3651 return -1; 3652 } 3653 if (!is_id_in_scope(SYM_TYPES, id)) { 3654 yyerror2("type %s is not within scope", id); 3655 free(id); 3656 return -1; 3657 } 3658 typdatum = (type_datum_t *) hashtab_search(policydbp->p_types.table, 3659 (hashtab_key_t) id); 3660 if (!typdatum || typdatum->flavor == TYPE_ATTRIB) { 3661 yyerror2("type %s is not defined or is an attribute", id); 3662 free(id); 3663 return -1; 3664 } 3665 c->type = typdatum->s.value; 3666 3667 /* no need to keep the type name */ 3668 free(id); 3669 3670 if (mlspol) { 3671 /* extract the low sensitivity */ 3672 id = (char *)queue_head(id_queue); 3673 if (!id) { 3674 yyerror("no sensitivity name for sid context" 3675 " definition?"); 3676 return -1; 3677 } 3678 3679 id = (char *)queue_remove(id_queue); 3680 for (l = 0; l < 2; l++) { 3681 levdatum = (level_datum_t *) 3682 hashtab_search(policydbp->p_levels.table, 3683 (hashtab_key_t) id); 3684 if (!levdatum) { 3685 yyerror2("Sensitivity %s is not defined", id); 3686 free(id); 3687 return -1; 3688 } 3689 free(id); 3690 c->range.level[l].sens = levdatum->level->sens; 3691 3692 /* extract low category set */ 3693 while ((id = queue_remove(id_queue))) { 3694 if (parse_categories(id, levdatum, 3695 &c->range.level[l].cat)) { 3696 free(id); 3697 return -1; 3698 } 3699 free(id); 3700 } 3701 3702 /* extract high sensitivity */ 3703 id = (char *)queue_remove(id_queue); 3704 if (!id) 3705 break; 3706 } 3707 3708 if (l == 0) { 3709 c->range.level[1].sens = c->range.level[0].sens; 3710 if (ebitmap_cpy(&c->range.level[1].cat, 3711 &c->range.level[0].cat)) { 3712 3713 yyerror("out of memory"); 3714 goto bad; 3715 } 3716 } 3717 } 3718 3719 if (!policydb_context_isvalid(policydbp, c)) { 3720 yyerror("invalid security context"); 3721 goto bad; 3722 } 3723 return 0; 3724 3725 bad: 3726 context_destroy(c); 3727 3728 return -1; 3729} 3730 3731int define_initial_sid_context(void) 3732{ 3733 char *id; 3734 ocontext_t *c, *head; 3735 3736 if (pass == 1) { 3737 id = (char *)queue_remove(id_queue); 3738 free(id); 3739 parse_security_context(NULL); 3740 return 0; 3741 } 3742 3743 id = (char *)queue_remove(id_queue); 3744 if (!id) { 3745 yyerror("no sid name for SID context definition?"); 3746 return -1; 3747 } 3748 head = policydbp->ocontexts[OCON_ISID]; 3749 for (c = head; c; c = c->next) { 3750 if (!strcmp(id, c->u.name)) 3751 break; 3752 } 3753 3754 if (!c) { 3755 yyerror2("SID %s is not defined", id); 3756 free(id); 3757 return -1; 3758 } 3759 if (c->context[0].user) { 3760 yyerror2("The context for SID %s is multiply defined", id); 3761 free(id); 3762 return -1; 3763 } 3764 /* no need to keep the sid name */ 3765 free(id); 3766 3767 if (parse_security_context(&c->context[0])) 3768 return -1; 3769 3770 return 0; 3771} 3772 3773int define_fs_context(unsigned int major, unsigned int minor) 3774{ 3775 ocontext_t *newc, *c, *head; 3776 3777 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 3778 yyerror("fscon not supported for target"); 3779 return -1; 3780 } 3781 3782 if (pass == 1) { 3783 parse_security_context(NULL); 3784 parse_security_context(NULL); 3785 return 0; 3786 } 3787 3788 newc = (ocontext_t *) malloc(sizeof(ocontext_t)); 3789 if (!newc) { 3790 yyerror("out of memory"); 3791 return -1; 3792 } 3793 memset(newc, 0, sizeof(ocontext_t)); 3794 3795 newc->u.name = (char *)malloc(6); 3796 if (!newc->u.name) { 3797 yyerror("out of memory"); 3798 free(newc); 3799 return -1; 3800 } 3801 sprintf(newc->u.name, "%02x:%02x", major, minor); 3802 3803 if (parse_security_context(&newc->context[0])) { 3804 free(newc->u.name); 3805 free(newc); 3806 return -1; 3807 } 3808 if (parse_security_context(&newc->context[1])) { 3809 context_destroy(&newc->context[0]); 3810 free(newc->u.name); 3811 free(newc); 3812 return -1; 3813 } 3814 head = policydbp->ocontexts[OCON_FS]; 3815 3816 for (c = head; c; c = c->next) { 3817 if (!strcmp(newc->u.name, c->u.name)) { 3818 yyerror2("duplicate entry for file system %s", 3819 newc->u.name); 3820 context_destroy(&newc->context[0]); 3821 context_destroy(&newc->context[1]); 3822 free(newc->u.name); 3823 free(newc); 3824 return -1; 3825 } 3826 } 3827 3828 newc->next = head; 3829 policydbp->ocontexts[OCON_FS] = newc; 3830 3831 return 0; 3832} 3833 3834int define_pirq_context(unsigned int pirq) 3835{ 3836 ocontext_t *newc, *c, *l, *head; 3837 char *id; 3838 3839 if (policydbp->target_platform != SEPOL_TARGET_XEN) { 3840 yyerror("pirqcon not supported for target"); 3841 return -1; 3842 } 3843 3844 if (pass == 1) { 3845 id = (char *) queue_remove(id_queue); 3846 free(id); 3847 parse_security_context(NULL); 3848 return 0; 3849 } 3850 3851 newc = malloc(sizeof(ocontext_t)); 3852 if (!newc) { 3853 yyerror("out of memory"); 3854 return -1; 3855 } 3856 memset(newc, 0, sizeof(ocontext_t)); 3857 3858 newc->u.pirq = pirq; 3859 3860 if (parse_security_context(&newc->context[0])) { 3861 free(newc); 3862 return -1; 3863 } 3864 3865 head = policydbp->ocontexts[OCON_XEN_PIRQ]; 3866 for (l = NULL, c = head; c; l = c, c = c->next) { 3867 unsigned int pirq2; 3868 3869 pirq2 = c->u.pirq; 3870 if (pirq == pirq2) { 3871 yyerror2("duplicate pirqcon entry for %d ", pirq); 3872 goto bad; 3873 } 3874 } 3875 3876 if (l) 3877 l->next = newc; 3878 else 3879 policydbp->ocontexts[OCON_XEN_PIRQ] = newc; 3880 3881 return 0; 3882 3883bad: 3884 free(newc); 3885 return -1; 3886} 3887 3888int define_iomem_context(unsigned long low, unsigned long high) 3889{ 3890 ocontext_t *newc, *c, *l, *head; 3891 char *id; 3892 3893 if (policydbp->target_platform != SEPOL_TARGET_XEN) { 3894 yyerror("iomemcon not supported for target"); 3895 return -1; 3896 } 3897 3898 if (pass == 1) { 3899 id = (char *)queue_remove(id_queue); 3900 free(id); 3901 parse_security_context(NULL); 3902 return 0; 3903 } 3904 3905 newc = malloc(sizeof(ocontext_t)); 3906 if (!newc) { 3907 yyerror("out of memory"); 3908 return -1; 3909 } 3910 memset(newc, 0, sizeof(ocontext_t)); 3911 3912 newc->u.iomem.low_iomem = low; 3913 newc->u.iomem.high_iomem = high; 3914 3915 if (low > high) { 3916 yyerror2("low memory 0x%x exceeds high memory 0x%x", low, high); 3917 free(newc); 3918 return -1; 3919 } 3920 3921 if (parse_security_context(&newc->context[0])) { 3922 free(newc); 3923 return -1; 3924 } 3925 3926 head = policydbp->ocontexts[OCON_XEN_IOMEM]; 3927 for (l = NULL, c = head; c; l = c, c = c->next) { 3928 unsigned int low2, high2; 3929 3930 low2 = c->u.iomem.low_iomem; 3931 high2 = c->u.iomem.high_iomem; 3932 if (low <= high2 && low2 <= high) { 3933 yyerror2("iomemcon entry for 0x%x-0x%x overlaps with " 3934 "earlier entry 0x%x-0x%x", low, high, 3935 low2, high2); 3936 goto bad; 3937 } 3938 } 3939 3940 if (l) 3941 l->next = newc; 3942 else 3943 policydbp->ocontexts[OCON_XEN_IOMEM] = newc; 3944 3945 return 0; 3946 3947bad: 3948 free(newc); 3949 return -1; 3950} 3951 3952int define_ioport_context(unsigned long low, unsigned long high) 3953{ 3954 ocontext_t *newc, *c, *l, *head; 3955 char *id; 3956 3957 if (policydbp->target_platform != SEPOL_TARGET_XEN) { 3958 yyerror("ioportcon not supported for target"); 3959 return -1; 3960 } 3961 3962 if (pass == 1) { 3963 id = (char *)queue_remove(id_queue); 3964 free(id); 3965 parse_security_context(NULL); 3966 return 0; 3967 } 3968 3969 newc = malloc(sizeof(ocontext_t)); 3970 if (!newc) { 3971 yyerror("out of memory"); 3972 return -1; 3973 } 3974 memset(newc, 0, sizeof(ocontext_t)); 3975 3976 newc->u.ioport.low_ioport = low; 3977 newc->u.ioport.high_ioport = high; 3978 3979 if (low > high) { 3980 yyerror2("low ioport 0x%x exceeds high ioport 0x%x", low, high); 3981 free(newc); 3982 return -1; 3983 } 3984 3985 if (parse_security_context(&newc->context[0])) { 3986 free(newc); 3987 return -1; 3988 } 3989 3990 head = policydbp->ocontexts[OCON_XEN_IOPORT]; 3991 for (l = NULL, c = head; c; l = c, c = c->next) { 3992 unsigned int low2, high2; 3993 3994 low2 = c->u.ioport.low_ioport; 3995 high2 = c->u.ioport.high_ioport; 3996 if (low <= high2 && low2 <= high) { 3997 yyerror2("ioportcon entry for 0x%x-0x%x overlaps with" 3998 "earlier entry 0x%x-0x%x", low, high, 3999 low2, high2); 4000 goto bad; 4001 } 4002 } 4003 4004 if (l) 4005 l->next = newc; 4006 else 4007 policydbp->ocontexts[OCON_XEN_IOPORT] = newc; 4008 4009 return 0; 4010 4011bad: 4012 free(newc); 4013 return -1; 4014} 4015 4016int define_pcidevice_context(unsigned long device) 4017{ 4018 ocontext_t *newc, *c, *l, *head; 4019 char *id; 4020 4021 if (policydbp->target_platform != SEPOL_TARGET_XEN) { 4022 yyerror("pcidevicecon not supported for target"); 4023 return -1; 4024 } 4025 4026 if (pass == 1) { 4027 id = (char *) queue_remove(id_queue); 4028 free(id); 4029 parse_security_context(NULL); 4030 return 0; 4031 } 4032 4033 newc = malloc(sizeof(ocontext_t)); 4034 if (!newc) { 4035 yyerror("out of memory"); 4036 return -1; 4037 } 4038 memset(newc, 0, sizeof(ocontext_t)); 4039 4040 newc->u.device = device; 4041 4042 if (parse_security_context(&newc->context[0])) { 4043 free(newc); 4044 return -1; 4045 } 4046 4047 head = policydbp->ocontexts[OCON_XEN_PCIDEVICE]; 4048 for (l = NULL, c = head; c; l = c, c = c->next) { 4049 unsigned int device2; 4050 4051 device2 = c->u.device; 4052 if (device == device2) { 4053 yyerror2("duplicate pcidevicecon entry for 0x%x ", 4054 device); 4055 goto bad; 4056 } 4057 } 4058 4059 if (l) 4060 l->next = newc; 4061 else 4062 policydbp->ocontexts[OCON_XEN_PCIDEVICE] = newc; 4063 4064 return 0; 4065 4066bad: 4067 free(newc); 4068 return -1; 4069} 4070 4071int define_port_context(unsigned int low, unsigned int high) 4072{ 4073 ocontext_t *newc, *c, *l, *head; 4074 unsigned int protocol; 4075 char *id; 4076 4077 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 4078 yyerror("portcon not supported for target"); 4079 return -1; 4080 } 4081 4082 if (pass == 1) { 4083 id = (char *)queue_remove(id_queue); 4084 free(id); 4085 parse_security_context(NULL); 4086 return 0; 4087 } 4088 4089 newc = malloc(sizeof(ocontext_t)); 4090 if (!newc) { 4091 yyerror("out of memory"); 4092 return -1; 4093 } 4094 memset(newc, 0, sizeof(ocontext_t)); 4095 4096 id = (char *)queue_remove(id_queue); 4097 if (!id) { 4098 free(newc); 4099 return -1; 4100 } 4101 if ((strcmp(id, "tcp") == 0) || (strcmp(id, "TCP") == 0)) { 4102 protocol = IPPROTO_TCP; 4103 } else if ((strcmp(id, "udp") == 0) || (strcmp(id, "UDP") == 0)) { 4104 protocol = IPPROTO_UDP; 4105 } else { 4106 yyerror2("unrecognized protocol %s", id); 4107 free(newc); 4108 return -1; 4109 } 4110 4111 newc->u.port.protocol = protocol; 4112 newc->u.port.low_port = low; 4113 newc->u.port.high_port = high; 4114 4115 if (low > high) { 4116 yyerror2("low port %d exceeds high port %d", low, high); 4117 free(newc); 4118 return -1; 4119 } 4120 4121 if (parse_security_context(&newc->context[0])) { 4122 free(newc); 4123 return -1; 4124 } 4125 4126 /* Preserve the matching order specified in the configuration. */ 4127 head = policydbp->ocontexts[OCON_PORT]; 4128 for (l = NULL, c = head; c; l = c, c = c->next) { 4129 unsigned int prot2, low2, high2; 4130 4131 prot2 = c->u.port.protocol; 4132 low2 = c->u.port.low_port; 4133 high2 = c->u.port.high_port; 4134 if (protocol != prot2) 4135 continue; 4136 if (low == low2 && high == high2) { 4137 yyerror2("duplicate portcon entry for %s %d-%d ", id, 4138 low, high); 4139 goto bad; 4140 } 4141 if (low2 <= low && high2 >= high) { 4142 yyerror2("portcon entry for %s %d-%d hidden by earlier " 4143 "entry for %d-%d", id, low, high, low2, high2); 4144 goto bad; 4145 } 4146 } 4147 4148 if (l) 4149 l->next = newc; 4150 else 4151 policydbp->ocontexts[OCON_PORT] = newc; 4152 4153 return 0; 4154 4155 bad: 4156 free(newc); 4157 return -1; 4158} 4159 4160int define_netif_context(void) 4161{ 4162 ocontext_t *newc, *c, *head; 4163 4164 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 4165 yyerror("netifcon not supported for target"); 4166 return -1; 4167 } 4168 4169 if (pass == 1) { 4170 free(queue_remove(id_queue)); 4171 parse_security_context(NULL); 4172 parse_security_context(NULL); 4173 return 0; 4174 } 4175 4176 newc = (ocontext_t *) malloc(sizeof(ocontext_t)); 4177 if (!newc) { 4178 yyerror("out of memory"); 4179 return -1; 4180 } 4181 memset(newc, 0, sizeof(ocontext_t)); 4182 4183 newc->u.name = (char *)queue_remove(id_queue); 4184 if (!newc->u.name) { 4185 free(newc); 4186 return -1; 4187 } 4188 if (parse_security_context(&newc->context[0])) { 4189 free(newc->u.name); 4190 free(newc); 4191 return -1; 4192 } 4193 if (parse_security_context(&newc->context[1])) { 4194 context_destroy(&newc->context[0]); 4195 free(newc->u.name); 4196 free(newc); 4197 return -1; 4198 } 4199 head = policydbp->ocontexts[OCON_NETIF]; 4200 4201 for (c = head; c; c = c->next) { 4202 if (!strcmp(newc->u.name, c->u.name)) { 4203 yyerror2("duplicate entry for network interface %s", 4204 newc->u.name); 4205 context_destroy(&newc->context[0]); 4206 context_destroy(&newc->context[1]); 4207 free(newc->u.name); 4208 free(newc); 4209 return -1; 4210 } 4211 } 4212 4213 newc->next = head; 4214 policydbp->ocontexts[OCON_NETIF] = newc; 4215 return 0; 4216} 4217 4218int define_ipv4_node_context() 4219{ 4220 char *id; 4221 int rc = 0; 4222 struct in_addr addr, mask; 4223 ocontext_t *newc, *c, *l, *head; 4224 4225 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 4226 yyerror("nodecon not supported for target"); 4227 return -1; 4228 } 4229 4230 if (pass == 1) { 4231 free(queue_remove(id_queue)); 4232 free(queue_remove(id_queue)); 4233 parse_security_context(NULL); 4234 goto out; 4235 } 4236 4237 id = queue_remove(id_queue); 4238 if (!id) { 4239 yyerror("failed to read ipv4 address"); 4240 rc = -1; 4241 goto out; 4242 } 4243 4244 rc = inet_pton(AF_INET, id, &addr); 4245 free(id); 4246 if (rc < 1) { 4247 yyerror("failed to parse ipv4 address"); 4248 if (rc == 0) 4249 rc = -1; 4250 goto out; 4251 } 4252 4253 id = queue_remove(id_queue); 4254 if (!id) { 4255 yyerror("failed to read ipv4 address"); 4256 rc = -1; 4257 goto out; 4258 } 4259 4260 rc = inet_pton(AF_INET, id, &mask); 4261 free(id); 4262 if (rc < 1) { 4263 yyerror("failed to parse ipv4 mask"); 4264 if (rc == 0) 4265 rc = -1; 4266 goto out; 4267 } 4268 4269 newc = malloc(sizeof(ocontext_t)); 4270 if (!newc) { 4271 yyerror("out of memory"); 4272 rc = -1; 4273 goto out; 4274 } 4275 4276 memset(newc, 0, sizeof(ocontext_t)); 4277 newc->u.node.addr = addr.s_addr; 4278 newc->u.node.mask = mask.s_addr; 4279 4280 if (parse_security_context(&newc->context[0])) { 4281 free(newc); 4282 return -1; 4283 } 4284 4285 /* Create order of most specific to least retaining 4286 the order specified in the configuration. */ 4287 head = policydbp->ocontexts[OCON_NODE]; 4288 for (l = NULL, c = head; c; l = c, c = c->next) { 4289 if (newc->u.node.mask > c->u.node.mask) 4290 break; 4291 } 4292 4293 newc->next = c; 4294 4295 if (l) 4296 l->next = newc; 4297 else 4298 policydbp->ocontexts[OCON_NODE] = newc; 4299 rc = 0; 4300out: 4301 return rc; 4302} 4303 4304int define_ipv6_node_context(void) 4305{ 4306 char *id; 4307 int rc = 0; 4308 struct in6_addr addr, mask; 4309 ocontext_t *newc, *c, *l, *head; 4310 4311 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 4312 yyerror("nodecon not supported for target"); 4313 return -1; 4314 } 4315 4316 if (pass == 1) { 4317 free(queue_remove(id_queue)); 4318 free(queue_remove(id_queue)); 4319 parse_security_context(NULL); 4320 goto out; 4321 } 4322 4323 id = queue_remove(id_queue); 4324 if (!id) { 4325 yyerror("failed to read ipv6 address"); 4326 rc = -1; 4327 goto out; 4328 } 4329 4330 rc = inet_pton(AF_INET6, id, &addr); 4331 free(id); 4332 if (rc < 1) { 4333 yyerror("failed to parse ipv6 address"); 4334 if (rc == 0) 4335 rc = -1; 4336 goto out; 4337 } 4338 4339 id = queue_remove(id_queue); 4340 if (!id) { 4341 yyerror("failed to read ipv6 address"); 4342 rc = -1; 4343 goto out; 4344 } 4345 4346 rc = inet_pton(AF_INET6, id, &mask); 4347 free(id); 4348 if (rc < 1) { 4349 yyerror("failed to parse ipv6 mask"); 4350 if (rc == 0) 4351 rc = -1; 4352 goto out; 4353 } 4354 4355 newc = malloc(sizeof(ocontext_t)); 4356 if (!newc) { 4357 yyerror("out of memory"); 4358 rc = -1; 4359 goto out; 4360 } 4361 4362 memset(newc, 0, sizeof(ocontext_t)); 4363 4364#ifdef DARWIN 4365 memcpy(&newc->u.node6.addr[0], &addr.s6_addr[0], 16); 4366 memcpy(&newc->u.node6.mask[0], &mask.s6_addr[0], 16); 4367#else 4368 memcpy(&newc->u.node6.addr[0], &addr.s6_addr32[0], 16); 4369 memcpy(&newc->u.node6.mask[0], &mask.s6_addr32[0], 16); 4370#endif 4371 4372 if (parse_security_context(&newc->context[0])) { 4373 free(newc); 4374 rc = -1; 4375 goto out; 4376 } 4377 4378 /* Create order of most specific to least retaining 4379 the order specified in the configuration. */ 4380 head = policydbp->ocontexts[OCON_NODE6]; 4381 for (l = NULL, c = head; c; l = c, c = c->next) { 4382 if (memcmp(&newc->u.node6.mask, &c->u.node6.mask, 16) > 0) 4383 break; 4384 } 4385 4386 newc->next = c; 4387 4388 if (l) 4389 l->next = newc; 4390 else 4391 policydbp->ocontexts[OCON_NODE6] = newc; 4392 4393 rc = 0; 4394 out: 4395 return rc; 4396} 4397 4398int define_fs_use(int behavior) 4399{ 4400 ocontext_t *newc, *c, *head; 4401 4402 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 4403 yyerror("fsuse not supported for target"); 4404 return -1; 4405 } 4406 4407 if (pass == 1) { 4408 free(queue_remove(id_queue)); 4409 parse_security_context(NULL); 4410 return 0; 4411 } 4412 4413 newc = (ocontext_t *) malloc(sizeof(ocontext_t)); 4414 if (!newc) { 4415 yyerror("out of memory"); 4416 return -1; 4417 } 4418 memset(newc, 0, sizeof(ocontext_t)); 4419 4420 newc->u.name = (char *)queue_remove(id_queue); 4421 if (!newc->u.name) { 4422 free(newc); 4423 return -1; 4424 } 4425 newc->v.behavior = behavior; 4426 if (parse_security_context(&newc->context[0])) { 4427 free(newc->u.name); 4428 free(newc); 4429 return -1; 4430 } 4431 4432 head = policydbp->ocontexts[OCON_FSUSE]; 4433 4434 for (c = head; c; c = c->next) { 4435 if (!strcmp(newc->u.name, c->u.name)) { 4436 yyerror2("duplicate fs_use entry for filesystem type %s", 4437 newc->u.name); 4438 context_destroy(&newc->context[0]); 4439 free(newc->u.name); 4440 free(newc); 4441 return -1; 4442 } 4443 } 4444 4445 newc->next = head; 4446 policydbp->ocontexts[OCON_FSUSE] = newc; 4447 return 0; 4448} 4449 4450int define_genfs_context_helper(char *fstype, int has_type) 4451{ 4452 struct genfs *genfs_p, *genfs, *newgenfs; 4453 ocontext_t *newc, *c, *head, *p; 4454 char *type = NULL; 4455 int len, len2; 4456 4457 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 4458 yyerror("genfs not supported for target"); 4459 return -1; 4460 } 4461 4462 if (pass == 1) { 4463 free(fstype); 4464 free(queue_remove(id_queue)); 4465 if (has_type) 4466 free(queue_remove(id_queue)); 4467 parse_security_context(NULL); 4468 return 0; 4469 } 4470 4471 for (genfs_p = NULL, genfs = policydbp->genfs; 4472 genfs; genfs_p = genfs, genfs = genfs->next) { 4473 if (strcmp(fstype, genfs->fstype) <= 0) 4474 break; 4475 } 4476 4477 if (!genfs || strcmp(fstype, genfs->fstype)) { 4478 newgenfs = malloc(sizeof(struct genfs)); 4479 if (!newgenfs) { 4480 yyerror("out of memory"); 4481 return -1; 4482 } 4483 memset(newgenfs, 0, sizeof(struct genfs)); 4484 newgenfs->fstype = fstype; 4485 newgenfs->next = genfs; 4486 if (genfs_p) 4487 genfs_p->next = newgenfs; 4488 else 4489 policydbp->genfs = newgenfs; 4490 genfs = newgenfs; 4491 } 4492 4493 newc = (ocontext_t *) malloc(sizeof(ocontext_t)); 4494 if (!newc) { 4495 yyerror("out of memory"); 4496 return -1; 4497 } 4498 memset(newc, 0, sizeof(ocontext_t)); 4499 4500 newc->u.name = (char *)queue_remove(id_queue); 4501 if (!newc->u.name) 4502 goto fail; 4503 if (has_type) { 4504 type = (char *)queue_remove(id_queue); 4505 if (!type) 4506 goto fail; 4507 if (type[1] != 0) { 4508 yyerror2("invalid type %s", type); 4509 goto fail; 4510 } 4511 switch (type[0]) { 4512 case 'b': 4513 newc->v.sclass = SECCLASS_BLK_FILE; 4514 break; 4515 case 'c': 4516 newc->v.sclass = SECCLASS_CHR_FILE; 4517 break; 4518 case 'd': 4519 newc->v.sclass = SECCLASS_DIR; 4520 break; 4521 case 'p': 4522 newc->v.sclass = SECCLASS_FIFO_FILE; 4523 break; 4524 case 'l': 4525 newc->v.sclass = SECCLASS_LNK_FILE; 4526 break; 4527 case 's': 4528 newc->v.sclass = SECCLASS_SOCK_FILE; 4529 break; 4530 case '-': 4531 newc->v.sclass = SECCLASS_FILE; 4532 break; 4533 default: 4534 yyerror2("invalid type %s", type); 4535 goto fail; 4536 } 4537 } 4538 if (parse_security_context(&newc->context[0])) 4539 goto fail; 4540 4541 head = genfs->head; 4542 4543 for (p = NULL, c = head; c; p = c, c = c->next) { 4544 if (!strcmp(newc->u.name, c->u.name) && 4545 (!newc->v.sclass || !c->v.sclass 4546 || newc->v.sclass == c->v.sclass)) { 4547 yyerror2("duplicate entry for genfs entry (%s, %s)", 4548 fstype, newc->u.name); 4549 goto fail; 4550 } 4551 len = strlen(newc->u.name); 4552 len2 = strlen(c->u.name); 4553 if (len > len2) 4554 break; 4555 } 4556 4557 newc->next = c; 4558 if (p) 4559 p->next = newc; 4560 else 4561 genfs->head = newc; 4562 return 0; 4563 fail: 4564 if (type) 4565 free(type); 4566 context_destroy(&newc->context[0]); 4567 if (fstype) 4568 free(fstype); 4569 if (newc->u.name) 4570 free(newc->u.name); 4571 free(newc); 4572 return -1; 4573} 4574 4575int define_genfs_context(int has_type) 4576{ 4577 return define_genfs_context_helper(queue_remove(id_queue), has_type); 4578} 4579 4580int define_range_trans(int class_specified) 4581{ 4582 char *id; 4583 level_datum_t *levdatum = 0; 4584 class_datum_t *cladatum; 4585 range_trans_rule_t *rule; 4586 int l, add = 1; 4587 4588 if (!mlspol) { 4589 yyerror("range_transition rule in non-MLS configuration"); 4590 return -1; 4591 } 4592 4593 if (pass == 1) { 4594 while ((id = queue_remove(id_queue))) 4595 free(id); 4596 while ((id = queue_remove(id_queue))) 4597 free(id); 4598 if (class_specified) 4599 while ((id = queue_remove(id_queue))) 4600 free(id); 4601 id = queue_remove(id_queue); 4602 free(id); 4603 for (l = 0; l < 2; l++) { 4604 while ((id = queue_remove(id_queue))) { 4605 free(id); 4606 } 4607 id = queue_remove(id_queue); 4608 if (!id) 4609 break; 4610 free(id); 4611 } 4612 return 0; 4613 } 4614 4615 rule = malloc(sizeof(struct range_trans_rule)); 4616 if (!rule) { 4617 yyerror("out of memory"); 4618 return -1; 4619 } 4620 range_trans_rule_init(rule); 4621 4622 while ((id = queue_remove(id_queue))) { 4623 if (set_types(&rule->stypes, id, &add, 0)) 4624 goto out; 4625 } 4626 add = 1; 4627 while ((id = queue_remove(id_queue))) { 4628 if (set_types(&rule->ttypes, id, &add, 0)) 4629 goto out; 4630 } 4631 4632 if (class_specified) { 4633 if (read_classes(&rule->tclasses)) 4634 goto out; 4635 } else { 4636 cladatum = hashtab_search(policydbp->p_classes.table, 4637 "process"); 4638 if (!cladatum) { 4639 yyerror2("could not find process class for " 4640 "legacy range_transition statement"); 4641 goto out; 4642 } 4643 4644 ebitmap_set_bit(&rule->tclasses, cladatum->s.value - 1, TRUE); 4645 } 4646 4647 id = (char *)queue_remove(id_queue); 4648 if (!id) { 4649 yyerror("no range in range_transition definition?"); 4650 goto out; 4651 } 4652 for (l = 0; l < 2; l++) { 4653 levdatum = hashtab_search(policydbp->p_levels.table, id); 4654 if (!levdatum) { 4655 yyerror2("unknown level %s used in range_transition " 4656 "definition", id); 4657 free(id); 4658 goto out; 4659 } 4660 free(id); 4661 4662 rule->trange.level[l].sens = levdatum->level->sens; 4663 4664 while ((id = queue_remove(id_queue))) { 4665 if (parse_semantic_categories(id, levdatum, 4666 &rule->trange.level[l].cat)) { 4667 free(id); 4668 goto out; 4669 } 4670 free(id); 4671 } 4672 4673 id = (char *)queue_remove(id_queue); 4674 if (!id) 4675 break; 4676 } 4677 if (l == 0) { 4678 if (mls_semantic_level_cpy(&rule->trange.level[1], 4679 &rule->trange.level[0])) { 4680 yyerror("out of memory"); 4681 goto out; 4682 } 4683 } 4684 4685 append_range_trans(rule); 4686 return 0; 4687 4688out: 4689 range_trans_rule_destroy(rule); 4690 free(rule); 4691 return -1; 4692} 4693 4694/* FLASK */ 4695