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