1/* Author : Joshua Brindle <jbrindle@tresys.com> 2 * Karl MacMillan <kmacmillan@tresys.com> 3 * Jason Tang <jtang@tresys.com> 4 * Added support for binary policy modules 5 * 6 * Copyright (C) 2004 - 2005 Tresys Technology, LLC 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, version 2. 10 */ 11 12#include <assert.h> 13#include <stdarg.h> 14#include <stdlib.h> 15#include <string.h> 16 17#include <sepol/policydb/policydb.h> 18#include <sepol/policydb/avrule_block.h> 19#include <sepol/policydb/conditional.h> 20 21#include "queue.h" 22#include "module_compiler.h" 23 24union stack_item_u { 25 avrule_block_t *avrule; 26 cond_list_t *cond_list; 27}; 28 29typedef struct scope_stack { 30 union stack_item_u u; 31 int type; /* for above union: 1 = avrule block, 2 = conditional */ 32 avrule_decl_t *decl; /* if in an avrule block, which 33 * declaration is current */ 34 avrule_t *last_avrule; 35 int in_else; /* if in an avrule block, within ELSE branch */ 36 int require_given; /* 1 if this block had at least one require */ 37 struct scope_stack *parent, *child; 38} scope_stack_t; 39 40extern policydb_t *policydbp; 41extern queue_t id_queue; 42extern int yyerror(const char *msg); 43__attribute__ ((format(printf, 1, 2))) 44extern void yyerror2(const char *fmt, ...); 45 46static int push_stack(int stack_type, ...); 47static void pop_stack(void); 48 49/* keep track of the last item added to the stack */ 50static scope_stack_t *stack_top = NULL; 51static avrule_block_t *last_block; 52static uint32_t next_decl_id = 1; 53 54static const char * const flavor_str[SYM_NUM] = { 55 [SYM_COMMONS] = "common", 56 [SYM_CLASSES] = "class", 57 [SYM_ROLES] = "role", 58 [SYM_TYPES] = "type", 59 [SYM_USERS] = "user", 60 [SYM_BOOLS] = "bool", 61 [SYM_LEVELS] = "level", 62 [SYM_CATS] = "cat" 63}; 64 65static void print_error_msg(int ret, uint32_t symbol_type) 66{ 67 switch (ret) { 68 case -3: 69 yyerror("Out of memory!"); 70 break; 71 case -2: 72 yyerror2("Duplicate declaration of %s", flavor_str[symbol_type]); 73 break; 74 case -1: 75 yyerror2("Could not declare %s here", flavor_str[symbol_type]); 76 break; 77 default: 78 yyerror("Unknown error"); 79 } 80} 81 82int define_policy(int pass, int module_header_given) 83{ 84 char *id; 85 86 if (module_header_given) { 87 if (policydbp->policy_type != POLICY_MOD) { 88 yyerror 89 ("Module specification found while not building a policy module.\n"); 90 return -1; 91 } 92 93 if (pass == 2) { 94 while ((id = queue_remove(id_queue)) != NULL) 95 free(id); 96 } else { 97 id = (char *)queue_remove(id_queue); 98 if (!id) { 99 yyerror("no module name"); 100 return -1; 101 } 102 free(policydbp->name); 103 policydbp->name = id; 104 if ((policydbp->version = 105 queue_remove(id_queue)) == NULL) { 106 yyerror 107 ("Expected a module version but none was found."); 108 return -1; 109 } 110 } 111 } else { 112 if (policydbp->policy_type == POLICY_MOD) { 113 yyerror 114 ("Building a policy module, but no module specification found.\n"); 115 return -1; 116 } 117 } 118 /* the first declaration within the global avrule 119 block will always have an id of 1 */ 120 next_decl_id = 2; 121 122 /* reset the scoping stack */ 123 while (stack_top != NULL) { 124 pop_stack(); 125 } 126 if (push_stack(1, policydbp->global, policydbp->global->branch_list) == 127 -1) { 128 return -1; 129 } 130 last_block = policydbp->global; 131 return 0; 132} 133 134/* Given the current parse stack, returns 1 if a declaration or require would 135 * be allowed here or 0 if not. For example, declarations and requirements are 136 * not allowed in conditionals, so if there are any conditionals in the 137 * current scope stack then this would return a 0. 138 */ 139static int is_creation_allowed(void) 140{ 141 if (stack_top->type != 1 || stack_top->in_else) { 142 return 0; 143 } 144 return 1; 145} 146 147/* Attempt to declare or require a symbol within the current scope. 148 * Returns: 149 * 0: Success - Symbol had not been previously created. 150 * 1: Success - Symbol had already been created and caller must free datum. 151 * -1: Failure - Symbol cannot be created here 152 * -2: Failure - Duplicate declaration or type/attribute mismatch 153 * -3: Failure - Out of memory or some other error 154 */ 155static int create_symbol(uint32_t symbol_type, hashtab_key_t key, hashtab_datum_t datum, 156 uint32_t * dest_value, uint32_t scope) 157{ 158 avrule_decl_t *decl = stack_top->decl; 159 int ret; 160 161 if (!is_creation_allowed()) { 162 return -1; 163 } 164 165 ret = symtab_insert(policydbp, symbol_type, key, datum, scope, 166 decl->decl_id, dest_value); 167 168 if (ret == 1 && dest_value) { 169 hashtab_datum_t s = 170 hashtab_search(policydbp->symtab[symbol_type].table, 171 key); 172 assert(s != NULL); 173 174 if (symbol_type == SYM_LEVELS) { 175 *dest_value = ((level_datum_t *)s)->level->sens; 176 } else { 177 *dest_value = ((symtab_datum_t *)s)->value; 178 } 179 } else if (ret == -2) { 180 return -2; 181 } else if (ret < 0) { 182 return -3; 183 } 184 185 return ret; 186} 187 188/* Attempt to declare a symbol within the current declaration. If 189 * currently within a non-conditional and in a non-else branch then 190 * insert the symbol, return 0 on success if symbol was undeclared. 191 * For roles and users, it is legal to have multiple declarations; as 192 * such return 1 to indicate that caller must free() the datum because 193 * it was not added. If symbols may not be declared here return -1. 194 * For duplicate declarations return -2. For all else, including out 195 * of memory, return -3. Note that dest_value and datum_value might 196 * not be restricted pointers. */ 197int declare_symbol(uint32_t symbol_type, 198 hashtab_key_t key, hashtab_datum_t datum, 199 uint32_t * dest_value, uint32_t * datum_value) 200{ 201 avrule_decl_t *decl = stack_top->decl; 202 int ret = create_symbol(symbol_type, key, datum, dest_value, SCOPE_DECL); 203 204 if (ret < 0) { 205 return ret; 206 } 207 208 if (ebitmap_set_bit(decl->declared.scope + symbol_type, 209 *datum_value - 1, 1)) { 210 return -3; 211 } 212 213 return ret; 214} 215 216static int role_implicit_bounds(hashtab_t roles_tab, 217 char *role_id, role_datum_t *role) 218{ 219 role_datum_t *bounds; 220 char *bounds_id, *delim; 221 222 delim = strrchr(role_id, '.'); 223 if (!delim) 224 return 0; /* no implicit boundary */ 225 226 bounds_id = strdup(role_id); 227 if (!bounds_id) { 228 yyerror("out of memory"); 229 return -1; 230 } 231 bounds_id[(size_t)(delim - role_id)] = '\0'; 232 233 bounds = hashtab_search(roles_tab, bounds_id); 234 if (!bounds) { 235 yyerror2("role %s doesn't exist, is implicit bounds of %s", 236 bounds_id, role_id); 237 return -1; 238 } 239 240 if (!role->bounds) 241 role->bounds = bounds->s.value; 242 else if (role->bounds != bounds->s.value) { 243 yyerror2("role %s has inconsistent bounds %s/%s", 244 role_id, bounds_id, 245 policydbp->p_role_val_to_name[role->bounds - 1]); 246 return -1; 247 } 248 free(bounds_id); 249 250 return 0; 251} 252 253static int create_role(uint32_t scope, unsigned char isattr, role_datum_t **role, char **key) 254{ 255 char *id = queue_remove(id_queue); 256 role_datum_t *datum = NULL; 257 int ret; 258 uint32_t value; 259 260 *role = NULL; 261 *key = NULL; 262 isattr = isattr ? ROLE_ATTRIB : ROLE_ROLE; 263 264 if (id == NULL) { 265 yyerror("no role name"); 266 return -1; 267 } 268 269 datum = malloc(sizeof(*datum)); 270 if (datum == NULL) { 271 yyerror("Out of memory!"); 272 free(id); 273 return -1; 274 } 275 276 role_datum_init(datum); 277 datum->flavor = isattr; 278 279 if (scope == SCOPE_DECL) { 280 ret = declare_symbol(SYM_ROLES, id, datum, &value, &value); 281 } else { 282 ret = require_symbol(SYM_ROLES, id, datum, &value, &value); 283 } 284 285 datum->s.value = value; 286 287 if (ret == 0) { 288 *role = datum; 289 *key = strdup(id); 290 if (*key == NULL) { 291 yyerror("Out of memory!"); 292 return -1; 293 } 294 } else if (ret == 1) { 295 *role = hashtab_search(policydbp->symtab[SYM_ROLES].table, id); 296 if (*role && (isattr != (*role)->flavor)) { 297 yyerror2("Identifier %s used as both an attribute and a role", 298 id); 299 free(id); 300 role_datum_destroy(datum); 301 free(datum); 302 return -1; 303 } 304 *role = datum; 305 *key = id; 306 } else { 307 print_error_msg(ret, SYM_ROLES); 308 free(id); 309 role_datum_destroy(datum); 310 free(datum); 311 } 312 313 return ret; 314} 315 316role_datum_t *declare_role(unsigned char isattr) 317{ 318 char *key = NULL; 319 role_datum_t *role = NULL; 320 role_datum_t *dest_role = NULL; 321 hashtab_t roles_tab; 322 int ret, ret2; 323 324 ret = create_role(SCOPE_DECL, isattr, &role, &key); 325 if (ret < 0) { 326 return NULL; 327 } 328 329 /* create a new role_datum_t for this decl, if necessary */ 330 assert(stack_top->type == 1); 331 332 if (stack_top->parent == NULL) { 333 /* in parent, so use global symbol table */ 334 roles_tab = policydbp->p_roles.table; 335 } else { 336 roles_tab = stack_top->decl->p_roles.table; 337 } 338 339 dest_role = hashtab_search(roles_tab, key); 340 if (dest_role == NULL) { 341 if (ret == 0) { 342 dest_role = malloc(sizeof(*dest_role)); 343 if (dest_role == NULL) { 344 yyerror("Out of memory!"); 345 free(key); 346 return NULL; 347 } 348 role_datum_init(dest_role); 349 dest_role->s.value = role->s.value; 350 dest_role->flavor = role->flavor; 351 } else { 352 dest_role = role; 353 } 354 ret2 = role_implicit_bounds(roles_tab, key, dest_role); 355 if (ret2 != 0) { 356 free(key); 357 role_datum_destroy(dest_role); 358 free(dest_role); 359 return NULL; 360 } 361 ret2 = hashtab_insert(roles_tab, key, dest_role); 362 if (ret2 != 0) { 363 yyerror("Out of memory!"); 364 free(key); 365 role_datum_destroy(dest_role); 366 free(dest_role); 367 return NULL; 368 } 369 } else { 370 free(key); 371 if (ret == 1) { 372 role_datum_destroy(role); 373 free(role); 374 } 375 } 376 377 if (ret == 0) { 378 ret2 = ebitmap_set_bit(&dest_role->dominates, dest_role->s.value - 1, 1); 379 if (ret2 != 0) { 380 yyerror("out of memory"); 381 return NULL; 382 } 383 } 384 385 return dest_role; 386} 387 388static int create_type(uint32_t scope, unsigned char isattr, type_datum_t **type) 389{ 390 char *id; 391 type_datum_t *datum; 392 int ret; 393 uint32_t value = 0; 394 395 *type = NULL; 396 isattr = isattr ? TYPE_ATTRIB : TYPE_TYPE; 397 398 id = (char *)queue_remove(id_queue); 399 if (!id) { 400 yyerror("no type/attribute name?"); 401 return -1; 402 } 403 if (strcmp(id, "self") == 0) { 404 yyerror("\"self\" is a reserved type name."); 405 free(id); 406 return -1; 407 } 408 409 datum = malloc(sizeof(*datum)); 410 if (!datum) { 411 yyerror("Out of memory!"); 412 free(id); 413 return -1; 414 } 415 type_datum_init(datum); 416 datum->primary = 1; 417 datum->flavor = isattr; 418 419 if (scope == SCOPE_DECL) { 420 ret = declare_symbol(SYM_TYPES, id, datum, &value, &value); 421 } else { 422 ret = require_symbol(SYM_TYPES, id, datum, &value, &value); 423 } 424 425 if (ret == 0) { 426 datum->s.value = value; 427 *type = datum; 428 } else if (ret == 1) { 429 type_datum_destroy(datum); 430 free(datum); 431 *type = hashtab_search(policydbp->symtab[SYM_TYPES].table, id); 432 if (*type && (isattr != (*type)->flavor)) { 433 yyerror2("Identifier %s used as both an attribute and a type", 434 id); 435 free(id); 436 return -1; 437 } 438 free(id); 439 } else { 440 print_error_msg(ret, SYM_TYPES); 441 free(id); 442 type_datum_destroy(datum); 443 free(datum); 444 } 445 446 return ret; 447} 448 449type_datum_t *declare_type(unsigned char primary, unsigned char isattr) 450{ 451 type_datum_t *type = NULL; 452 int ret = create_type(SCOPE_DECL, isattr, &type); 453 454 if (ret == 0) { 455 type->primary = primary; 456 } 457 458 return type; 459} 460 461static int user_implicit_bounds(hashtab_t users_tab, 462 char *user_id, user_datum_t *user) 463{ 464 user_datum_t *bounds; 465 char *bounds_id, *delim; 466 467 delim = strrchr(user_id, '.'); 468 if (!delim) 469 return 0; /* no implicit boundary */ 470 471 bounds_id = strdup(user_id); 472 if (!bounds_id) { 473 yyerror("out of memory"); 474 return -1; 475 } 476 bounds_id[(size_t)(delim - user_id)] = '\0'; 477 478 bounds = hashtab_search(users_tab, bounds_id); 479 if (!bounds) { 480 yyerror2("user %s doesn't exist, is implicit bounds of %s", 481 bounds_id, user_id); 482 return -1; 483 } 484 485 if (!user->bounds) 486 user->bounds = bounds->s.value; 487 else if (user->bounds != bounds->s.value) { 488 yyerror2("user %s has inconsistent bounds %s/%s", 489 user_id, bounds_id, 490 policydbp->p_role_val_to_name[user->bounds - 1]); 491 return -1; 492 } 493 free(bounds_id); 494 495 return 0; 496} 497 498static int create_user(uint32_t scope, user_datum_t **user, char **key) 499{ 500 char *id = queue_remove(id_queue); 501 user_datum_t *datum = NULL; 502 int ret; 503 uint32_t value; 504 505 *user = NULL; 506 *key = NULL; 507 508 if (id == NULL) { 509 yyerror("no user name"); 510 return -1; 511 } 512 513 datum = malloc(sizeof(*datum)); 514 if (datum == NULL) { 515 yyerror("Out of memory!"); 516 free(id); 517 return -1; 518 } 519 520 user_datum_init(datum); 521 522 if (scope == SCOPE_DECL) { 523 ret = declare_symbol(SYM_USERS, id, datum, &value, &value); 524 } else { 525 ret = require_symbol(SYM_USERS, id, datum, &value, &value); 526 } 527 528 datum->s.value = value; 529 530 if (ret == 0) { 531 *user = datum; 532 *key = strdup(id); 533 if (*key == NULL) { 534 yyerror("Out of memory!"); 535 return -1; 536 } 537 } else if (ret == 1) { 538 *user = datum; 539 *key = id; 540 } else { 541 print_error_msg(ret, SYM_USERS); 542 free(id); 543 user_datum_destroy(datum); 544 free(datum); 545 } 546 547 return ret; 548} 549 550user_datum_t *declare_user(void) 551{ 552 char *key = NULL; 553 user_datum_t *user = NULL; 554 user_datum_t *dest_user = NULL; 555 hashtab_t users_tab; 556 int ret, ret2; 557 558 ret = create_user(SCOPE_DECL, &user, &key); 559 if (ret < 0) { 560 return NULL; 561 } 562 563 /* create a new user_datum_t for this decl, if necessary */ 564 assert(stack_top->type == 1); 565 566 if (stack_top->parent == NULL) { 567 /* in parent, so use global symbol table */ 568 users_tab = policydbp->p_users.table; 569 } else { 570 users_tab = stack_top->decl->p_users.table; 571 } 572 573 dest_user = hashtab_search(users_tab, key); 574 if (dest_user == NULL) { 575 if (ret == 0) { 576 dest_user = malloc(sizeof(*dest_user)); 577 if (dest_user == NULL) { 578 yyerror("Out of memory!"); 579 free(key); 580 return NULL; 581 } 582 user_datum_init(dest_user); 583 dest_user->s.value = user->s.value; 584 } else { 585 dest_user = user; 586 } 587 ret2 = user_implicit_bounds(users_tab, key, dest_user); 588 if (ret2 != 0) { 589 free(key); 590 user_datum_destroy(dest_user); 591 free(dest_user); 592 return NULL; 593 } 594 ret2 = hashtab_insert(users_tab, key, dest_user); 595 if (ret2 != 0) { 596 yyerror("Out of memory!"); 597 free(key); 598 user_datum_destroy(dest_user); 599 free(dest_user); 600 return NULL; 601 } 602 } else { 603 free(key); 604 if (ret == 1) { 605 user_datum_destroy(user); 606 free(user); 607 } 608 } 609 610 return dest_user; 611} 612 613/* Return a type_datum_t for the local avrule_decl with the given ID. 614 * If it does not exist, create one with the same value as 'value'. 615 * This function assumes that the ID is within scope. c.f., 616 * is_id_in_scope(). 617 * 618 * NOTE: this function usurps ownership of id afterwards. The caller 619 * shall not reference it nor free() it afterwards. 620 */ 621type_datum_t *get_local_type(char *id, uint32_t value, unsigned char isattr) 622{ 623 type_datum_t *dest_typdatum; 624 hashtab_t types_tab; 625 assert(stack_top->type == 1); 626 if (stack_top->parent == NULL) { 627 /* in global, so use global symbol table */ 628 types_tab = policydbp->p_types.table; 629 } else { 630 types_tab = stack_top->decl->p_types.table; 631 } 632 dest_typdatum = hashtab_search(types_tab, id); 633 if (!dest_typdatum) { 634 dest_typdatum = (type_datum_t *) malloc(sizeof(type_datum_t)); 635 if (dest_typdatum == NULL) { 636 free(id); 637 return NULL; 638 } 639 type_datum_init(dest_typdatum); 640 dest_typdatum->s.value = value; 641 dest_typdatum->flavor = isattr ? TYPE_ATTRIB : TYPE_TYPE; 642 dest_typdatum->primary = 1; 643 if (hashtab_insert(types_tab, id, dest_typdatum)) { 644 free(id); 645 type_datum_destroy(dest_typdatum); 646 free(dest_typdatum); 647 return NULL; 648 } 649 650 } else { 651 free(id); 652 if (dest_typdatum->flavor != isattr ? TYPE_ATTRIB : TYPE_TYPE) { 653 return NULL; 654 } 655 } 656 return dest_typdatum; 657} 658 659/* Return a role_datum_t for the local avrule_decl with the given ID. 660 * If it does not exist, create one with the same value as 'value'. 661 * This function assumes that the ID is within scope. c.f., 662 * is_id_in_scope(). 663 * 664 * NOTE: this function usurps ownership of id afterwards. The caller 665 * shall not reference it nor free() it afterwards. 666 */ 667role_datum_t *get_local_role(char *id, uint32_t value, unsigned char isattr) 668{ 669 role_datum_t *dest_roledatum; 670 hashtab_t roles_tab; 671 672 assert(stack_top->type == 1); 673 674 if (stack_top->parent == NULL) { 675 /* in global, so use global symbol table */ 676 roles_tab = policydbp->p_roles.table; 677 } else { 678 roles_tab = stack_top->decl->p_roles.table; 679 } 680 681 dest_roledatum = hashtab_search(roles_tab, id); 682 if (!dest_roledatum) { 683 dest_roledatum = (role_datum_t *)malloc(sizeof(role_datum_t)); 684 if (dest_roledatum == NULL) { 685 free(id); 686 return NULL; 687 } 688 689 role_datum_init(dest_roledatum); 690 dest_roledatum->s.value = value; 691 dest_roledatum->flavor = isattr ? ROLE_ATTRIB : ROLE_ROLE; 692 693 if (hashtab_insert(roles_tab, id, dest_roledatum)) { 694 free(id); 695 role_datum_destroy(dest_roledatum); 696 free(dest_roledatum); 697 return NULL; 698 } 699 } else { 700 free(id); 701 if (dest_roledatum->flavor != isattr ? ROLE_ATTRIB : ROLE_ROLE) 702 return NULL; 703 } 704 705 return dest_roledatum; 706} 707 708/* Attempt to require a symbol within the current scope. If currently 709 * within an optional (and not its else branch), add the symbol to the 710 * required list. Return 0 on success, 1 if caller needs to free() 711 * datum. If symbols may not be declared here return -1. For duplicate 712 * declarations return -2. For all else, including out of memory, 713 * return -3.. Note that dest_value and datum_value might not be 714 * restricted pointers. 715 */ 716int require_symbol(uint32_t symbol_type, 717 hashtab_key_t key, hashtab_datum_t datum, 718 uint32_t * dest_value, uint32_t * datum_value) 719{ 720 avrule_decl_t *decl = stack_top->decl; 721 int ret = create_symbol(symbol_type, key, datum, dest_value, SCOPE_REQ); 722 723 if (ret < 0) { 724 return ret; 725 } 726 727 if (ebitmap_set_bit(decl->required.scope + symbol_type, 728 *datum_value - 1, 1)) { 729 return -3; 730 } 731 732 stack_top->require_given = 1; 733 return ret; 734} 735 736int add_perm_to_class(uint32_t perm_value, uint32_t class_value) 737{ 738 avrule_decl_t *decl = stack_top->decl; 739 scope_index_t *scope; 740 741 assert(perm_value >= 1); 742 assert(class_value >= 1); 743 scope = &decl->required; 744 if (class_value > scope->class_perms_len) { 745 uint32_t i; 746 ebitmap_t *new_map = realloc(scope->class_perms_map, 747 class_value * sizeof(*new_map)); 748 if (new_map == NULL) { 749 return -1; 750 } 751 scope->class_perms_map = new_map; 752 for (i = scope->class_perms_len; i < class_value; i++) { 753 ebitmap_init(scope->class_perms_map + i); 754 } 755 scope->class_perms_len = class_value; 756 } 757 if (ebitmap_set_bit(scope->class_perms_map + class_value - 1, 758 perm_value - 1, 1)) { 759 return -1; 760 } 761 return 0; 762} 763 764static int perm_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p 765 __attribute__ ((unused))) 766{ 767 if (key) 768 free(key); 769 free(datum); 770 return 0; 771} 772 773static void class_datum_destroy(class_datum_t * cladatum) 774{ 775 if (cladatum != NULL) { 776 hashtab_map(cladatum->permissions.table, perm_destroy, NULL); 777 hashtab_destroy(cladatum->permissions.table); 778 free(cladatum); 779 } 780} 781 782int require_class(int pass) 783{ 784 char *class_id = queue_remove(id_queue); 785 char *perm_id = NULL; 786 class_datum_t *datum = NULL; 787 perm_datum_t *perm = NULL; 788 int ret; 789 790 if (pass == 2) { 791 free(class_id); 792 while ((perm_id = queue_remove(id_queue)) != NULL) 793 free(perm_id); 794 return 0; 795 } 796 797 /* first add the class if it is not already there */ 798 if (class_id == NULL) { 799 yyerror("no class name for class definition?"); 800 return -1; 801 } 802 803 if ((datum = calloc(1, sizeof(*datum))) == NULL || 804 symtab_init(&datum->permissions, PERM_SYMTAB_SIZE)) { 805 yyerror("Out of memory!"); 806 class_datum_destroy(datum); 807 return -1; 808 } 809 ret = 810 require_symbol(SYM_CLASSES, class_id, datum, &datum->s.value, 811 &datum->s.value); 812 if (ret < 0) { 813 print_error_msg(ret, SYM_CLASSES); 814 free(class_id); 815 class_datum_destroy(datum); 816 return -1; 817 } 818 819 if (ret == 0) { 820 /* a new class was added; reindex everything */ 821 if (policydb_index_classes(policydbp)) { 822 yyerror("Out of memory!"); 823 return -1; 824 } 825 } else { 826 class_datum_destroy(datum); 827 datum = hashtab_search(policydbp->p_classes.table, class_id); 828 assert(datum); /* the class datum should have existed */ 829 free(class_id); 830 } 831 832 /* now add each of the permissions to this class's requirements */ 833 while ((perm_id = queue_remove(id_queue)) != NULL) { 834 int allocated = 0; 835 836 /* Is the permission already in the table? */ 837 perm = hashtab_search(datum->permissions.table, perm_id); 838 if (!perm && datum->comdatum) 839 perm = 840 hashtab_search(datum->comdatum->permissions.table, 841 perm_id); 842 if (perm) { 843 /* Yes, drop the name. */ 844 free(perm_id); 845 } else { 846 /* No - allocate and insert an entry for it. */ 847 if (policydbp->policy_type == POLICY_BASE) { 848 yyerror2 849 ("Base policy - require of permission %s without prior declaration.", 850 perm_id); 851 free(perm_id); 852 return -1; 853 } 854 if (datum->permissions.nprim >= PERM_SYMTAB_SIZE) { 855 yyerror2("Class %s would have too many permissions " 856 "to fit in an access vector with permission %s", 857 policydbp->p_class_val_to_name[datum->s.value - 1], 858 perm_id); 859 free(perm_id); 860 return -1; 861 } 862 allocated = 1; 863 if ((perm = malloc(sizeof(*perm))) == NULL) { 864 yyerror("Out of memory!"); 865 free(perm_id); 866 return -1; 867 } 868 memset(perm, 0, sizeof(*perm)); 869 ret = 870 hashtab_insert(datum->permissions.table, perm_id, 871 perm); 872 if (ret) { 873 yyerror("Out of memory!"); 874 free(perm_id); 875 free(perm); 876 return -1; 877 } 878 perm->s.value = datum->permissions.nprim + 1; 879 } 880 881 if (add_perm_to_class(perm->s.value, datum->s.value) == -1) { 882 yyerror("Out of memory!"); 883 return -1; 884 } 885 886 /* Update number of primitives if we allocated one. */ 887 if (allocated) 888 datum->permissions.nprim++; 889 } 890 return 0; 891} 892 893static int require_role_or_attribute(int pass, unsigned char isattr) 894{ 895 char *key = NULL; 896 role_datum_t *role = NULL; 897 int ret; 898 899 if (pass == 2) { 900 free(queue_remove(id_queue)); 901 return 0; 902 } 903 904 ret = create_role(SCOPE_REQ, isattr, &role, &key); 905 if (ret < 0) { 906 return -1; 907 } 908 909 free(key); 910 911 if (ret == 0) { 912 ret = ebitmap_set_bit(&role->dominates, role->s.value - 1, 1); 913 if (ret != 0) { 914 yyerror("Out of memory"); 915 return -1; 916 } 917 } else { 918 role_datum_destroy(role); 919 free(role); 920 } 921 922 return 0; 923} 924 925int require_role(int pass) 926{ 927 return require_role_or_attribute(pass, 0); 928} 929 930int require_attribute_role(int pass) 931{ 932 return require_role_or_attribute(pass, 1); 933} 934 935static int require_type_or_attribute(int pass, unsigned char isattr) 936{ 937 type_datum_t *type = NULL; 938 int ret; 939 940 if (pass == 2) { 941 free(queue_remove(id_queue)); 942 return 0; 943 } 944 945 ret = create_type(SCOPE_REQ, isattr, &type); 946 947 if (ret < 0) { 948 return -1; 949 } 950 951 return 0; 952} 953 954int require_type(int pass) 955{ 956 return require_type_or_attribute(pass, 0); 957} 958 959int require_attribute(int pass) 960{ 961 return require_type_or_attribute(pass, 1); 962} 963 964int require_user(int pass) 965{ 966 char *key = NULL; 967 user_datum_t *user = NULL; 968 int ret; 969 970 if (pass == 1) { 971 free(queue_remove(id_queue)); 972 return 0; 973 } 974 975 ret = create_user(SCOPE_REQ, &user, &key); 976 if (ret < 0) { 977 return -1; 978 } 979 980 free(key); 981 982 if (ret == 1) { 983 user_datum_destroy(user); 984 free(user); 985 } 986 987 return 0; 988} 989 990static int require_bool_tunable(int pass, int is_tunable) 991{ 992 char *id = queue_remove(id_queue); 993 cond_bool_datum_t *booldatum = NULL; 994 int retval; 995 if (pass == 2) { 996 free(id); 997 return 0; 998 } 999 if (id == NULL) { 1000 yyerror("no boolean name"); 1001 return -1; 1002 } 1003 if ((booldatum = calloc(1, sizeof(*booldatum))) == NULL) { 1004 cond_destroy_bool(id, booldatum, NULL); 1005 yyerror("Out of memory!"); 1006 return -1; 1007 } 1008 if (is_tunable) 1009 booldatum->flags |= COND_BOOL_FLAGS_TUNABLE; 1010 retval = 1011 require_symbol(SYM_BOOLS, id, booldatum, 1012 &booldatum->s.value, &booldatum->s.value); 1013 if (retval != 0) { 1014 cond_destroy_bool(id, booldatum, NULL); 1015 if (retval < 0) { 1016 print_error_msg(retval, SYM_BOOLS); 1017 return -1; 1018 } 1019 } 1020 1021 return 0; 1022} 1023 1024int require_bool(int pass) 1025{ 1026 return require_bool_tunable(pass, 0); 1027} 1028 1029int require_tunable(int pass) 1030{ 1031 return require_bool_tunable(pass, 1); 1032} 1033 1034int require_sens(int pass) 1035{ 1036 char *id = queue_remove(id_queue); 1037 level_datum_t *level = NULL; 1038 int retval; 1039 if (pass == 2) { 1040 free(id); 1041 return 0; 1042 } 1043 if (!id) { 1044 yyerror("no sensitivity name"); 1045 return -1; 1046 } 1047 level = malloc(sizeof(level_datum_t)); 1048 if (!level) { 1049 free(id); 1050 yyerror("Out of memory!"); 1051 return -1; 1052 } 1053 level_datum_init(level); 1054 level->level = malloc(sizeof(mls_level_t)); 1055 if (!level->level) { 1056 free(id); 1057 level_datum_destroy(level); 1058 free(level); 1059 yyerror("Out of memory!"); 1060 return -1; 1061 } 1062 mls_level_init(level->level); 1063 retval = require_symbol(SYM_LEVELS, id, level, 1064 &level->level->sens, &level->level->sens); 1065 if (retval != 0) { 1066 free(id); 1067 mls_level_destroy(level->level); 1068 free(level->level); 1069 level_datum_destroy(level); 1070 free(level); 1071 if (retval < 0) { 1072 print_error_msg(retval, SYM_LEVELS); 1073 return -1; 1074 } 1075 } 1076 1077 return 0; 1078} 1079 1080int require_cat(int pass) 1081{ 1082 char *id = queue_remove(id_queue); 1083 cat_datum_t *cat = NULL; 1084 int retval; 1085 if (pass == 2) { 1086 free(id); 1087 return 0; 1088 } 1089 if (!id) { 1090 yyerror("no category name"); 1091 return -1; 1092 } 1093 cat = malloc(sizeof(cat_datum_t)); 1094 if (!cat) { 1095 free(id); 1096 yyerror("Out of memory!"); 1097 return -1; 1098 } 1099 cat_datum_init(cat); 1100 1101 retval = require_symbol(SYM_CATS, id, cat, 1102 &cat->s.value, &cat->s.value); 1103 if (retval != 0) { 1104 free(id); 1105 cat_datum_destroy(cat); 1106 free(cat); 1107 if (retval < 0) { 1108 print_error_msg(retval, SYM_CATS); 1109 return -1; 1110 } 1111 } 1112 1113 return 0; 1114} 1115 1116static int is_scope_in_stack(const scope_datum_t * scope, const scope_stack_t * stack) 1117{ 1118 uint32_t i; 1119 if (stack == NULL) { 1120 return 0; /* no matching scope found */ 1121 } 1122 if (stack->type == 1) { 1123 const avrule_decl_t *decl = stack->decl; 1124 for (i = 0; i < scope->decl_ids_len; i++) { 1125 if (scope->decl_ids[i] == decl->decl_id) { 1126 return 1; 1127 } 1128 } 1129 } else { 1130 /* note that conditionals can't declare or require 1131 * symbols, so skip this level */ 1132 } 1133 1134 /* not within scope of this stack, so try its parent */ 1135 return is_scope_in_stack(scope, stack->parent); 1136} 1137 1138int is_id_in_scope(uint32_t symbol_type, const_hashtab_key_t id) 1139{ 1140 const scope_datum_t *scope = 1141 (scope_datum_t *) hashtab_search(policydbp->scope[symbol_type]. 1142 table, id); 1143 if (scope == NULL) { 1144 return 1; /* id is not known, so return success */ 1145 } 1146 return is_scope_in_stack(scope, stack_top); 1147} 1148 1149static int is_perm_in_scope_index(uint32_t perm_value, uint32_t class_value, 1150 const scope_index_t * scope) 1151{ 1152 if (class_value > scope->class_perms_len) { 1153 return 1; 1154 } 1155 if (ebitmap_get_bit(scope->class_perms_map + class_value - 1, 1156 perm_value - 1)) { 1157 return 1; 1158 } 1159 return 0; 1160} 1161 1162static int is_perm_in_stack(uint32_t perm_value, uint32_t class_value, 1163 const scope_stack_t * stack) 1164{ 1165 if (stack == NULL) { 1166 return 0; /* no matching scope found */ 1167 } 1168 if (stack->type == 1) { 1169 avrule_decl_t *decl = stack->decl; 1170 if (is_perm_in_scope_index 1171 (perm_value, class_value, &decl->required) 1172 || is_perm_in_scope_index(perm_value, class_value, 1173 &decl->declared)) { 1174 return 1; 1175 } 1176 } else { 1177 /* note that conditionals can't declare or require 1178 * symbols, so skip this level */ 1179 } 1180 1181 /* not within scope of this stack, so try its parent */ 1182 return is_perm_in_stack(perm_value, class_value, stack->parent); 1183} 1184 1185int is_perm_in_scope(const_hashtab_key_t perm_id, const_hashtab_key_t class_id) 1186{ 1187 const class_datum_t *cladatum = 1188 (class_datum_t *) hashtab_search(policydbp->p_classes.table, 1189 class_id); 1190 const perm_datum_t *perdatum; 1191 if (cladatum == NULL) { 1192 return 1; 1193 } 1194 perdatum = (perm_datum_t *) hashtab_search(cladatum->permissions.table, 1195 perm_id); 1196 if (perdatum == NULL) { 1197 return 1; 1198 } 1199 return is_perm_in_stack(perdatum->s.value, cladatum->s.value, 1200 stack_top); 1201} 1202 1203cond_list_t *get_current_cond_list(cond_list_t * cond) 1204{ 1205 /* FIX ME: do something different here if in a nested 1206 * conditional? */ 1207 avrule_decl_t *decl = stack_top->decl; 1208 return get_decl_cond_list(policydbp, decl, cond); 1209} 1210 1211/* Append the new conditional node to the existing ones. During 1212 * expansion the list will be reversed -- i.e., the last AV rule will 1213 * be the first one listed in the policy. This matches the behavior 1214 * of the upstream compiler. */ 1215void append_cond_list(cond_list_t * cond) 1216{ 1217 cond_list_t *old_cond = get_current_cond_list(cond); 1218 avrule_t *tmp; 1219 assert(old_cond != NULL); /* probably out of memory */ 1220 if (old_cond->avtrue_list == NULL) { 1221 old_cond->avtrue_list = cond->avtrue_list; 1222 } else { 1223 for (tmp = old_cond->avtrue_list; tmp->next != NULL; 1224 tmp = tmp->next) ; 1225 tmp->next = cond->avtrue_list; 1226 } 1227 if (old_cond->avfalse_list == NULL) { 1228 old_cond->avfalse_list = cond->avfalse_list; 1229 } else { 1230 for (tmp = old_cond->avfalse_list; tmp->next != NULL; 1231 tmp = tmp->next) ; 1232 tmp->next = cond->avfalse_list; 1233 } 1234 1235 old_cond->flags |= cond->flags; 1236} 1237 1238void append_avrule(avrule_t * avrule) 1239{ 1240 avrule_decl_t *decl = stack_top->decl; 1241 1242 /* currently avrules follow a completely different code path 1243 * for handling avrules and compute types 1244 * (define_cond_avrule_te_avtab, define_cond_compute_type); 1245 * therefore there ought never be a conditional on top of the 1246 * scope stack */ 1247 assert(stack_top->type == 1); 1248 1249 if (stack_top->last_avrule == NULL) { 1250 decl->avrules = avrule; 1251 } else { 1252 stack_top->last_avrule->next = avrule; 1253 } 1254 stack_top->last_avrule = avrule; 1255} 1256 1257/* this doesn't actually append, but really prepends it */ 1258void append_role_trans(role_trans_rule_t * role_tr_rules) 1259{ 1260 avrule_decl_t *decl = stack_top->decl; 1261 1262 /* role transitions are not allowed within conditionals */ 1263 assert(stack_top->type == 1); 1264 1265 role_tr_rules->next = decl->role_tr_rules; 1266 decl->role_tr_rules = role_tr_rules; 1267} 1268 1269/* this doesn't actually append, but really prepends it */ 1270void append_role_allow(role_allow_rule_t * role_allow_rules) 1271{ 1272 avrule_decl_t *decl = stack_top->decl; 1273 1274 /* role allows are not allowed within conditionals */ 1275 assert(stack_top->type == 1); 1276 1277 role_allow_rules->next = decl->role_allow_rules; 1278 decl->role_allow_rules = role_allow_rules; 1279} 1280 1281/* this doesn't actually append, but really prepends it */ 1282void append_filename_trans(filename_trans_rule_t * filename_trans_rules) 1283{ 1284 avrule_decl_t *decl = stack_top->decl; 1285 1286 /* filename transitions are not allowed within conditionals */ 1287 assert(stack_top->type == 1); 1288 1289 filename_trans_rules->next = decl->filename_trans_rules; 1290 decl->filename_trans_rules = filename_trans_rules; 1291} 1292 1293/* this doesn't actually append, but really prepends it */ 1294void append_range_trans(range_trans_rule_t * range_tr_rules) 1295{ 1296 avrule_decl_t *decl = stack_top->decl; 1297 1298 /* range transitions are not allowed within conditionals */ 1299 assert(stack_top->type == 1); 1300 1301 range_tr_rules->next = decl->range_tr_rules; 1302 decl->range_tr_rules = range_tr_rules; 1303} 1304 1305int begin_optional(int pass) 1306{ 1307 avrule_block_t *block = NULL; 1308 avrule_decl_t *decl; 1309 if (pass == 1) { 1310 /* allocate a new avrule block for this optional block */ 1311 if ((block = avrule_block_create()) == NULL || 1312 (decl = avrule_decl_create(next_decl_id)) == NULL) { 1313 goto cleanup; 1314 } 1315 block->flags |= AVRULE_OPTIONAL; 1316 block->branch_list = decl; 1317 last_block->next = block; 1318 } else { 1319 /* select the next block from the chain built during pass 1 */ 1320 block = last_block->next; 1321 assert(block != NULL && 1322 block->branch_list != NULL && 1323 block->branch_list->decl_id == next_decl_id); 1324 decl = block->branch_list; 1325 } 1326 if (push_stack(1, block, decl) == -1) { 1327 goto cleanup; 1328 } 1329 stack_top->last_avrule = NULL; 1330 last_block = block; 1331 next_decl_id++; 1332 return 0; 1333 cleanup: 1334 yyerror("Out of memory!"); 1335 avrule_block_destroy(block); 1336 return -1; 1337} 1338 1339int end_optional(int pass __attribute__ ((unused))) 1340{ 1341 /* once nested conditionals are allowed, do the stack unfolding here */ 1342 pop_stack(); 1343 return 0; 1344} 1345 1346int begin_optional_else(int pass) 1347{ 1348 avrule_decl_t *decl; 1349 assert(stack_top->type == 1 && stack_top->in_else == 0); 1350 if (pass == 1) { 1351 /* allocate a new declaration and add it to the 1352 * current chain */ 1353 if ((decl = avrule_decl_create(next_decl_id)) == NULL) { 1354 yyerror("Out of memory!"); 1355 return -1; 1356 } 1357 stack_top->decl->next = decl; 1358 } else { 1359 /* pick the (hopefully last) declaration of this 1360 avrule block, built from pass 1 */ 1361 decl = stack_top->decl->next; 1362 assert(decl != NULL && 1363 decl->next == NULL && decl->decl_id == next_decl_id); 1364 } 1365 stack_top->in_else = 1; 1366 stack_top->decl = decl; 1367 stack_top->last_avrule = NULL; 1368 stack_top->require_given = 0; 1369 next_decl_id++; 1370 return 0; 1371} 1372 1373static int copy_requirements(avrule_decl_t * dest, const scope_stack_t * stack) 1374{ 1375 uint32_t i; 1376 if (stack == NULL) { 1377 return 0; 1378 } 1379 if (stack->type == 1) { 1380 const scope_index_t *src_scope = &stack->decl->required; 1381 scope_index_t *dest_scope = &dest->required; 1382 for (i = 0; i < SYM_NUM; i++) { 1383 const ebitmap_t *src_bitmap = &src_scope->scope[i]; 1384 ebitmap_t *dest_bitmap = &dest_scope->scope[i]; 1385 if (ebitmap_union(dest_bitmap, src_bitmap)) { 1386 yyerror("Out of memory!"); 1387 return -1; 1388 } 1389 } 1390 /* now copy class permissions */ 1391 if (src_scope->class_perms_len > dest_scope->class_perms_len) { 1392 ebitmap_t *new_map = 1393 realloc(dest_scope->class_perms_map, 1394 src_scope->class_perms_len * 1395 sizeof(*new_map)); 1396 if (new_map == NULL) { 1397 yyerror("Out of memory!"); 1398 return -1; 1399 } 1400 dest_scope->class_perms_map = new_map; 1401 for (i = dest_scope->class_perms_len; 1402 i < src_scope->class_perms_len; i++) { 1403 ebitmap_init(dest_scope->class_perms_map + i); 1404 } 1405 dest_scope->class_perms_len = 1406 src_scope->class_perms_len; 1407 } 1408 for (i = 0; i < src_scope->class_perms_len; i++) { 1409 const ebitmap_t *src_bitmap = &src_scope->class_perms_map[i]; 1410 ebitmap_t *dest_bitmap = 1411 &dest_scope->class_perms_map[i]; 1412 if (ebitmap_union(dest_bitmap, src_bitmap)) { 1413 yyerror("Out of memory!"); 1414 return -1; 1415 } 1416 } 1417 } 1418 return copy_requirements(dest, stack->parent); 1419} 1420 1421/* During pass 1, check that at least one thing was required within 1422 * this block, for those places where a REQUIRED is necessary. During 1423 * pass 2, have this block inherit its parents' requirements. Return 1424 * 0 on success, -1 on failure. */ 1425int end_avrule_block(int pass) 1426{ 1427 avrule_decl_t *decl = stack_top->decl; 1428 assert(stack_top->type == 1); 1429 if (pass == 2) { 1430 /* this avrule_decl inherits all of its parents' 1431 * requirements */ 1432 if (copy_requirements(decl, stack_top->parent) == -1) { 1433 return -1; 1434 } 1435 return 0; 1436 } 1437 if (!stack_top->in_else && !stack_top->require_given) { 1438 if (policydbp->policy_type == POLICY_BASE 1439 && stack_top->parent != NULL) { 1440 /* if this is base no require should be in the global block */ 1441 return 0; 1442 } else { 1443 /* non-ELSE branches must have at least one thing required */ 1444 yyerror("This block has no require section."); 1445 return -1; 1446 } 1447 } 1448 return 0; 1449} 1450 1451/* Push a new scope on to the stack and update the 'last' pointer. 1452 * Return 0 on success, -1 if out * of memory. */ 1453static int push_stack(int stack_type, ...) 1454{ 1455 scope_stack_t *s = calloc(1, sizeof(*s)); 1456 va_list ap; 1457 if (s == NULL) { 1458 return -1; 1459 } 1460 va_start(ap, stack_type); 1461 switch (s->type = stack_type) { 1462 case 1:{ 1463 s->u.avrule = va_arg(ap, avrule_block_t *); 1464 s->decl = va_arg(ap, avrule_decl_t *); 1465 break; 1466 } 1467 case 2:{ 1468 s->u.cond_list = va_arg(ap, cond_list_t *); 1469 break; 1470 } 1471 default: 1472 /* invalid stack type given */ 1473 assert(0); 1474 } 1475 va_end(ap); 1476 s->parent = stack_top; 1477 s->child = NULL; 1478 stack_top = s; 1479 return 0; 1480} 1481 1482/* Pop off the most recently added from the stack. Update the 'last' 1483 * pointer. */ 1484static void pop_stack(void) 1485{ 1486 scope_stack_t *parent; 1487 assert(stack_top != NULL); 1488 parent = stack_top->parent; 1489 if (parent != NULL) { 1490 parent->child = NULL; 1491 } 1492 free(stack_top); 1493 stack_top = parent; 1494} 1495