policy_define.c revision 49bfee8562b778129cb989bdf9014045e39b0916
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_rule_t *ftr; 3224 type_datum_t *typdatum; 3225 uint32_t otype; 3226 unsigned int c, s, t; 3227 int add; 3228 3229 if (pass == 1) { 3230 /* stype */ 3231 while ((id = queue_remove(id_queue))) 3232 free(id); 3233 /* ttype */ 3234 while ((id = queue_remove(id_queue))) 3235 free(id); 3236 /* tclass */ 3237 while ((id = queue_remove(id_queue))) 3238 free(id); 3239 /* otype */ 3240 id = queue_remove(id_queue); 3241 free(id); 3242 /* name */ 3243 id = queue_remove(id_queue); 3244 free(id); 3245 return 0; 3246 } 3247 3248 3249 add = 1; 3250 type_set_init(&stypes); 3251 while ((id = queue_remove(id_queue))) { 3252 if (set_types(&stypes, id, &add, 0)) 3253 goto bad; 3254 } 3255 3256 add =1; 3257 type_set_init(&ttypes); 3258 while ((id = queue_remove(id_queue))) { 3259 if (set_types(&ttypes, id, &add, 0)) 3260 goto bad; 3261 } 3262 3263 ebitmap_init(&e_tclasses); 3264 if (read_classes(&e_tclasses)) 3265 goto bad; 3266 3267 id = (char *)queue_remove(id_queue); 3268 if (!id) { 3269 yyerror("no otype in transition definition?"); 3270 goto bad; 3271 } 3272 if (!is_id_in_scope(SYM_TYPES, id)) { 3273 yyerror2("type %s is not within scope", id); 3274 free(id); 3275 goto bad; 3276 } 3277 typdatum = hashtab_search(policydbp->p_types.table, id); 3278 if (!typdatum) { 3279 yyerror2("unknown type %s used in transition definition", id); 3280 goto bad; 3281 } 3282 free(id); 3283 otype = typdatum->s.value; 3284 3285 name = queue_remove(id_queue); 3286 if (!name) { 3287 yyerror("no pathname specified in filename_trans definition?"); 3288 goto bad; 3289 } 3290 3291 /* We expand the class set into seperate rules. We expand the types 3292 * just to make sure there are not duplicates. They will get turned 3293 * into seperate rules later */ 3294 ebitmap_init(&e_stypes); 3295 if (type_set_expand(&stypes, &e_stypes, policydbp, 1)) 3296 goto bad; 3297 3298 ebitmap_init(&e_ttypes); 3299 if (type_set_expand(&ttypes, &e_ttypes, policydbp, 1)) 3300 goto bad; 3301 3302 ebitmap_for_each_bit(&e_tclasses, cnode, c) { 3303 if (!ebitmap_node_get_bit(cnode, c)) 3304 continue; 3305 ebitmap_for_each_bit(&e_stypes, snode, s) { 3306 if (!ebitmap_node_get_bit(snode, s)) 3307 continue; 3308 ebitmap_for_each_bit(&e_ttypes, tnode, t) { 3309 if (!ebitmap_node_get_bit(tnode, t)) 3310 continue; 3311 3312 for (ft = policydbp->filename_trans; ft; ft = ft->next) { 3313 if (ft->stype == (s + 1) && 3314 ft->ttype == (t + 1) && 3315 ft->tclass == (c + 1) && 3316 !strcmp(ft->name, name)) { 3317 yyerror2("duplicate filename transition for: filename_trans %s %s %s:%s", 3318 name, 3319 policydbp->p_type_val_to_name[s], 3320 policydbp->p_type_val_to_name[t], 3321 policydbp->p_class_val_to_name[c]); 3322 goto bad; 3323 } 3324 } 3325 3326 ft = malloc(sizeof(*ft)); 3327 if (!ft) { 3328 yyerror("out of memory"); 3329 goto bad; 3330 } 3331 memset(ft, 0, sizeof(*ft)); 3332 3333 ft->next = policydbp->filename_trans; 3334 policydbp->filename_trans = ft; 3335 3336 ft->name = strdup(name); 3337 if (!ft->name) { 3338 yyerror("out of memory"); 3339 goto bad; 3340 } 3341 ft->stype = s + 1; 3342 ft->ttype = t + 1; 3343 ft->tclass = c + 1; 3344 ft->otype = otype; 3345 } 3346 } 3347 3348 /* Now add the real rule since we didn't find any duplicates */ 3349 ftr = malloc(sizeof(*ftr)); 3350 if (!ftr) { 3351 yyerror("out of memory"); 3352 goto bad; 3353 } 3354 filename_trans_rule_init(ftr); 3355 append_filename_trans(ftr); 3356 3357 ftr->name = strdup(name); 3358 if (type_set_cpy(&ftr->stypes, &stypes)) { 3359 yyerror("out of memory"); 3360 goto bad; 3361 } 3362 if (type_set_cpy(&ftr->ttypes, &ttypes)) { 3363 yyerror("out of memory"); 3364 goto bad; 3365 } 3366 ftr->tclass = c + 1; 3367 ftr->otype = otype; 3368 } 3369 3370 free(name); 3371 ebitmap_destroy(&e_stypes); 3372 ebitmap_destroy(&e_ttypes); 3373 ebitmap_destroy(&e_tclasses); 3374 3375 return 0; 3376 3377bad: 3378 free(name); 3379 return -1; 3380} 3381 3382static constraint_expr_t *constraint_expr_clone(constraint_expr_t * expr) 3383{ 3384 constraint_expr_t *h = NULL, *l = NULL, *e, *newe; 3385 for (e = expr; e; e = e->next) { 3386 newe = malloc(sizeof(*newe)); 3387 if (!newe) 3388 goto oom; 3389 if (constraint_expr_init(newe) == -1) { 3390 free(newe); 3391 goto oom; 3392 } 3393 if (l) 3394 l->next = newe; 3395 else 3396 h = newe; 3397 l = newe; 3398 newe->expr_type = e->expr_type; 3399 newe->attr = e->attr; 3400 newe->op = e->op; 3401 if (newe->expr_type == CEXPR_NAMES) { 3402 if (newe->attr & CEXPR_TYPE) { 3403 if (type_set_cpy 3404 (newe->type_names, e->type_names)) 3405 goto oom; 3406 } else { 3407 if (ebitmap_cpy(&newe->names, &e->names)) 3408 goto oom; 3409 } 3410 } 3411 } 3412 3413 return h; 3414 oom: 3415 e = h; 3416 while (e) { 3417 l = e; 3418 e = e->next; 3419 constraint_expr_destroy(l); 3420 } 3421 return NULL; 3422} 3423 3424int define_constraint(constraint_expr_t * expr) 3425{ 3426 struct constraint_node *node; 3427 char *id; 3428 class_datum_t *cladatum; 3429 perm_datum_t *perdatum; 3430 ebitmap_t classmap; 3431 ebitmap_node_t *enode; 3432 constraint_expr_t *e; 3433 unsigned int i; 3434 int depth; 3435 unsigned char useexpr = 1; 3436 3437 if (pass == 1) { 3438 while ((id = queue_remove(id_queue))) 3439 free(id); 3440 while ((id = queue_remove(id_queue))) 3441 free(id); 3442 return 0; 3443 } 3444 3445 depth = -1; 3446 for (e = expr; e; e = e->next) { 3447 switch (e->expr_type) { 3448 case CEXPR_NOT: 3449 if (depth < 0) { 3450 yyerror("illegal constraint expression"); 3451 return -1; 3452 } 3453 break; 3454 case CEXPR_AND: 3455 case CEXPR_OR: 3456 if (depth < 1) { 3457 yyerror("illegal constraint expression"); 3458 return -1; 3459 } 3460 depth--; 3461 break; 3462 case CEXPR_ATTR: 3463 case CEXPR_NAMES: 3464 if (e->attr & CEXPR_XTARGET) { 3465 yyerror("illegal constraint expression"); 3466 return -1; /* only for validatetrans rules */ 3467 } 3468 if (depth == (CEXPR_MAXDEPTH - 1)) { 3469 yyerror("constraint expression is too deep"); 3470 return -1; 3471 } 3472 depth++; 3473 break; 3474 default: 3475 yyerror("illegal constraint expression"); 3476 return -1; 3477 } 3478 } 3479 if (depth != 0) { 3480 yyerror("illegal constraint expression"); 3481 return -1; 3482 } 3483 3484 ebitmap_init(&classmap); 3485 while ((id = queue_remove(id_queue))) { 3486 if (!is_id_in_scope(SYM_CLASSES, id)) { 3487 yyerror2("class %s is not within scope", id); 3488 free(id); 3489 return -1; 3490 } 3491 cladatum = 3492 (class_datum_t *) hashtab_search(policydbp->p_classes.table, 3493 (hashtab_key_t) id); 3494 if (!cladatum) { 3495 yyerror2("class %s is not defined", id); 3496 ebitmap_destroy(&classmap); 3497 free(id); 3498 return -1; 3499 } 3500 if (ebitmap_set_bit(&classmap, cladatum->s.value - 1, TRUE)) { 3501 yyerror("out of memory"); 3502 ebitmap_destroy(&classmap); 3503 free(id); 3504 return -1; 3505 } 3506 node = malloc(sizeof(struct constraint_node)); 3507 if (!node) { 3508 yyerror("out of memory"); 3509 free(node); 3510 return -1; 3511 } 3512 memset(node, 0, sizeof(constraint_node_t)); 3513 if (useexpr) { 3514 node->expr = expr; 3515 useexpr = 0; 3516 } else { 3517 node->expr = constraint_expr_clone(expr); 3518 } 3519 if (!node->expr) { 3520 yyerror("out of memory"); 3521 free(node); 3522 return -1; 3523 } 3524 node->permissions = 0; 3525 3526 node->next = cladatum->constraints; 3527 cladatum->constraints = node; 3528 3529 free(id); 3530 } 3531 3532 while ((id = queue_remove(id_queue))) { 3533 ebitmap_for_each_bit(&classmap, enode, i) { 3534 if (ebitmap_node_get_bit(enode, i)) { 3535 cladatum = policydbp->class_val_to_struct[i]; 3536 node = cladatum->constraints; 3537 3538 perdatum = 3539 (perm_datum_t *) hashtab_search(cladatum-> 3540 permissions. 3541 table, 3542 (hashtab_key_t) 3543 id); 3544 if (!perdatum) { 3545 if (cladatum->comdatum) { 3546 perdatum = 3547 (perm_datum_t *) 3548 hashtab_search(cladatum-> 3549 comdatum-> 3550 permissions. 3551 table, 3552 (hashtab_key_t) 3553 id); 3554 } 3555 if (!perdatum) { 3556 yyerror2("permission %s is not" 3557 " defined", id); 3558 free(id); 3559 ebitmap_destroy(&classmap); 3560 return -1; 3561 } 3562 } 3563 node->permissions |= 3564 (1 << (perdatum->s.value - 1)); 3565 } 3566 } 3567 free(id); 3568 } 3569 3570 ebitmap_destroy(&classmap); 3571 3572 return 0; 3573} 3574 3575int define_validatetrans(constraint_expr_t * expr) 3576{ 3577 struct constraint_node *node; 3578 char *id; 3579 class_datum_t *cladatum; 3580 ebitmap_t classmap; 3581 constraint_expr_t *e; 3582 int depth; 3583 unsigned char useexpr = 1; 3584 3585 if (pass == 1) { 3586 while ((id = queue_remove(id_queue))) 3587 free(id); 3588 return 0; 3589 } 3590 3591 depth = -1; 3592 for (e = expr; e; e = e->next) { 3593 switch (e->expr_type) { 3594 case CEXPR_NOT: 3595 if (depth < 0) { 3596 yyerror("illegal validatetrans expression"); 3597 return -1; 3598 } 3599 break; 3600 case CEXPR_AND: 3601 case CEXPR_OR: 3602 if (depth < 1) { 3603 yyerror("illegal validatetrans expression"); 3604 return -1; 3605 } 3606 depth--; 3607 break; 3608 case CEXPR_ATTR: 3609 case CEXPR_NAMES: 3610 if (depth == (CEXPR_MAXDEPTH - 1)) { 3611 yyerror("validatetrans expression is too deep"); 3612 return -1; 3613 } 3614 depth++; 3615 break; 3616 default: 3617 yyerror("illegal validatetrans expression"); 3618 return -1; 3619 } 3620 } 3621 if (depth != 0) { 3622 yyerror("illegal validatetrans expression"); 3623 return -1; 3624 } 3625 3626 ebitmap_init(&classmap); 3627 while ((id = queue_remove(id_queue))) { 3628 if (!is_id_in_scope(SYM_CLASSES, id)) { 3629 yyerror2("class %s is not within scope", id); 3630 free(id); 3631 return -1; 3632 } 3633 cladatum = 3634 (class_datum_t *) hashtab_search(policydbp->p_classes.table, 3635 (hashtab_key_t) id); 3636 if (!cladatum) { 3637 yyerror2("class %s is not defined", id); 3638 ebitmap_destroy(&classmap); 3639 free(id); 3640 return -1; 3641 } 3642 if (ebitmap_set_bit(&classmap, (cladatum->s.value - 1), TRUE)) { 3643 yyerror("out of memory"); 3644 ebitmap_destroy(&classmap); 3645 free(id); 3646 return -1; 3647 } 3648 3649 node = malloc(sizeof(struct constraint_node)); 3650 if (!node) { 3651 yyerror("out of memory"); 3652 return -1; 3653 } 3654 memset(node, 0, sizeof(constraint_node_t)); 3655 if (useexpr) { 3656 node->expr = expr; 3657 useexpr = 0; 3658 } else { 3659 node->expr = constraint_expr_clone(expr); 3660 } 3661 node->permissions = 0; 3662 3663 node->next = cladatum->validatetrans; 3664 cladatum->validatetrans = node; 3665 3666 free(id); 3667 } 3668 3669 ebitmap_destroy(&classmap); 3670 3671 return 0; 3672} 3673 3674uintptr_t define_cexpr(uint32_t expr_type, uintptr_t arg1, uintptr_t arg2) 3675{ 3676 struct constraint_expr *expr, *e1 = NULL, *e2; 3677 user_datum_t *user; 3678 role_datum_t *role; 3679 ebitmap_t negset; 3680 char *id; 3681 uint32_t val; 3682 int add = 1; 3683 3684 if (pass == 1) { 3685 if (expr_type == CEXPR_NAMES) { 3686 while ((id = queue_remove(id_queue))) 3687 free(id); 3688 } 3689 return 1; /* any non-NULL value */ 3690 } 3691 3692 if ((expr = malloc(sizeof(*expr))) == NULL || 3693 constraint_expr_init(expr) == -1) { 3694 yyerror("out of memory"); 3695 free(expr); 3696 return 0; 3697 } 3698 expr->expr_type = expr_type; 3699 3700 switch (expr_type) { 3701 case CEXPR_NOT: 3702 e1 = NULL; 3703 e2 = (struct constraint_expr *)arg1; 3704 while (e2) { 3705 e1 = e2; 3706 e2 = e2->next; 3707 } 3708 if (!e1 || e1->next) { 3709 yyerror("illegal constraint expression"); 3710 constraint_expr_destroy(expr); 3711 return 0; 3712 } 3713 e1->next = expr; 3714 return arg1; 3715 case CEXPR_AND: 3716 case CEXPR_OR: 3717 e1 = NULL; 3718 e2 = (struct constraint_expr *)arg1; 3719 while (e2) { 3720 e1 = e2; 3721 e2 = e2->next; 3722 } 3723 if (!e1 || e1->next) { 3724 yyerror("illegal constraint expression"); 3725 constraint_expr_destroy(expr); 3726 return 0; 3727 } 3728 e1->next = (struct constraint_expr *)arg2; 3729 3730 e1 = NULL; 3731 e2 = (struct constraint_expr *)arg2; 3732 while (e2) { 3733 e1 = e2; 3734 e2 = e2->next; 3735 } 3736 if (!e1 || e1->next) { 3737 yyerror("illegal constraint expression"); 3738 constraint_expr_destroy(expr); 3739 return 0; 3740 } 3741 e1->next = expr; 3742 return arg1; 3743 case CEXPR_ATTR: 3744 expr->attr = arg1; 3745 expr->op = arg2; 3746 return (uintptr_t) expr; 3747 case CEXPR_NAMES: 3748 add = 1; 3749 expr->attr = arg1; 3750 expr->op = arg2; 3751 ebitmap_init(&negset); 3752 while ((id = (char *)queue_remove(id_queue))) { 3753 if (expr->attr & CEXPR_USER) { 3754 if (!is_id_in_scope(SYM_USERS, id)) { 3755 yyerror2("user %s is not within scope", 3756 id); 3757 constraint_expr_destroy(expr); 3758 return 0; 3759 } 3760 user = 3761 (user_datum_t *) hashtab_search(policydbp-> 3762 p_users. 3763 table, 3764 (hashtab_key_t) 3765 id); 3766 if (!user) { 3767 yyerror2("unknown user %s", id); 3768 constraint_expr_destroy(expr); 3769 return 0; 3770 } 3771 val = user->s.value; 3772 } else if (expr->attr & CEXPR_ROLE) { 3773 if (!is_id_in_scope(SYM_ROLES, id)) { 3774 yyerror2("role %s is not within scope", 3775 id); 3776 constraint_expr_destroy(expr); 3777 return 0; 3778 } 3779 role = 3780 (role_datum_t *) hashtab_search(policydbp-> 3781 p_roles. 3782 table, 3783 (hashtab_key_t) 3784 id); 3785 if (!role) { 3786 yyerror2("unknown role %s", id); 3787 constraint_expr_destroy(expr); 3788 return 0; 3789 } 3790 val = role->s.value; 3791 } else if (expr->attr & CEXPR_TYPE) { 3792 if (set_types(expr->type_names, id, &add, 0)) { 3793 constraint_expr_destroy(expr); 3794 return 0; 3795 } 3796 continue; 3797 } else { 3798 yyerror("invalid constraint expression"); 3799 constraint_expr_destroy(expr); 3800 return 0; 3801 } 3802 if (ebitmap_set_bit(&expr->names, val - 1, TRUE)) { 3803 yyerror("out of memory"); 3804 ebitmap_destroy(&expr->names); 3805 constraint_expr_destroy(expr); 3806 return 0; 3807 } 3808 free(id); 3809 } 3810 ebitmap_destroy(&negset); 3811 return (uintptr_t) expr; 3812 default: 3813 break; 3814 } 3815 3816 yyerror("invalid constraint expression"); 3817 constraint_expr_destroy(expr); 3818 return 0; 3819} 3820 3821int define_conditional(cond_expr_t * expr, avrule_t * t, avrule_t * f) 3822{ 3823 cond_expr_t *e; 3824 int depth; 3825 cond_node_t cn, *cn_old; 3826 3827 /* expression cannot be NULL */ 3828 if (!expr) { 3829 yyerror("illegal conditional expression"); 3830 return -1; 3831 } 3832 if (!t) { 3833 if (!f) { 3834 /* empty is fine, destroy expression and return */ 3835 cond_expr_destroy(expr); 3836 return 0; 3837 } 3838 /* Invert */ 3839 t = f; 3840 f = 0; 3841 expr = define_cond_expr(COND_NOT, expr, 0); 3842 if (!expr) { 3843 yyerror("unable to invert"); 3844 return -1; 3845 } 3846 } 3847 3848 /* verify expression */ 3849 depth = -1; 3850 for (e = expr; e; e = e->next) { 3851 switch (e->expr_type) { 3852 case COND_NOT: 3853 if (depth < 0) { 3854 yyerror 3855 ("illegal conditional expression; Bad NOT"); 3856 return -1; 3857 } 3858 break; 3859 case COND_AND: 3860 case COND_OR: 3861 case COND_XOR: 3862 case COND_EQ: 3863 case COND_NEQ: 3864 if (depth < 1) { 3865 yyerror 3866 ("illegal conditional expression; Bad binary op"); 3867 return -1; 3868 } 3869 depth--; 3870 break; 3871 case COND_BOOL: 3872 if (depth == (COND_EXPR_MAXDEPTH - 1)) { 3873 yyerror 3874 ("conditional expression is like totally too deep"); 3875 return -1; 3876 } 3877 depth++; 3878 break; 3879 default: 3880 yyerror("illegal conditional expression"); 3881 return -1; 3882 } 3883 } 3884 if (depth != 0) { 3885 yyerror("illegal conditional expression"); 3886 return -1; 3887 } 3888 3889 /* use tmp conditional node to partially build new node */ 3890 memset(&cn, 0, sizeof(cn)); 3891 cn.expr = expr; 3892 cn.avtrue_list = t; 3893 cn.avfalse_list = f; 3894 3895 /* normalize/precompute expression */ 3896 if (cond_normalize_expr(policydbp, &cn) < 0) { 3897 yyerror("problem normalizing conditional expression"); 3898 return -1; 3899 } 3900 3901 /* get the existing conditional node, or create a new one */ 3902 cn_old = get_current_cond_list(&cn); 3903 if (!cn_old) { 3904 return -1; 3905 } 3906 3907 append_cond_list(&cn); 3908 3909 /* note that there is no check here for duplicate rules, nor 3910 * check that rule already exists in base -- that will be 3911 * handled during conditional expansion, in expand.c */ 3912 3913 cn.avtrue_list = NULL; 3914 cn.avfalse_list = NULL; 3915 cond_node_destroy(&cn); 3916 3917 return 0; 3918} 3919 3920cond_expr_t *define_cond_expr(uint32_t expr_type, void *arg1, void *arg2) 3921{ 3922 struct cond_expr *expr, *e1 = NULL, *e2; 3923 cond_bool_datum_t *bool_var; 3924 char *id; 3925 3926 /* expressions are handled in the second pass */ 3927 if (pass == 1) { 3928 if (expr_type == COND_BOOL) { 3929 while ((id = queue_remove(id_queue))) { 3930 free(id); 3931 } 3932 } 3933 return (cond_expr_t *) 1; /* any non-NULL value */ 3934 } 3935 3936 /* create a new expression struct */ 3937 expr = malloc(sizeof(struct cond_expr)); 3938 if (!expr) { 3939 yyerror("out of memory"); 3940 return NULL; 3941 } 3942 memset(expr, 0, sizeof(cond_expr_t)); 3943 expr->expr_type = expr_type; 3944 3945 /* create the type asked for */ 3946 switch (expr_type) { 3947 case COND_NOT: 3948 e1 = NULL; 3949 e2 = (struct cond_expr *)arg1; 3950 while (e2) { 3951 e1 = e2; 3952 e2 = e2->next; 3953 } 3954 if (!e1 || e1->next) { 3955 yyerror("illegal conditional NOT expression"); 3956 free(expr); 3957 return NULL; 3958 } 3959 e1->next = expr; 3960 return (struct cond_expr *)arg1; 3961 case COND_AND: 3962 case COND_OR: 3963 case COND_XOR: 3964 case COND_EQ: 3965 case COND_NEQ: 3966 e1 = NULL; 3967 e2 = (struct cond_expr *)arg1; 3968 while (e2) { 3969 e1 = e2; 3970 e2 = e2->next; 3971 } 3972 if (!e1 || e1->next) { 3973 yyerror 3974 ("illegal left side of conditional binary op expression"); 3975 free(expr); 3976 return NULL; 3977 } 3978 e1->next = (struct cond_expr *)arg2; 3979 3980 e1 = NULL; 3981 e2 = (struct cond_expr *)arg2; 3982 while (e2) { 3983 e1 = e2; 3984 e2 = e2->next; 3985 } 3986 if (!e1 || e1->next) { 3987 yyerror 3988 ("illegal right side of conditional binary op expression"); 3989 free(expr); 3990 return NULL; 3991 } 3992 e1->next = expr; 3993 return (struct cond_expr *)arg1; 3994 case COND_BOOL: 3995 id = (char *)queue_remove(id_queue); 3996 if (!id) { 3997 yyerror("bad conditional; expected boolean id"); 3998 free(id); 3999 free(expr); 4000 return NULL; 4001 } 4002 if (!is_id_in_scope(SYM_BOOLS, id)) { 4003 yyerror2("boolean %s is not within scope", id); 4004 free(id); 4005 free(expr); 4006 return NULL; 4007 } 4008 bool_var = 4009 (cond_bool_datum_t *) hashtab_search(policydbp->p_bools. 4010 table, 4011 (hashtab_key_t) id); 4012 if (!bool_var) { 4013 yyerror2("unknown boolean %s in conditional expression", 4014 id); 4015 free(expr); 4016 free(id); 4017 return NULL; 4018 } 4019 expr->bool = bool_var->s.value; 4020 free(id); 4021 return expr; 4022 default: 4023 yyerror("illegal conditional expression"); 4024 free(expr); 4025 return NULL; 4026 } 4027} 4028 4029static int set_user_roles(role_set_t * set, char *id) 4030{ 4031 role_datum_t *r; 4032 unsigned int i; 4033 ebitmap_node_t *node; 4034 4035 if (strcmp(id, "*") == 0) { 4036 free(id); 4037 yyerror("* is not allowed in user declarations"); 4038 return -1; 4039 } 4040 4041 if (strcmp(id, "~") == 0) { 4042 free(id); 4043 yyerror("~ is not allowed in user declarations"); 4044 return -1; 4045 } 4046 4047 if (!is_id_in_scope(SYM_ROLES, id)) { 4048 yyerror2("role %s is not within scope", id); 4049 free(id); 4050 return -1; 4051 } 4052 r = hashtab_search(policydbp->p_roles.table, id); 4053 if (!r) { 4054 yyerror2("unknown role %s", id); 4055 free(id); 4056 return -1; 4057 } 4058 4059 /* set the role and every role it dominates */ 4060 ebitmap_for_each_bit(&r->dominates, node, i) { 4061 if (ebitmap_node_get_bit(node, i)) 4062 if (ebitmap_set_bit(&set->roles, i, TRUE)) 4063 goto oom; 4064 } 4065 free(id); 4066 return 0; 4067 oom: 4068 yyerror("out of memory"); 4069 return -1; 4070} 4071 4072static int parse_categories(char *id, level_datum_t * levdatum, ebitmap_t * cats) 4073{ 4074 cat_datum_t *cdatum; 4075 int range_start, range_end, i; 4076 4077 if (id_has_dot(id)) { 4078 char *id_start = id; 4079 char *id_end = strchr(id, '.'); 4080 4081 *(id_end++) = '\0'; 4082 4083 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 4084 (hashtab_key_t) 4085 id_start); 4086 if (!cdatum) { 4087 yyerror2("unknown category %s", id_start); 4088 return -1; 4089 } 4090 range_start = cdatum->s.value - 1; 4091 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 4092 (hashtab_key_t) id_end); 4093 if (!cdatum) { 4094 yyerror2("unknown category %s", id_end); 4095 return -1; 4096 } 4097 range_end = cdatum->s.value - 1; 4098 4099 if (range_end < range_start) { 4100 yyerror2("category range is invalid"); 4101 return -1; 4102 } 4103 } else { 4104 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 4105 (hashtab_key_t) id); 4106 if (!cdatum) { 4107 yyerror2("unknown category %s", id); 4108 return -1; 4109 } 4110 range_start = range_end = cdatum->s.value - 1; 4111 } 4112 4113 for (i = range_start; i <= range_end; i++) { 4114 if (!ebitmap_get_bit(&levdatum->level->cat, i)) { 4115 uint32_t level_value = levdatum->level->sens - 1; 4116 policydb_index_others(NULL, policydbp, 0); 4117 yyerror2("category %s can not be associated " 4118 "with level %s", 4119 policydbp->p_cat_val_to_name[i], 4120 policydbp->p_sens_val_to_name[level_value]); 4121 return -1; 4122 } 4123 if (ebitmap_set_bit(cats, i, TRUE)) { 4124 yyerror("out of memory"); 4125 return -1; 4126 } 4127 } 4128 4129 return 0; 4130} 4131 4132static int parse_semantic_categories(char *id, level_datum_t * levdatum __attribute__ ((unused)), 4133 mls_semantic_cat_t ** cats) 4134{ 4135 cat_datum_t *cdatum; 4136 mls_semantic_cat_t *newcat; 4137 unsigned int range_start, range_end; 4138 4139 if (id_has_dot(id)) { 4140 char *id_start = id; 4141 char *id_end = strchr(id, '.'); 4142 4143 *(id_end++) = '\0'; 4144 4145 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 4146 (hashtab_key_t) 4147 id_start); 4148 if (!cdatum) { 4149 yyerror2("unknown category %s", id_start); 4150 return -1; 4151 } 4152 range_start = cdatum->s.value; 4153 4154 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 4155 (hashtab_key_t) id_end); 4156 if (!cdatum) { 4157 yyerror2("unknown category %s", id_end); 4158 return -1; 4159 } 4160 range_end = cdatum->s.value; 4161 } else { 4162 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 4163 (hashtab_key_t) id); 4164 if (!cdatum) { 4165 yyerror2("unknown category %s", id); 4166 return -1; 4167 } 4168 range_start = range_end = cdatum->s.value; 4169 } 4170 4171 newcat = (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t)); 4172 if (!newcat) { 4173 yyerror("out of memory"); 4174 return -1; 4175 } 4176 4177 mls_semantic_cat_init(newcat); 4178 newcat->next = *cats; 4179 newcat->low = range_start; 4180 newcat->high = range_end; 4181 4182 *cats = newcat; 4183 4184 return 0; 4185} 4186 4187int define_user(void) 4188{ 4189 char *id; 4190 user_datum_t *usrdatum; 4191 level_datum_t *levdatum; 4192 int l; 4193 4194 if (pass == 1) { 4195 while ((id = queue_remove(id_queue))) 4196 free(id); 4197 if (mlspol) { 4198 while ((id = queue_remove(id_queue))) 4199 free(id); 4200 id = queue_remove(id_queue); 4201 free(id); 4202 for (l = 0; l < 2; l++) { 4203 while ((id = queue_remove(id_queue))) { 4204 free(id); 4205 } 4206 id = queue_remove(id_queue); 4207 if (!id) 4208 break; 4209 free(id); 4210 } 4211 } 4212 return 0; 4213 } 4214 4215 if ((usrdatum = declare_user()) == NULL) { 4216 return -1; 4217 } 4218 4219 while ((id = queue_remove(id_queue))) { 4220 if (set_user_roles(&usrdatum->roles, id)) 4221 continue; 4222 } 4223 4224 if (mlspol) { 4225 id = queue_remove(id_queue); 4226 if (!id) { 4227 yyerror("no default level specified for user"); 4228 return -1; 4229 } 4230 4231 levdatum = (level_datum_t *) 4232 hashtab_search(policydbp->p_levels.table, 4233 (hashtab_key_t) id); 4234 if (!levdatum) { 4235 yyerror2("unknown sensitivity %s used in user" 4236 " level definition", id); 4237 free(id); 4238 return -1; 4239 } 4240 free(id); 4241 4242 usrdatum->dfltlevel.sens = levdatum->level->sens; 4243 4244 while ((id = queue_remove(id_queue))) { 4245 if (parse_semantic_categories(id, levdatum, 4246 &usrdatum->dfltlevel.cat)) { 4247 free(id); 4248 return -1; 4249 } 4250 free(id); 4251 } 4252 4253 id = queue_remove(id_queue); 4254 4255 for (l = 0; l < 2; l++) { 4256 levdatum = (level_datum_t *) 4257 hashtab_search(policydbp->p_levels.table, 4258 (hashtab_key_t) id); 4259 if (!levdatum) { 4260 yyerror2("unknown sensitivity %s used in user" 4261 " range definition", id); 4262 free(id); 4263 return -1; 4264 } 4265 free(id); 4266 4267 usrdatum->range.level[l].sens = levdatum->level->sens; 4268 4269 while ((id = queue_remove(id_queue))) { 4270 if (parse_semantic_categories(id, levdatum, 4271 &usrdatum->range.level[l].cat)) { 4272 free(id); 4273 return -1; 4274 } 4275 free(id); 4276 } 4277 4278 id = queue_remove(id_queue); 4279 if (!id) 4280 break; 4281 } 4282 4283 if (l == 0) { 4284 if (mls_semantic_level_cpy(&usrdatum->range.level[1], 4285 &usrdatum->range.level[0])) { 4286 yyerror("out of memory"); 4287 return -1; 4288 } 4289 } 4290 } 4291 return 0; 4292} 4293 4294static int parse_security_context(context_struct_t * c) 4295{ 4296 char *id; 4297 role_datum_t *role; 4298 type_datum_t *typdatum; 4299 user_datum_t *usrdatum; 4300 level_datum_t *levdatum; 4301 int l; 4302 4303 if (pass == 1) { 4304 id = queue_remove(id_queue); 4305 free(id); /* user */ 4306 id = queue_remove(id_queue); 4307 free(id); /* role */ 4308 id = queue_remove(id_queue); 4309 free(id); /* type */ 4310 if (mlspol) { 4311 id = queue_remove(id_queue); 4312 free(id); 4313 for (l = 0; l < 2; l++) { 4314 while ((id = queue_remove(id_queue))) { 4315 free(id); 4316 } 4317 id = queue_remove(id_queue); 4318 if (!id) 4319 break; 4320 free(id); 4321 } 4322 } 4323 return 0; 4324 } 4325 4326 /* check context c to make sure ok to dereference c later */ 4327 if (c == NULL) { 4328 yyerror("null context pointer!"); 4329 return -1; 4330 } 4331 4332 context_init(c); 4333 4334 /* extract the user */ 4335 id = queue_remove(id_queue); 4336 if (!id) { 4337 yyerror("no effective user?"); 4338 goto bad; 4339 } 4340 if (!is_id_in_scope(SYM_USERS, id)) { 4341 yyerror2("user %s is not within scope", id); 4342 free(id); 4343 goto bad; 4344 } 4345 usrdatum = (user_datum_t *) hashtab_search(policydbp->p_users.table, 4346 (hashtab_key_t) id); 4347 if (!usrdatum) { 4348 yyerror2("user %s is not defined", id); 4349 free(id); 4350 goto bad; 4351 } 4352 c->user = usrdatum->s.value; 4353 4354 /* no need to keep the user name */ 4355 free(id); 4356 4357 /* extract the role */ 4358 id = (char *)queue_remove(id_queue); 4359 if (!id) { 4360 yyerror("no role name for sid context definition?"); 4361 return -1; 4362 } 4363 if (!is_id_in_scope(SYM_ROLES, id)) { 4364 yyerror2("role %s is not within scope", id); 4365 free(id); 4366 return -1; 4367 } 4368 role = (role_datum_t *) hashtab_search(policydbp->p_roles.table, 4369 (hashtab_key_t) id); 4370 if (!role) { 4371 yyerror2("role %s is not defined", id); 4372 free(id); 4373 return -1; 4374 } 4375 c->role = role->s.value; 4376 4377 /* no need to keep the role name */ 4378 free(id); 4379 4380 /* extract the type */ 4381 id = (char *)queue_remove(id_queue); 4382 if (!id) { 4383 yyerror("no type name for sid context definition?"); 4384 return -1; 4385 } 4386 if (!is_id_in_scope(SYM_TYPES, id)) { 4387 yyerror2("type %s is not within scope", id); 4388 free(id); 4389 return -1; 4390 } 4391 typdatum = (type_datum_t *) hashtab_search(policydbp->p_types.table, 4392 (hashtab_key_t) id); 4393 if (!typdatum || typdatum->flavor == TYPE_ATTRIB) { 4394 yyerror2("type %s is not defined or is an attribute", id); 4395 free(id); 4396 return -1; 4397 } 4398 c->type = typdatum->s.value; 4399 4400 /* no need to keep the type name */ 4401 free(id); 4402 4403 if (mlspol) { 4404 /* extract the low sensitivity */ 4405 id = (char *)queue_head(id_queue); 4406 if (!id) { 4407 yyerror("no sensitivity name for sid context" 4408 " definition?"); 4409 return -1; 4410 } 4411 4412 id = (char *)queue_remove(id_queue); 4413 for (l = 0; l < 2; l++) { 4414 levdatum = (level_datum_t *) 4415 hashtab_search(policydbp->p_levels.table, 4416 (hashtab_key_t) id); 4417 if (!levdatum) { 4418 yyerror2("Sensitivity %s is not defined", id); 4419 free(id); 4420 return -1; 4421 } 4422 free(id); 4423 c->range.level[l].sens = levdatum->level->sens; 4424 4425 /* extract low category set */ 4426 while ((id = queue_remove(id_queue))) { 4427 if (parse_categories(id, levdatum, 4428 &c->range.level[l].cat)) { 4429 free(id); 4430 return -1; 4431 } 4432 free(id); 4433 } 4434 4435 /* extract high sensitivity */ 4436 id = (char *)queue_remove(id_queue); 4437 if (!id) 4438 break; 4439 } 4440 4441 if (l == 0) { 4442 c->range.level[1].sens = c->range.level[0].sens; 4443 if (ebitmap_cpy(&c->range.level[1].cat, 4444 &c->range.level[0].cat)) { 4445 4446 yyerror("out of memory"); 4447 goto bad; 4448 } 4449 } 4450 } 4451 4452 if (!policydb_context_isvalid(policydbp, c)) { 4453 yyerror("invalid security context"); 4454 goto bad; 4455 } 4456 return 0; 4457 4458 bad: 4459 context_destroy(c); 4460 4461 return -1; 4462} 4463 4464int define_initial_sid_context(void) 4465{ 4466 char *id; 4467 ocontext_t *c, *head; 4468 4469 if (pass == 1) { 4470 id = (char *)queue_remove(id_queue); 4471 free(id); 4472 parse_security_context(NULL); 4473 return 0; 4474 } 4475 4476 id = (char *)queue_remove(id_queue); 4477 if (!id) { 4478 yyerror("no sid name for SID context definition?"); 4479 return -1; 4480 } 4481 head = policydbp->ocontexts[OCON_ISID]; 4482 for (c = head; c; c = c->next) { 4483 if (!strcmp(id, c->u.name)) 4484 break; 4485 } 4486 4487 if (!c) { 4488 yyerror2("SID %s is not defined", id); 4489 free(id); 4490 return -1; 4491 } 4492 if (c->context[0].user) { 4493 yyerror2("The context for SID %s is multiply defined", id); 4494 free(id); 4495 return -1; 4496 } 4497 /* no need to keep the sid name */ 4498 free(id); 4499 4500 if (parse_security_context(&c->context[0])) 4501 return -1; 4502 4503 return 0; 4504} 4505 4506int define_fs_context(unsigned int major, unsigned int minor) 4507{ 4508 ocontext_t *newc, *c, *head; 4509 4510 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 4511 yyerror("fscon not supported for target"); 4512 return -1; 4513 } 4514 4515 if (pass == 1) { 4516 parse_security_context(NULL); 4517 parse_security_context(NULL); 4518 return 0; 4519 } 4520 4521 newc = (ocontext_t *) malloc(sizeof(ocontext_t)); 4522 if (!newc) { 4523 yyerror("out of memory"); 4524 return -1; 4525 } 4526 memset(newc, 0, sizeof(ocontext_t)); 4527 4528 newc->u.name = (char *)malloc(6); 4529 if (!newc->u.name) { 4530 yyerror("out of memory"); 4531 free(newc); 4532 return -1; 4533 } 4534 sprintf(newc->u.name, "%02x:%02x", major, minor); 4535 4536 if (parse_security_context(&newc->context[0])) { 4537 free(newc->u.name); 4538 free(newc); 4539 return -1; 4540 } 4541 if (parse_security_context(&newc->context[1])) { 4542 context_destroy(&newc->context[0]); 4543 free(newc->u.name); 4544 free(newc); 4545 return -1; 4546 } 4547 head = policydbp->ocontexts[OCON_FS]; 4548 4549 for (c = head; c; c = c->next) { 4550 if (!strcmp(newc->u.name, c->u.name)) { 4551 yyerror2("duplicate entry for file system %s", 4552 newc->u.name); 4553 context_destroy(&newc->context[0]); 4554 context_destroy(&newc->context[1]); 4555 free(newc->u.name); 4556 free(newc); 4557 return -1; 4558 } 4559 } 4560 4561 newc->next = head; 4562 policydbp->ocontexts[OCON_FS] = newc; 4563 4564 return 0; 4565} 4566 4567int define_pirq_context(unsigned int pirq) 4568{ 4569 ocontext_t *newc, *c, *l, *head; 4570 char *id; 4571 4572 if (policydbp->target_platform != SEPOL_TARGET_XEN) { 4573 yyerror("pirqcon not supported for target"); 4574 return -1; 4575 } 4576 4577 if (pass == 1) { 4578 id = (char *) queue_remove(id_queue); 4579 free(id); 4580 parse_security_context(NULL); 4581 return 0; 4582 } 4583 4584 newc = malloc(sizeof(ocontext_t)); 4585 if (!newc) { 4586 yyerror("out of memory"); 4587 return -1; 4588 } 4589 memset(newc, 0, sizeof(ocontext_t)); 4590 4591 newc->u.pirq = pirq; 4592 4593 if (parse_security_context(&newc->context[0])) { 4594 free(newc); 4595 return -1; 4596 } 4597 4598 head = policydbp->ocontexts[OCON_XEN_PIRQ]; 4599 for (l = NULL, c = head; c; l = c, c = c->next) { 4600 unsigned int pirq2; 4601 4602 pirq2 = c->u.pirq; 4603 if (pirq == pirq2) { 4604 yyerror2("duplicate pirqcon entry for %d ", pirq); 4605 goto bad; 4606 } 4607 } 4608 4609 if (l) 4610 l->next = newc; 4611 else 4612 policydbp->ocontexts[OCON_XEN_PIRQ] = newc; 4613 4614 return 0; 4615 4616bad: 4617 free(newc); 4618 return -1; 4619} 4620 4621int define_iomem_context(uint64_t low, uint64_t high) 4622{ 4623 ocontext_t *newc, *c, *l, *head; 4624 char *id; 4625 4626 if (policydbp->target_platform != SEPOL_TARGET_XEN) { 4627 yyerror("iomemcon not supported for target"); 4628 return -1; 4629 } 4630 4631 if (pass == 1) { 4632 id = (char *)queue_remove(id_queue); 4633 free(id); 4634 parse_security_context(NULL); 4635 return 0; 4636 } 4637 4638 newc = malloc(sizeof(ocontext_t)); 4639 if (!newc) { 4640 yyerror("out of memory"); 4641 return -1; 4642 } 4643 memset(newc, 0, sizeof(ocontext_t)); 4644 4645 newc->u.iomem.low_iomem = low; 4646 newc->u.iomem.high_iomem = high; 4647 4648 if (low > high) { 4649 yyerror2("low memory 0x%"PRIx64" exceeds high memory 0x%"PRIx64"", low, high); 4650 free(newc); 4651 return -1; 4652 } 4653 4654 if (parse_security_context(&newc->context[0])) { 4655 free(newc); 4656 return -1; 4657 } 4658 4659 head = policydbp->ocontexts[OCON_XEN_IOMEM]; 4660 for (l = NULL, c = head; c; l = c, c = c->next) { 4661 uint64_t low2, high2; 4662 4663 low2 = c->u.iomem.low_iomem; 4664 high2 = c->u.iomem.high_iomem; 4665 if (low <= high2 && low2 <= high) { 4666 yyerror2("iomemcon entry for 0x%"PRIx64"-0x%"PRIx64" overlaps with " 4667 "earlier entry 0x%"PRIx64"-0x%"PRIx64"", low, high, 4668 low2, high2); 4669 goto bad; 4670 } 4671 } 4672 4673 if (l) 4674 l->next = newc; 4675 else 4676 policydbp->ocontexts[OCON_XEN_IOMEM] = newc; 4677 4678 return 0; 4679 4680bad: 4681 free(newc); 4682 return -1; 4683} 4684 4685int define_ioport_context(unsigned long low, unsigned long high) 4686{ 4687 ocontext_t *newc, *c, *l, *head; 4688 char *id; 4689 4690 if (policydbp->target_platform != SEPOL_TARGET_XEN) { 4691 yyerror("ioportcon not supported for target"); 4692 return -1; 4693 } 4694 4695 if (pass == 1) { 4696 id = (char *)queue_remove(id_queue); 4697 free(id); 4698 parse_security_context(NULL); 4699 return 0; 4700 } 4701 4702 newc = malloc(sizeof(ocontext_t)); 4703 if (!newc) { 4704 yyerror("out of memory"); 4705 return -1; 4706 } 4707 memset(newc, 0, sizeof(ocontext_t)); 4708 4709 newc->u.ioport.low_ioport = low; 4710 newc->u.ioport.high_ioport = high; 4711 4712 if (low > high) { 4713 yyerror2("low ioport 0x%lx exceeds high ioport 0x%lx", low, high); 4714 free(newc); 4715 return -1; 4716 } 4717 4718 if (parse_security_context(&newc->context[0])) { 4719 free(newc); 4720 return -1; 4721 } 4722 4723 head = policydbp->ocontexts[OCON_XEN_IOPORT]; 4724 for (l = NULL, c = head; c; l = c, c = c->next) { 4725 uint32_t low2, high2; 4726 4727 low2 = c->u.ioport.low_ioport; 4728 high2 = c->u.ioport.high_ioport; 4729 if (low <= high2 && low2 <= high) { 4730 yyerror2("ioportcon entry for 0x%lx-0x%lx overlaps with" 4731 "earlier entry 0x%x-0x%x", low, high, 4732 low2, high2); 4733 goto bad; 4734 } 4735 } 4736 4737 if (l) 4738 l->next = newc; 4739 else 4740 policydbp->ocontexts[OCON_XEN_IOPORT] = newc; 4741 4742 return 0; 4743 4744bad: 4745 free(newc); 4746 return -1; 4747} 4748 4749int define_pcidevice_context(unsigned long device) 4750{ 4751 ocontext_t *newc, *c, *l, *head; 4752 char *id; 4753 4754 if (policydbp->target_platform != SEPOL_TARGET_XEN) { 4755 yyerror("pcidevicecon not supported for target"); 4756 return -1; 4757 } 4758 4759 if (pass == 1) { 4760 id = (char *) queue_remove(id_queue); 4761 free(id); 4762 parse_security_context(NULL); 4763 return 0; 4764 } 4765 4766 newc = malloc(sizeof(ocontext_t)); 4767 if (!newc) { 4768 yyerror("out of memory"); 4769 return -1; 4770 } 4771 memset(newc, 0, sizeof(ocontext_t)); 4772 4773 newc->u.device = device; 4774 4775 if (parse_security_context(&newc->context[0])) { 4776 free(newc); 4777 return -1; 4778 } 4779 4780 head = policydbp->ocontexts[OCON_XEN_PCIDEVICE]; 4781 for (l = NULL, c = head; c; l = c, c = c->next) { 4782 unsigned int device2; 4783 4784 device2 = c->u.device; 4785 if (device == device2) { 4786 yyerror2("duplicate pcidevicecon entry for 0x%lx", 4787 device); 4788 goto bad; 4789 } 4790 } 4791 4792 if (l) 4793 l->next = newc; 4794 else 4795 policydbp->ocontexts[OCON_XEN_PCIDEVICE] = newc; 4796 4797 return 0; 4798 4799bad: 4800 free(newc); 4801 return -1; 4802} 4803 4804int define_devicetree_context() 4805{ 4806 ocontext_t *newc, *c, *l, *head; 4807 4808 if (policydbp->target_platform != SEPOL_TARGET_XEN) { 4809 yyerror("devicetreecon not supported for target"); 4810 return -1; 4811 } 4812 4813 if (pass == 1) { 4814 free(queue_remove(id_queue)); 4815 parse_security_context(NULL); 4816 return 0; 4817 } 4818 4819 newc = malloc(sizeof(ocontext_t)); 4820 if (!newc) { 4821 yyerror("out of memory"); 4822 return -1; 4823 } 4824 memset(newc, 0, sizeof(ocontext_t)); 4825 4826 newc->u.name = (char *)queue_remove(id_queue); 4827 if (!newc->u.name) { 4828 free(newc); 4829 return -1; 4830 } 4831 4832 if (parse_security_context(&newc->context[0])) { 4833 free(newc->u.name); 4834 free(newc); 4835 return -1; 4836 } 4837 4838 head = policydbp->ocontexts[OCON_XEN_DEVICETREE]; 4839 for (l = NULL, c = head; c; l = c, c = c->next) { 4840 if (strcmp(newc->u.name, c->u.name) == 0) { 4841 yyerror2("duplicate devicetree entry for '%s'", newc->u.name); 4842 goto bad; 4843 } 4844 } 4845 4846 if (l) 4847 l->next = newc; 4848 else 4849 policydbp->ocontexts[OCON_XEN_DEVICETREE] = newc; 4850 4851 return 0; 4852 4853bad: 4854 free(newc->u.name); 4855 free(newc); 4856 return -1; 4857} 4858 4859int define_port_context(unsigned int low, unsigned int high) 4860{ 4861 ocontext_t *newc, *c, *l, *head; 4862 unsigned int protocol; 4863 char *id; 4864 4865 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 4866 yyerror("portcon not supported for target"); 4867 return -1; 4868 } 4869 4870 if (pass == 1) { 4871 id = (char *)queue_remove(id_queue); 4872 free(id); 4873 parse_security_context(NULL); 4874 return 0; 4875 } 4876 4877 newc = malloc(sizeof(ocontext_t)); 4878 if (!newc) { 4879 yyerror("out of memory"); 4880 return -1; 4881 } 4882 memset(newc, 0, sizeof(ocontext_t)); 4883 4884 id = (char *)queue_remove(id_queue); 4885 if (!id) { 4886 free(newc); 4887 return -1; 4888 } 4889 if ((strcmp(id, "tcp") == 0) || (strcmp(id, "TCP") == 0)) { 4890 protocol = IPPROTO_TCP; 4891 } else if ((strcmp(id, "udp") == 0) || (strcmp(id, "UDP") == 0)) { 4892 protocol = IPPROTO_UDP; 4893 } else if ((strcmp(id, "dccp") == 0) || (strcmp(id, "DCCP") == 0)) { 4894 protocol = IPPROTO_DCCP; 4895 } else { 4896 yyerror2("unrecognized protocol %s", id); 4897 free(newc); 4898 return -1; 4899 } 4900 4901 newc->u.port.protocol = protocol; 4902 newc->u.port.low_port = low; 4903 newc->u.port.high_port = high; 4904 4905 if (low > high) { 4906 yyerror2("low port %d exceeds high port %d", low, high); 4907 free(newc); 4908 return -1; 4909 } 4910 4911 if (parse_security_context(&newc->context[0])) { 4912 free(newc); 4913 return -1; 4914 } 4915 4916 /* Preserve the matching order specified in the configuration. */ 4917 head = policydbp->ocontexts[OCON_PORT]; 4918 for (l = NULL, c = head; c; l = c, c = c->next) { 4919 unsigned int prot2, low2, high2; 4920 4921 prot2 = c->u.port.protocol; 4922 low2 = c->u.port.low_port; 4923 high2 = c->u.port.high_port; 4924 if (protocol != prot2) 4925 continue; 4926 if (low == low2 && high == high2) { 4927 yyerror2("duplicate portcon entry for %s %d-%d ", id, 4928 low, high); 4929 goto bad; 4930 } 4931 if (low2 <= low && high2 >= high) { 4932 yyerror2("portcon entry for %s %d-%d hidden by earlier " 4933 "entry for %d-%d", id, low, high, low2, high2); 4934 goto bad; 4935 } 4936 } 4937 4938 if (l) 4939 l->next = newc; 4940 else 4941 policydbp->ocontexts[OCON_PORT] = newc; 4942 4943 return 0; 4944 4945 bad: 4946 free(newc); 4947 return -1; 4948} 4949 4950int define_netif_context(void) 4951{ 4952 ocontext_t *newc, *c, *head; 4953 4954 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 4955 yyerror("netifcon not supported for target"); 4956 return -1; 4957 } 4958 4959 if (pass == 1) { 4960 free(queue_remove(id_queue)); 4961 parse_security_context(NULL); 4962 parse_security_context(NULL); 4963 return 0; 4964 } 4965 4966 newc = (ocontext_t *) malloc(sizeof(ocontext_t)); 4967 if (!newc) { 4968 yyerror("out of memory"); 4969 return -1; 4970 } 4971 memset(newc, 0, sizeof(ocontext_t)); 4972 4973 newc->u.name = (char *)queue_remove(id_queue); 4974 if (!newc->u.name) { 4975 free(newc); 4976 return -1; 4977 } 4978 if (parse_security_context(&newc->context[0])) { 4979 free(newc->u.name); 4980 free(newc); 4981 return -1; 4982 } 4983 if (parse_security_context(&newc->context[1])) { 4984 context_destroy(&newc->context[0]); 4985 free(newc->u.name); 4986 free(newc); 4987 return -1; 4988 } 4989 head = policydbp->ocontexts[OCON_NETIF]; 4990 4991 for (c = head; c; c = c->next) { 4992 if (!strcmp(newc->u.name, c->u.name)) { 4993 yyerror2("duplicate entry for network interface %s", 4994 newc->u.name); 4995 context_destroy(&newc->context[0]); 4996 context_destroy(&newc->context[1]); 4997 free(newc->u.name); 4998 free(newc); 4999 return -1; 5000 } 5001 } 5002 5003 newc->next = head; 5004 policydbp->ocontexts[OCON_NETIF] = newc; 5005 return 0; 5006} 5007 5008int define_ipv4_node_context() 5009{ 5010 char *id; 5011 int rc = 0; 5012 struct in_addr addr, mask; 5013 ocontext_t *newc, *c, *l, *head; 5014 5015 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 5016 yyerror("nodecon not supported for target"); 5017 return -1; 5018 } 5019 5020 if (pass == 1) { 5021 free(queue_remove(id_queue)); 5022 free(queue_remove(id_queue)); 5023 parse_security_context(NULL); 5024 goto out; 5025 } 5026 5027 id = queue_remove(id_queue); 5028 if (!id) { 5029 yyerror("failed to read ipv4 address"); 5030 rc = -1; 5031 goto out; 5032 } 5033 5034 rc = inet_pton(AF_INET, id, &addr); 5035 free(id); 5036 if (rc < 1) { 5037 yyerror("failed to parse ipv4 address"); 5038 if (rc == 0) 5039 rc = -1; 5040 goto out; 5041 } 5042 5043 id = queue_remove(id_queue); 5044 if (!id) { 5045 yyerror("failed to read ipv4 address"); 5046 rc = -1; 5047 goto out; 5048 } 5049 5050 rc = inet_pton(AF_INET, id, &mask); 5051 free(id); 5052 if (rc < 1) { 5053 yyerror("failed to parse ipv4 mask"); 5054 if (rc == 0) 5055 rc = -1; 5056 goto out; 5057 } 5058 5059 newc = malloc(sizeof(ocontext_t)); 5060 if (!newc) { 5061 yyerror("out of memory"); 5062 rc = -1; 5063 goto out; 5064 } 5065 5066 memset(newc, 0, sizeof(ocontext_t)); 5067 newc->u.node.addr = addr.s_addr; 5068 newc->u.node.mask = mask.s_addr; 5069 5070 if (parse_security_context(&newc->context[0])) { 5071 free(newc); 5072 return -1; 5073 } 5074 5075 /* Create order of most specific to least retaining 5076 the order specified in the configuration. */ 5077 head = policydbp->ocontexts[OCON_NODE]; 5078 for (l = NULL, c = head; c; l = c, c = c->next) { 5079 if (newc->u.node.mask > c->u.node.mask) 5080 break; 5081 } 5082 5083 newc->next = c; 5084 5085 if (l) 5086 l->next = newc; 5087 else 5088 policydbp->ocontexts[OCON_NODE] = newc; 5089 rc = 0; 5090out: 5091 return rc; 5092} 5093 5094int define_ipv6_node_context(void) 5095{ 5096 char *id; 5097 int rc = 0; 5098 struct in6_addr addr, mask; 5099 ocontext_t *newc, *c, *l, *head; 5100 5101 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 5102 yyerror("nodecon not supported for target"); 5103 return -1; 5104 } 5105 5106 if (pass == 1) { 5107 free(queue_remove(id_queue)); 5108 free(queue_remove(id_queue)); 5109 parse_security_context(NULL); 5110 goto out; 5111 } 5112 5113 id = queue_remove(id_queue); 5114 if (!id) { 5115 yyerror("failed to read ipv6 address"); 5116 rc = -1; 5117 goto out; 5118 } 5119 5120 rc = inet_pton(AF_INET6, id, &addr); 5121 free(id); 5122 if (rc < 1) { 5123 yyerror("failed to parse ipv6 address"); 5124 if (rc == 0) 5125 rc = -1; 5126 goto out; 5127 } 5128 5129 id = queue_remove(id_queue); 5130 if (!id) { 5131 yyerror("failed to read ipv6 address"); 5132 rc = -1; 5133 goto out; 5134 } 5135 5136 rc = inet_pton(AF_INET6, id, &mask); 5137 free(id); 5138 if (rc < 1) { 5139 yyerror("failed to parse ipv6 mask"); 5140 if (rc == 0) 5141 rc = -1; 5142 goto out; 5143 } 5144 5145 newc = malloc(sizeof(ocontext_t)); 5146 if (!newc) { 5147 yyerror("out of memory"); 5148 rc = -1; 5149 goto out; 5150 } 5151 5152 memset(newc, 0, sizeof(ocontext_t)); 5153 5154#ifdef __APPLE__ 5155 memcpy(&newc->u.node6.addr[0], &addr.s6_addr[0], 16); 5156 memcpy(&newc->u.node6.mask[0], &mask.s6_addr[0], 16); 5157#else 5158 memcpy(&newc->u.node6.addr[0], &addr.s6_addr32[0], 16); 5159 memcpy(&newc->u.node6.mask[0], &mask.s6_addr32[0], 16); 5160#endif 5161 5162 if (parse_security_context(&newc->context[0])) { 5163 free(newc); 5164 rc = -1; 5165 goto out; 5166 } 5167 5168 /* Create order of most specific to least retaining 5169 the order specified in the configuration. */ 5170 head = policydbp->ocontexts[OCON_NODE6]; 5171 for (l = NULL, c = head; c; l = c, c = c->next) { 5172 if (memcmp(&newc->u.node6.mask, &c->u.node6.mask, 16) > 0) 5173 break; 5174 } 5175 5176 newc->next = c; 5177 5178 if (l) 5179 l->next = newc; 5180 else 5181 policydbp->ocontexts[OCON_NODE6] = newc; 5182 5183 rc = 0; 5184 out: 5185 return rc; 5186} 5187 5188int define_fs_use(int behavior) 5189{ 5190 ocontext_t *newc, *c, *head; 5191 5192 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 5193 yyerror("fsuse not supported for target"); 5194 return -1; 5195 } 5196 5197 if (pass == 1) { 5198 free(queue_remove(id_queue)); 5199 parse_security_context(NULL); 5200 return 0; 5201 } 5202 5203 newc = (ocontext_t *) malloc(sizeof(ocontext_t)); 5204 if (!newc) { 5205 yyerror("out of memory"); 5206 return -1; 5207 } 5208 memset(newc, 0, sizeof(ocontext_t)); 5209 5210 newc->u.name = (char *)queue_remove(id_queue); 5211 if (!newc->u.name) { 5212 free(newc); 5213 return -1; 5214 } 5215 newc->v.behavior = behavior; 5216 if (parse_security_context(&newc->context[0])) { 5217 free(newc->u.name); 5218 free(newc); 5219 return -1; 5220 } 5221 5222 head = policydbp->ocontexts[OCON_FSUSE]; 5223 5224 for (c = head; c; c = c->next) { 5225 if (!strcmp(newc->u.name, c->u.name)) { 5226 yyerror2("duplicate fs_use entry for filesystem type %s", 5227 newc->u.name); 5228 context_destroy(&newc->context[0]); 5229 free(newc->u.name); 5230 free(newc); 5231 return -1; 5232 } 5233 } 5234 5235 newc->next = head; 5236 policydbp->ocontexts[OCON_FSUSE] = newc; 5237 return 0; 5238} 5239 5240int define_genfs_context_helper(char *fstype, int has_type) 5241{ 5242 struct genfs *genfs_p, *genfs, *newgenfs; 5243 ocontext_t *newc, *c, *head, *p; 5244 char *type = NULL; 5245 int len, len2; 5246 5247 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 5248 yyerror("genfs not supported for target"); 5249 return -1; 5250 } 5251 5252 if (pass == 1) { 5253 free(fstype); 5254 free(queue_remove(id_queue)); 5255 if (has_type) 5256 free(queue_remove(id_queue)); 5257 parse_security_context(NULL); 5258 return 0; 5259 } 5260 5261 for (genfs_p = NULL, genfs = policydbp->genfs; 5262 genfs; genfs_p = genfs, genfs = genfs->next) { 5263 if (strcmp(fstype, genfs->fstype) <= 0) 5264 break; 5265 } 5266 5267 if (!genfs || strcmp(fstype, genfs->fstype)) { 5268 newgenfs = malloc(sizeof(struct genfs)); 5269 if (!newgenfs) { 5270 yyerror("out of memory"); 5271 return -1; 5272 } 5273 memset(newgenfs, 0, sizeof(struct genfs)); 5274 newgenfs->fstype = fstype; 5275 newgenfs->next = genfs; 5276 if (genfs_p) 5277 genfs_p->next = newgenfs; 5278 else 5279 policydbp->genfs = newgenfs; 5280 genfs = newgenfs; 5281 } 5282 5283 newc = (ocontext_t *) malloc(sizeof(ocontext_t)); 5284 if (!newc) { 5285 yyerror("out of memory"); 5286 return -1; 5287 } 5288 memset(newc, 0, sizeof(ocontext_t)); 5289 5290 newc->u.name = (char *)queue_remove(id_queue); 5291 if (!newc->u.name) 5292 goto fail; 5293 if (has_type) { 5294 type = (char *)queue_remove(id_queue); 5295 if (!type) 5296 goto fail; 5297 if (type[1] != 0) { 5298 yyerror2("invalid type %s", type); 5299 goto fail; 5300 } 5301 switch (type[0]) { 5302 case 'b': 5303 newc->v.sclass = SECCLASS_BLK_FILE; 5304 break; 5305 case 'c': 5306 newc->v.sclass = SECCLASS_CHR_FILE; 5307 break; 5308 case 'd': 5309 newc->v.sclass = SECCLASS_DIR; 5310 break; 5311 case 'p': 5312 newc->v.sclass = SECCLASS_FIFO_FILE; 5313 break; 5314 case 'l': 5315 newc->v.sclass = SECCLASS_LNK_FILE; 5316 break; 5317 case 's': 5318 newc->v.sclass = SECCLASS_SOCK_FILE; 5319 break; 5320 case '-': 5321 newc->v.sclass = SECCLASS_FILE; 5322 break; 5323 default: 5324 yyerror2("invalid type %s", type); 5325 goto fail; 5326 } 5327 } 5328 if (parse_security_context(&newc->context[0])) 5329 goto fail; 5330 5331 head = genfs->head; 5332 5333 for (p = NULL, c = head; c; p = c, c = c->next) { 5334 if (!strcmp(newc->u.name, c->u.name) && 5335 (!newc->v.sclass || !c->v.sclass 5336 || newc->v.sclass == c->v.sclass)) { 5337 yyerror2("duplicate entry for genfs entry (%s, %s)", 5338 fstype, newc->u.name); 5339 goto fail; 5340 } 5341 len = strlen(newc->u.name); 5342 len2 = strlen(c->u.name); 5343 if (len > len2) 5344 break; 5345 } 5346 5347 newc->next = c; 5348 if (p) 5349 p->next = newc; 5350 else 5351 genfs->head = newc; 5352 return 0; 5353 fail: 5354 if (type) 5355 free(type); 5356 context_destroy(&newc->context[0]); 5357 if (fstype) 5358 free(fstype); 5359 if (newc->u.name) 5360 free(newc->u.name); 5361 free(newc); 5362 return -1; 5363} 5364 5365int define_genfs_context(int has_type) 5366{ 5367 return define_genfs_context_helper(queue_remove(id_queue), has_type); 5368} 5369 5370int define_range_trans(int class_specified) 5371{ 5372 char *id; 5373 level_datum_t *levdatum = 0; 5374 class_datum_t *cladatum; 5375 range_trans_rule_t *rule; 5376 int l, add = 1; 5377 5378 if (!mlspol) { 5379 yyerror("range_transition rule in non-MLS configuration"); 5380 return -1; 5381 } 5382 5383 if (pass == 1) { 5384 while ((id = queue_remove(id_queue))) 5385 free(id); 5386 while ((id = queue_remove(id_queue))) 5387 free(id); 5388 if (class_specified) 5389 while ((id = queue_remove(id_queue))) 5390 free(id); 5391 id = queue_remove(id_queue); 5392 free(id); 5393 for (l = 0; l < 2; l++) { 5394 while ((id = queue_remove(id_queue))) { 5395 free(id); 5396 } 5397 id = queue_remove(id_queue); 5398 if (!id) 5399 break; 5400 free(id); 5401 } 5402 return 0; 5403 } 5404 5405 rule = malloc(sizeof(struct range_trans_rule)); 5406 if (!rule) { 5407 yyerror("out of memory"); 5408 return -1; 5409 } 5410 range_trans_rule_init(rule); 5411 5412 while ((id = queue_remove(id_queue))) { 5413 if (set_types(&rule->stypes, id, &add, 0)) 5414 goto out; 5415 } 5416 add = 1; 5417 while ((id = queue_remove(id_queue))) { 5418 if (set_types(&rule->ttypes, id, &add, 0)) 5419 goto out; 5420 } 5421 5422 if (class_specified) { 5423 if (read_classes(&rule->tclasses)) 5424 goto out; 5425 } else { 5426 cladatum = hashtab_search(policydbp->p_classes.table, 5427 "process"); 5428 if (!cladatum) { 5429 yyerror2("could not find process class for " 5430 "legacy range_transition statement"); 5431 goto out; 5432 } 5433 5434 if (ebitmap_set_bit(&rule->tclasses, cladatum->s.value - 1, TRUE)) { 5435 yyerror("out of memory"); 5436 goto out; 5437 } 5438 } 5439 5440 id = (char *)queue_remove(id_queue); 5441 if (!id) { 5442 yyerror("no range in range_transition definition?"); 5443 goto out; 5444 } 5445 for (l = 0; l < 2; l++) { 5446 levdatum = hashtab_search(policydbp->p_levels.table, id); 5447 if (!levdatum) { 5448 yyerror2("unknown level %s used in range_transition " 5449 "definition", id); 5450 free(id); 5451 goto out; 5452 } 5453 free(id); 5454 5455 rule->trange.level[l].sens = levdatum->level->sens; 5456 5457 while ((id = queue_remove(id_queue))) { 5458 if (parse_semantic_categories(id, levdatum, 5459 &rule->trange.level[l].cat)) { 5460 free(id); 5461 goto out; 5462 } 5463 free(id); 5464 } 5465 5466 id = (char *)queue_remove(id_queue); 5467 if (!id) 5468 break; 5469 } 5470 if (l == 0) { 5471 if (mls_semantic_level_cpy(&rule->trange.level[1], 5472 &rule->trange.level[0])) { 5473 yyerror("out of memory"); 5474 goto out; 5475 } 5476 } 5477 5478 append_range_trans(rule); 5479 return 0; 5480 5481out: 5482 range_trans_rule_destroy(rule); 5483 free(rule); 5484 return -1; 5485} 5486 5487/* FLASK */ 5488