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