00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <config.h>
00018
00019 #include <assert.h>
00020 #include <stdarg.h>
00021 #include <stdlib.h>
00022 #include <string.h>
00023
00024 #include <sepol/policydb/policydb.h>
00025 #include <sepol/policydb/avrule_block.h>
00026 #include <sepol/policydb/conditional.h>
00027
00028 #include "queue.h"
00029 #include "module_compiler.h"
00030
00031 union stack_item_u
00032 {
00033 avrule_block_t *avrule;
00034 cond_list_t *cond_list;
00035 };
00036
00037 typedef struct scope_stack
00038 {
00039 union stack_item_u u;
00040 int type;
00041 avrule_decl_t *decl;
00042
00043 avrule_t *last_avrule;
00044 int in_else;
00045 int require_given;
00046 struct scope_stack *parent, *child;
00047 } scope_stack_t;
00048
00049 extern policydb_t *policydbp;
00050 extern queue_t id_queue;
00051 extern int yyerror(char *msg);
00052 extern void yyerror2(char *fmt, ...);
00053
00054 static int push_stack(int stack_type, ...);
00055 static void pop_stack(void);
00056
00057
00058 static scope_stack_t *stack_top = NULL;
00059 static avrule_block_t *last_block;
00060 static uint32_t next_decl_id = 1;
00061
00062 int define_policy(int pass, int module_header_given)
00063 {
00064 char *id;
00065
00066 if (module_header_given) {
00067 if (policydbp->policy_type != POLICY_MOD) {
00068 yyerror("Module specification found while not building a policy module.\n");
00069 return -1;
00070 }
00071
00072 if (pass == 2) {
00073 while ((id = queue_remove(id_queue)) != NULL)
00074 free(id);
00075 } else {
00076 id = (char *)queue_remove(id_queue);
00077 if (!id) {
00078 yyerror("no module name");
00079 return -1;
00080 }
00081 policydbp->name = id;
00082 if ((policydbp->version = queue_remove(id_queue)) == NULL) {
00083 yyerror("Expected a module version but none was found.");
00084 return -1;
00085 }
00086 }
00087 } else {
00088 if (policydbp->policy_type == POLICY_MOD) {
00089 yyerror("Building a policy module, but no module specification found.\n");
00090 return -1;
00091 }
00092 }
00093
00094
00095 next_decl_id = 2;
00096
00097
00098 while (stack_top != NULL) {
00099 pop_stack();
00100 }
00101 if (push_stack(1, policydbp->global, policydbp->global->branch_list) == -1) {
00102 return -1;
00103 }
00104 last_block = policydbp->global;
00105 return 0;
00106 }
00107
00108
00109
00110
00111
00112
00113 static int is_declaration_allowed(void)
00114 {
00115 if (stack_top->type != 1 || stack_top->in_else) {
00116 return 0;
00117 }
00118 return 1;
00119 }
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 int declare_symbol(uint32_t symbol_type, hashtab_key_t key, hashtab_datum_t datum, uint32_t * dest_value, uint32_t * datum_value)
00131 {
00132 avrule_decl_t *decl = stack_top->decl;
00133 int retval;
00134
00135
00136 if (!is_declaration_allowed()) {
00137 return -1;
00138 }
00139 retval = symtab_insert(policydbp, symbol_type, key, datum, SCOPE_DECL, decl->decl_id, dest_value);
00140 if (retval == 1) {
00141 symtab_datum_t *s = (symtab_datum_t *) hashtab_search(policydbp->symtab[symbol_type].table,
00142 key);
00143 assert(s != NULL);
00144
00145 if (symbol_type == SYM_LEVELS) {
00146 *dest_value = ((level_datum_t *) s)->level->sens;
00147 } else {
00148 *dest_value = s->value;
00149 }
00150 } else if (retval == -2) {
00151 return -2;
00152 } else if (retval < 0) {
00153 return -3;
00154 } else {
00155 }
00156 if (datum_value != NULL) {
00157 if (ebitmap_set_bit(decl->declared.scope + symbol_type, *datum_value - 1, 1)) {
00158 return -3;
00159 }
00160 }
00161 return retval;
00162 }
00163
00164 role_datum_t *declare_role(void)
00165 {
00166 char *id = queue_remove(id_queue), *dest_id = NULL;
00167 role_datum_t *role = NULL, *dest_role = NULL;
00168 int retval;
00169 uint32_t value;
00170
00171 if (id == NULL) {
00172 yyerror("no role name");
00173 return NULL;
00174 }
00175 if ((role = (role_datum_t *) malloc(sizeof(*role))) == NULL) {
00176 yyerror("Out of memory!");
00177 free(id);
00178 return NULL;
00179 }
00180 role_datum_init(role);
00181
00182 retval = declare_symbol(SYM_ROLES, id, (hashtab_datum_t *) role, &value, &value);
00183 if (retval == 0) {
00184 role->s.value = value;
00185 if ((dest_id = strdup(id)) == NULL) {
00186 yyerror("Out of memory!");
00187 return NULL;
00188 }
00189 } else {
00190
00191 dest_id = id;
00192 role_datum_destroy(role);
00193 free(role);
00194 }
00195 if (retval == 0 || retval == 1) {
00196
00197 hashtab_t roles_tab;
00198 assert(stack_top->type == 1);
00199 if (stack_top->parent == NULL) {
00200
00201 roles_tab = policydbp->p_roles.table;
00202 } else {
00203 roles_tab = stack_top->decl->p_roles.table;
00204 }
00205 dest_role = (role_datum_t *) hashtab_search(roles_tab, dest_id);
00206 if (dest_role == NULL) {
00207 if ((dest_role = (role_datum_t *) malloc(sizeof(*dest_role))) == NULL) {
00208 yyerror("Out of memory!");
00209 free(dest_id);
00210 return NULL;
00211 }
00212 role_datum_init(dest_role);
00213 dest_role->s.value = value;
00214 if (hashtab_insert(roles_tab, dest_id, dest_role)) {
00215 yyerror("Out of memory!");
00216 free(dest_id);
00217 role_datum_destroy(dest_role);
00218 free(dest_role);
00219 return NULL;
00220 }
00221 } else {
00222 free(dest_id);
00223 }
00224 } else {
00225 free(dest_id);
00226 }
00227 switch (retval) {
00228 case -3:
00229 {
00230 yyerror("Out of memory!");
00231 return NULL;
00232 }
00233 case -2:
00234 {
00235 yyerror("duplicate declaration of role");
00236 return NULL;
00237 }
00238 case -1:
00239 {
00240 yyerror("could not declare role here");
00241 return NULL;
00242 }
00243 case 0:
00244 {
00245 if (ebitmap_set_bit(&dest_role->dominates, role->s.value - 1, 1)) {
00246 yyerror("out of memory");
00247 return NULL;
00248 }
00249 return dest_role;
00250 }
00251 case 1:
00252 {
00253 return dest_role;
00254 }
00255 default:
00256 {
00257 assert(0);
00258 }
00259 }
00260 }
00261
00262 type_datum_t *declare_type(unsigned char primary, unsigned char isattr)
00263 {
00264 char *id;
00265 type_datum_t *typdatum;
00266 int retval;
00267 uint32_t value = 0;
00268
00269 id = (char *)queue_remove(id_queue);
00270 if (!id) {
00271 yyerror("no type/attribute name?");
00272 return NULL;
00273 }
00274 if (strcmp(id, "self") == 0) {
00275 yyerror("'self' is a reserved type name and may not be declared.");
00276 free(id);
00277 return NULL;
00278 }
00279
00280 typdatum = (type_datum_t *) malloc(sizeof(type_datum_t));
00281 if (!typdatum) {
00282 yyerror("Out of memory!");
00283 free(id);
00284 return NULL;
00285 }
00286 type_datum_init(typdatum);
00287 typdatum->primary = primary;
00288 typdatum->flavor = isattr ? TYPE_ATTRIB : TYPE_TYPE;
00289
00290 retval = declare_symbol(SYM_TYPES, id, typdatum, &value, &value);
00291 if (retval == 0 || retval == 1) {
00292 if (typdatum->primary) {
00293 typdatum->s.value = value;
00294 }
00295 } else {
00296
00297 free(id);
00298 type_datum_destroy(typdatum);
00299 free(typdatum);
00300 }
00301 switch (retval) {
00302 case -3:
00303 {
00304 yyerror("Out of memory!");
00305 return NULL;
00306 }
00307 case -2:
00308 {
00309 yyerror2("duplicate declaration of type/attribute");
00310 return NULL;
00311 }
00312 case -1:
00313 {
00314 yyerror("could not declare type/attribute here");
00315 return NULL;
00316 }
00317 case 0:
00318 case 1:
00319 {
00320 return typdatum;
00321 }
00322 default:
00323 {
00324 assert(0);
00325 }
00326 }
00327 }
00328
00329 user_datum_t *declare_user(void)
00330 {
00331 char *id = queue_remove(id_queue), *dest_id = NULL;
00332 user_datum_t *user = NULL, *dest_user = NULL;
00333 int retval;
00334 uint32_t value = 0;
00335
00336 if (id == NULL) {
00337 yyerror("no user name");
00338 return NULL;
00339 }
00340 if ((user = (user_datum_t *) malloc(sizeof(*user))) == NULL) {
00341 yyerror("Out of memory!");
00342 free(id);
00343 return NULL;
00344 }
00345 user_datum_init(user);
00346
00347 retval = declare_symbol(SYM_USERS, id, (hashtab_datum_t *) user, &value, &value);
00348
00349 if (retval == 0) {
00350 user->s.value = value;
00351 if ((dest_id = strdup(id)) == NULL) {
00352 yyerror("Out of memory!");
00353 return NULL;
00354 }
00355 } else {
00356
00357 dest_id = id;
00358 user_datum_destroy(user);
00359 free(user);
00360 }
00361 if (retval == 0 || retval == 1) {
00362
00363 hashtab_t users_tab;
00364 assert(stack_top->type == 1);
00365 if (stack_top->parent == NULL) {
00366
00367 users_tab = policydbp->p_users.table;
00368 } else {
00369 users_tab = stack_top->decl->p_users.table;
00370 }
00371 dest_user = (user_datum_t *) hashtab_search(users_tab, dest_id);
00372 if (dest_user == NULL) {
00373 if ((dest_user = (user_datum_t *) malloc(sizeof(*dest_user))) == NULL) {
00374 yyerror("Out of memory!");
00375 free(dest_id);
00376 return NULL;
00377 }
00378 user_datum_init(dest_user);
00379 dest_user->s.value = value;
00380 if (hashtab_insert(users_tab, dest_id, dest_user)) {
00381 yyerror("Out of memory!");
00382 free(dest_id);
00383 user_datum_destroy(dest_user);
00384 free(dest_user);
00385 return NULL;
00386 }
00387 } else {
00388 free(dest_id);
00389 }
00390 } else {
00391 free(dest_id);
00392 }
00393 switch (retval) {
00394 case -3:
00395 {
00396 yyerror("Out of memory!");
00397 return NULL;
00398 }
00399 case -2:
00400 {
00401 yyerror("duplicate declaration of user");
00402 return NULL;
00403 }
00404 case -1:
00405 {
00406 yyerror("could not declare user here");
00407 return NULL;
00408 }
00409 case 0:
00410 {
00411 return dest_user;
00412 }
00413 case 1:
00414 {
00415 return dest_user;
00416 }
00417 default:
00418 {
00419 assert(0);
00420 }
00421 }
00422 }
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432 type_datum_t *get_local_type(char *id, uint32_t value, unsigned char isattr)
00433 {
00434 type_datum_t *dest_typdatum;
00435 hashtab_t types_tab;
00436 assert(stack_top->type == 1);
00437 if (stack_top->parent == NULL) {
00438
00439 types_tab = policydbp->p_types.table;
00440 } else {
00441 types_tab = stack_top->decl->p_types.table;
00442 }
00443 dest_typdatum = hashtab_search(types_tab, id);
00444 if (!dest_typdatum) {
00445 dest_typdatum = (type_datum_t *) malloc(sizeof(type_datum_t));
00446 if (dest_typdatum == NULL) {
00447 free(id);
00448 return NULL;
00449 }
00450 type_datum_init(dest_typdatum);
00451 dest_typdatum->s.value = value;
00452 dest_typdatum->flavor = isattr ? TYPE_ATTRIB : TYPE_TYPE;
00453 dest_typdatum->primary = 1;
00454 if (hashtab_insert(types_tab, id, dest_typdatum)) {
00455 free(id);
00456 type_datum_destroy(dest_typdatum);
00457 free(dest_typdatum);
00458 return NULL;
00459 }
00460
00461 } else {
00462 free(id);
00463 if (dest_typdatum->flavor != isattr ? TYPE_ATTRIB : TYPE_TYPE) {
00464 return NULL;
00465 }
00466 }
00467 return dest_typdatum;
00468 }
00469
00470
00471
00472
00473
00474 static int is_require_allowed(void)
00475 {
00476 if (stack_top->type == 1 && !stack_top->in_else) {
00477 return 1;
00478 }
00479 return 0;
00480 }
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490 int require_symbol(uint32_t symbol_type, hashtab_key_t key, hashtab_datum_t datum, uint32_t * dest_value, uint32_t * datum_value)
00491 {
00492 avrule_decl_t *decl = stack_top->decl;
00493 int retval;
00494
00495
00496 if (!is_require_allowed()) {
00497 return -1;
00498 }
00499 retval = symtab_insert(policydbp, symbol_type, key, datum, SCOPE_REQ, decl->decl_id, dest_value);
00500 if (retval == 1) {
00501 symtab_datum_t *s = (symtab_datum_t *) hashtab_search(policydbp->symtab[symbol_type].table,
00502 key);
00503 assert(s != NULL);
00504
00505 if (symbol_type == SYM_LEVELS) {
00506 *dest_value = ((level_datum_t *) s)->level->sens;
00507 } else {
00508 *dest_value = s->value;
00509 }
00510 } else if (retval == -2) {
00511
00512
00513 int prev_declaration_ok = 0;
00514 if (is_id_in_scope(symbol_type, key)) {
00515 if (symbol_type == SYM_TYPES) {
00516
00517
00518 unsigned char new_isattr = ((type_datum_t *) datum)->flavor;
00519 type_datum_t *old_datum = (type_datum_t *) hashtab_search(policydbp->symtab[SYM_TYPES].table, key);
00520 assert(old_datum != NULL);
00521 unsigned char old_isattr = old_datum->flavor;
00522 prev_declaration_ok = (old_isattr == new_isattr ? 1 : 0);
00523 } else {
00524 prev_declaration_ok = 1;
00525 }
00526 }
00527 if (prev_declaration_ok) {
00528
00529
00530 stack_top->require_given = 1;
00531 return 1;
00532 } else {
00533
00534
00535
00536 return -2;
00537 }
00538 } else if (retval < 0) {
00539 return -3;
00540 } else {
00541 }
00542 if (datum_value != NULL) {
00543 if (ebitmap_set_bit(decl->required.scope + symbol_type, *datum_value - 1, 1)) {
00544 return -3;
00545 }
00546 }
00547 stack_top->require_given = 1;
00548 return retval;
00549 }
00550
00551 int add_perm_to_class(uint32_t perm_value, uint32_t class_value)
00552 {
00553 avrule_decl_t *decl = stack_top->decl;
00554 scope_index_t *scope;
00555
00556 assert(perm_value >= 1);
00557 assert(class_value >= 1);
00558 scope = &decl->required;
00559 if (class_value > scope->class_perms_len) {
00560 int i;
00561 ebitmap_t *new_map = realloc(scope->class_perms_map,
00562 class_value * sizeof(*new_map));
00563 if (new_map == NULL) {
00564 return -1;
00565 }
00566 scope->class_perms_map = new_map;
00567 for (i = scope->class_perms_len; i < class_value; i++) {
00568 ebitmap_init(scope->class_perms_map + i);
00569 }
00570 scope->class_perms_len = class_value;
00571 }
00572 if (ebitmap_set_bit(scope->class_perms_map + class_value - 1, perm_value - 1, 1)) {
00573 return -1;
00574 }
00575 return 0;
00576 }
00577
00578 static int perm_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p __attribute__ ((unused)))
00579 {
00580 if (key)
00581 free(key);
00582 free(datum);
00583 return 0;
00584 }
00585
00586 static void class_datum_destroy(class_datum_t * cladatum)
00587 {
00588 if (cladatum != NULL) {
00589 hashtab_map(cladatum->permissions.table, perm_destroy, NULL);
00590 hashtab_destroy(cladatum->permissions.table);
00591 free(cladatum);
00592 }
00593 }
00594
00595 int require_class(int pass)
00596 {
00597 char *class_id = queue_remove(id_queue);
00598 char *perm_id = NULL;
00599 class_datum_t *datum = NULL;
00600 perm_datum_t *perm = NULL;
00601 int ret;
00602
00603 if (pass == 2) {
00604 free(class_id);
00605 while ((perm_id = queue_remove(id_queue)) != NULL)
00606 free(perm_id);
00607 return 0;
00608 }
00609
00610
00611 if (class_id == NULL) {
00612 yyerror("no class name for class definition?");
00613 return -1;
00614 }
00615
00616 if ((datum = calloc(1, sizeof(*datum))) == NULL || symtab_init(&datum->permissions, PERM_SYMTAB_SIZE)) {
00617 yyerror("Out of memory!");
00618 goto cleanup;
00619 }
00620 ret = require_symbol(SYM_CLASSES, class_id, datum, &datum->s.value, &datum->s.value);
00621 switch (ret) {
00622 case -3:
00623 {
00624 yyerror("Out of memory!");
00625 free(class_id);
00626 class_datum_destroy(datum);
00627 goto cleanup;
00628 }
00629 case -2:
00630 {
00631 yyerror("duplicate declaration of class");
00632 free(class_id);
00633 class_datum_destroy(datum);
00634 goto cleanup;
00635 }
00636 case -1:
00637 {
00638 yyerror("could not require class here");
00639 free(class_id);
00640 class_datum_destroy(datum);
00641 goto cleanup;
00642 }
00643 case 0:
00644 {
00645
00646 if (policydb_index_classes(policydbp)) {
00647 yyerror("Out of memory!");
00648 goto cleanup;
00649 }
00650 break;
00651 }
00652 case 1:
00653 {
00654 class_datum_destroy(datum);
00655 datum = hashtab_search(policydbp->p_classes.table, class_id);
00656 assert(datum);
00657 free(class_id);
00658 break;
00659 }
00660 default:
00661 {
00662 assert(0);
00663 }
00664 }
00665
00666
00667 while ((perm_id = queue_remove(id_queue)) != NULL) {
00668 int allocated = 0;
00669
00670
00671 perm = hashtab_search(datum->permissions.table, perm_id);
00672 if (!perm && datum->comdatum)
00673 perm = hashtab_search(datum->comdatum->permissions.table, perm_id);
00674 if (perm) {
00675
00676 free(perm_id);
00677 } else {
00678
00679 if (policydbp->policy_type == POLICY_BASE) {
00680 yyerror2("Base policy - require of permission %s without prior declaration.", perm_id);
00681 free(perm_id);
00682 goto cleanup;
00683 }
00684 allocated = 1;
00685 if ((perm = malloc(sizeof(*perm))) == NULL) {
00686 yyerror("Out of memory!");
00687 free(perm_id);
00688 goto cleanup;
00689 }
00690 memset(perm, 0, sizeof(*perm));
00691 ret = hashtab_insert(datum->permissions.table, perm_id, perm);
00692 if (ret) {
00693 yyerror("Out of memory!");
00694 free(perm_id);
00695 free(perm);
00696 goto cleanup;
00697 }
00698 perm->s.value = datum->permissions.nprim + 1;
00699 }
00700
00701 if (add_perm_to_class(perm->s.value, datum->s.value) == -1) {
00702 yyerror("Out of memory!");
00703 goto cleanup;
00704 }
00705
00706
00707 if (allocated)
00708 datum->permissions.nprim++;
00709 }
00710 return 0;
00711 cleanup:
00712 return -1;
00713 }
00714
00715 int require_role(int pass)
00716 {
00717 char *id = queue_remove(id_queue);
00718 role_datum_t *role = NULL;
00719 int retval;
00720 if (pass == 2) {
00721 free(id);
00722 return 0;
00723 }
00724 if (id == NULL) {
00725 yyerror("no role name");
00726 return -1;
00727 }
00728 if ((role = malloc(sizeof(*role))) == NULL) {
00729 free(id);
00730 yyerror("Out of memory!");
00731 return -1;
00732 }
00733 role_datum_init(role);
00734 retval = require_symbol(SYM_ROLES, id, (hashtab_datum_t *) role, &role->s.value, &role->s.value);
00735 if (retval != 0) {
00736 free(id);
00737 role_datum_destroy(role);
00738 free(role);
00739 }
00740 switch (retval) {
00741 case -3:
00742 {
00743 yyerror("Out of memory!");
00744 return -1;
00745 }
00746 case -2:
00747 {
00748 yyerror("duplicate declaration of role");
00749 return -1;
00750 }
00751 case -1:
00752 {
00753 yyerror("could not require role here");
00754 return -1;
00755 }
00756 case 0:
00757 {
00758
00759 if (ebitmap_set_bit(&role->dominates, role->s.value - 1, 1)) {
00760 yyerror("Out of memory");
00761 return -1;
00762 }
00763 return 0;
00764 }
00765 case 1:
00766 {
00767 return 0;
00768 }
00769 default:
00770 {
00771 assert(0);
00772 }
00773 }
00774 }
00775
00776 static int require_type_or_attribute(int pass, unsigned char isattr)
00777 {
00778 char *id = queue_remove(id_queue);
00779 type_datum_t *type = NULL;
00780 int retval;
00781 if (pass == 2) {
00782 free(id);
00783 return 0;
00784 }
00785 if (id == NULL) {
00786 yyerror("no type name");
00787 return -1;
00788 }
00789 if ((type = malloc(sizeof(*type))) == NULL) {
00790 free(id);
00791 yyerror("Out of memory!");
00792 return -1;
00793 }
00794 type_datum_init(type);
00795 type->primary = 1;
00796 type->flavor = isattr ? TYPE_ATTRIB : TYPE_TYPE;
00797 retval = require_symbol(SYM_TYPES, id, (hashtab_datum_t *) type, &type->s.value, &type->s.value);
00798 if (retval != 0) {
00799 free(id);
00800 free(type);
00801 }
00802 switch (retval) {
00803 case -3:
00804 {
00805 yyerror("Out of memory!");
00806 return -1;
00807 }
00808 case -2:
00809 {
00810 yyerror("duplicate declaration of type/attribute");
00811 return -1;
00812 }
00813 case -1:
00814 {
00815 yyerror("could not require type/attribute here");
00816 return -1;
00817 }
00818 case 0:
00819 {
00820 return 0;
00821 }
00822 case 1:
00823 {
00824 return 0;
00825 }
00826 default:
00827 {
00828 assert(0);
00829 }
00830 }
00831 }
00832
00833 int require_type(int pass)
00834 {
00835 return require_type_or_attribute(pass, 0);
00836 }
00837
00838 int require_attribute(int pass)
00839 {
00840 return require_type_or_attribute(pass, 1);
00841 }
00842
00843 int require_user(int pass)
00844 {
00845 char *id = queue_remove(id_queue);
00846 user_datum_t *user = NULL;
00847 int retval;
00848 if (pass == 1) {
00849 free(id);
00850 return 0;
00851 }
00852 if (id == NULL) {
00853 yyerror("no user name");
00854 return -1;
00855 }
00856 if ((user = malloc(sizeof(*user))) == NULL) {
00857 free(id);
00858 yyerror("Out of memory!");
00859 return -1;
00860 }
00861 user_datum_init(user);
00862 retval = require_symbol(SYM_USERS, id, (hashtab_datum_t *) user, &user->s.value, &user->s.value);
00863 if (retval != 0) {
00864 free(id);
00865 user_datum_destroy(user);
00866 }
00867 switch (retval) {
00868 case -3:
00869 {
00870 yyerror("Out of memory!");
00871 return -1;
00872 }
00873 case -2:
00874 {
00875 yyerror("duplicate declaration of user");
00876 return -1;
00877 }
00878 case -1:
00879 {
00880 yyerror("could not require user here");
00881 return -1;
00882 }
00883 case 0:
00884 {
00885 return 0;
00886 }
00887 case 1:
00888 {
00889 return 0;
00890 }
00891 default:
00892 {
00893 assert(0);
00894 }
00895 }
00896 }
00897
00898 int require_bool(int pass)
00899 {
00900 char *id = queue_remove(id_queue);
00901 cond_bool_datum_t *booldatum = NULL;
00902 int retval;
00903 if (pass == 2) {
00904 free(id);
00905 return 0;
00906 }
00907 if (id == NULL) {
00908 yyerror("no boolean name");
00909 return -1;
00910 }
00911 if ((booldatum = calloc(1, sizeof(*booldatum))) == NULL) {
00912 cond_destroy_bool(id, booldatum, NULL);
00913 yyerror("Out of memory!");
00914 return -1;
00915 }
00916 retval = require_symbol(SYM_BOOLS, id, (hashtab_datum_t *) booldatum, &booldatum->s.value, &booldatum->s.value);
00917 if (retval != 0) {
00918 cond_destroy_bool(id, booldatum, NULL);
00919 }
00920 switch (retval) {
00921 case -3:
00922 {
00923 yyerror("Out of memory!");
00924 return -1;
00925 }
00926 case -2:
00927 {
00928 yyerror("duplicate declaration of boolean");
00929 return -1;
00930 }
00931 case -1:
00932 {
00933 yyerror("could not require boolean here");
00934 return -1;
00935 }
00936 case 0:
00937 {
00938 return 0;
00939 }
00940 case 1:
00941 {
00942 return 0;
00943 }
00944 default:
00945 {
00946 assert(0);
00947 }
00948 }
00949 }
00950
00951 int require_sens(int pass)
00952 {
00953 char *id = queue_remove(id_queue);
00954 level_datum_t *level = NULL;
00955 int retval;
00956 if (pass == 2) {
00957 free(id);
00958 return 0;
00959 }
00960 if (!id) {
00961 yyerror("no sensitivity name");
00962 return -1;
00963 }
00964 level = malloc(sizeof(level_datum_t));
00965 if (!level) {
00966 free(id);
00967 yyerror("Out of memory!");
00968 return -1;
00969 }
00970 level_datum_init(level);
00971 level->level = malloc(sizeof(mls_level_t));
00972 if (!level->level) {
00973 free(id);
00974 level_datum_destroy(level);
00975 free(level);
00976 yyerror("Out of memory!");
00977 return -1;
00978 }
00979 mls_level_init(level->level);
00980 retval = require_symbol(SYM_LEVELS, id, (hashtab_datum_t *) level, &level->level->sens, &level->level->sens);
00981 if (retval != 0) {
00982 free(id);
00983 mls_level_destroy(level->level);
00984 free(level->level);
00985 level_datum_destroy(level);
00986 free(level);
00987 }
00988 switch (retval) {
00989 case -3:
00990 {
00991 yyerror("Out of memory!");
00992 return -1;
00993 }
00994 case -2:
00995 {
00996 yyerror("duplicate declaration of sensitivity");
00997 return -1;
00998 }
00999 case -1:
01000 {
01001 yyerror("could not require sensitivity here");
01002 return -1;
01003 }
01004 case 0:
01005 {
01006 return 0;
01007 }
01008 case 1:
01009 {
01010 return 0;
01011 }
01012 default:
01013 {
01014 assert(0);
01015 }
01016 }
01017 }
01018
01019 int require_cat(int pass)
01020 {
01021 char *id = queue_remove(id_queue);
01022 cat_datum_t *cat = NULL;
01023 int retval;
01024 if (pass == 2) {
01025 free(id);
01026 return 0;
01027 }
01028 if (!id) {
01029 yyerror("no category name");
01030 return -1;
01031 }
01032 cat = malloc(sizeof(cat_datum_t));
01033 if (!cat) {
01034 free(id);
01035 yyerror("Out of memory!");
01036 return -1;
01037 }
01038 cat_datum_init(cat);
01039
01040 retval = require_symbol(SYM_CATS, id, (hashtab_datum_t *) cat, &cat->s.value, &cat->s.value);
01041 if (retval != 0) {
01042 free(id);
01043 cat_datum_destroy(cat);
01044 free(cat);
01045 }
01046 switch (retval) {
01047 case -3:
01048 {
01049 yyerror("Out of memory!");
01050 return -1;
01051 }
01052 case -2:
01053 {
01054 yyerror("duplicate declaration of category");
01055 return -1;
01056 }
01057 case -1:
01058 {
01059 yyerror("could not require category here");
01060 return -1;
01061 }
01062 case 0:
01063 {
01064 return 0;
01065 }
01066 case 1:
01067 {
01068 return 0;
01069 }
01070 default:
01071 {
01072 assert(0);
01073 }
01074 }
01075 }
01076
01077 static int is_scope_in_stack(scope_datum_t * scope, scope_stack_t * stack)
01078 {
01079 int i;
01080 if (stack == NULL) {
01081 return 0;
01082 }
01083 if (stack->type == 1) {
01084 avrule_decl_t *decl = stack->decl;
01085 for (i = 0; i < scope->decl_ids_len; i++) {
01086 if (scope->decl_ids[i] == decl->decl_id) {
01087 return 1;
01088 }
01089 }
01090 } else {
01091
01092
01093 }
01094
01095
01096 return is_scope_in_stack(scope, stack->parent);
01097 }
01098
01099 int is_id_in_scope(uint32_t symbol_type, hashtab_key_t id)
01100 {
01101 scope_datum_t *scope = (scope_datum_t *) hashtab_search(policydbp->scope[symbol_type].table, id);
01102 if (scope == NULL) {
01103 return 1;
01104 }
01105 return is_scope_in_stack(scope, stack_top);
01106 }
01107
01108 static int is_perm_in_scope_index(uint32_t perm_value, uint32_t class_value, scope_index_t * scope)
01109 {
01110 if (class_value > scope->class_perms_len) {
01111 return 1;
01112 }
01113 if (ebitmap_get_bit(scope->class_perms_map + class_value - 1, perm_value - 1)) {
01114 return 1;
01115 }
01116 return 0;
01117 }
01118
01119 static int is_perm_in_stack(uint32_t perm_value, uint32_t class_value, scope_stack_t * stack)
01120 {
01121 if (stack == NULL) {
01122 return 0;
01123 }
01124 if (stack->type == 1) {
01125 avrule_decl_t *decl = stack->decl;
01126 if (is_perm_in_scope_index(perm_value, class_value, &decl->required)
01127 || is_perm_in_scope_index(perm_value, class_value, &decl->declared)) {
01128 return 1;
01129 }
01130 } else {
01131
01132
01133 }
01134
01135
01136 return is_perm_in_stack(perm_value, class_value, stack->parent);
01137 }
01138
01139 int is_perm_in_scope(hashtab_key_t perm_id, hashtab_key_t class_id)
01140 {
01141 class_datum_t *cladatum = (class_datum_t *) hashtab_search(policydbp->p_classes.table,
01142 class_id);
01143 perm_datum_t *perdatum;
01144 if (cladatum == NULL) {
01145 return 1;
01146 }
01147 perdatum = (perm_datum_t *) hashtab_search(cladatum->permissions.table, perm_id);
01148 if (perdatum == NULL) {
01149 return 1;
01150 }
01151 return is_perm_in_stack(perdatum->s.value, cladatum->s.value, stack_top);
01152 }
01153
01154 cond_list_t *get_current_cond_list(cond_list_t * cond)
01155 {
01156
01157
01158 avrule_decl_t *decl = stack_top->decl;
01159 return get_decl_cond_list(policydbp, decl, cond);
01160 }
01161
01162
01163
01164
01165
01166 void append_cond_list(cond_list_t * cond)
01167 {
01168 cond_list_t *old_cond = get_current_cond_list(cond);
01169 avrule_t *tmp;
01170 assert(old_cond != NULL);
01171 if (old_cond->avtrue_list == NULL) {
01172 old_cond->avtrue_list = cond->avtrue_list;
01173 } else {
01174 for (tmp = old_cond->avtrue_list; tmp->next != NULL; tmp = tmp->next) ;
01175 tmp->next = cond->avtrue_list;
01176 }
01177 if (old_cond->avfalse_list == NULL) {
01178 old_cond->avfalse_list = cond->avfalse_list;
01179 } else {
01180 for (tmp = old_cond->avfalse_list; tmp->next != NULL; tmp = tmp->next) ;
01181 tmp->next = cond->avfalse_list;
01182 }
01183 }
01184
01185 void append_avrule(avrule_t * avrule)
01186 {
01187 avrule_decl_t *decl = stack_top->decl;
01188
01189
01190
01191
01192
01193
01194 assert(stack_top->type == 1);
01195
01196 if (stack_top->last_avrule == NULL) {
01197 decl->avrules = avrule;
01198 } else {
01199 stack_top->last_avrule->next = avrule;
01200 }
01201 stack_top->last_avrule = avrule;
01202 }
01203
01204
01205 void append_role_trans(role_trans_rule_t * role_tr_rules)
01206 {
01207 avrule_decl_t *decl = stack_top->decl;
01208
01209
01210 assert(stack_top->type == 1);
01211
01212 role_tr_rules->next = decl->role_tr_rules;
01213 decl->role_tr_rules = role_tr_rules;
01214 }
01215
01216
01217 void append_role_allow(role_allow_rule_t * role_allow_rules)
01218 {
01219 avrule_decl_t *decl = stack_top->decl;
01220
01221
01222 assert(stack_top->type == 1);
01223
01224 role_allow_rules->next = decl->role_allow_rules;
01225 decl->role_allow_rules = role_allow_rules;
01226 }
01227
01228
01229 void append_range_trans(range_trans_rule_t * range_tr_rules)
01230 {
01231 avrule_decl_t *decl = stack_top->decl;
01232
01233
01234 assert(stack_top->type == 1);
01235
01236 range_tr_rules->next = decl->range_tr_rules;
01237 decl->range_tr_rules = range_tr_rules;
01238 }
01239
01240 int begin_optional(int pass)
01241 {
01242 avrule_block_t *block = NULL;
01243 avrule_decl_t *decl;
01244 if (pass == 1) {
01245
01246 if ((block = avrule_block_create()) == NULL || (decl = avrule_decl_create(next_decl_id)) == NULL) {
01247 goto cleanup;
01248 }
01249 block->flags |= AVRULE_OPTIONAL;
01250 block->branch_list = decl;
01251 last_block->next = block;
01252 } else {
01253
01254 block = last_block->next;
01255 assert(block != NULL && block->branch_list != NULL && block->branch_list->decl_id == next_decl_id);
01256 decl = block->branch_list;
01257 }
01258 if (push_stack(1, block, decl) == -1) {
01259 goto cleanup;
01260 }
01261 stack_top->last_avrule = NULL;
01262 last_block = block;
01263 next_decl_id++;
01264 return 0;
01265 cleanup:
01266 yyerror("Out of memory!");
01267 avrule_block_destroy(block);
01268 return -1;
01269 }
01270
01271 int end_optional(int pass)
01272 {
01273
01274 pop_stack();
01275 return 0;
01276 }
01277
01278 int begin_optional_else(int pass)
01279 {
01280 avrule_decl_t *decl;
01281 assert(stack_top->type == 1 && stack_top->in_else == 0);
01282 if (pass == 1) {
01283
01284
01285 if ((decl = avrule_decl_create(next_decl_id)) == NULL) {
01286 yyerror("Out of memory!");
01287 return -1;
01288 }
01289 stack_top->decl->next = decl;
01290 } else {
01291
01292
01293 decl = stack_top->decl->next;
01294 assert(decl != NULL && decl->next == NULL && decl->decl_id == next_decl_id);
01295 }
01296 stack_top->in_else = 1;
01297 stack_top->decl = decl;
01298 stack_top->last_avrule = NULL;
01299 stack_top->require_given = 0;
01300 next_decl_id++;
01301 return 0;
01302 }
01303
01304 static int copy_requirements(avrule_decl_t * dest, scope_stack_t * stack)
01305 {
01306 int i;
01307 if (stack == NULL) {
01308 return 0;
01309 }
01310 if (stack->type == 1) {
01311 scope_index_t *src_scope = &stack->decl->required;
01312 scope_index_t *dest_scope = &dest->required;
01313 for (i = 0; i < SYM_NUM; i++) {
01314 ebitmap_t *src_bitmap = &src_scope->scope[i];
01315 ebitmap_t *dest_bitmap = &dest_scope->scope[i];
01316 if (ebitmap_union(dest_bitmap, src_bitmap)) {
01317 yyerror("Out of memory!");
01318 return -1;
01319 }
01320 }
01321
01322 if (src_scope->class_perms_len > dest_scope->class_perms_len) {
01323 ebitmap_t *new_map = realloc(dest_scope->class_perms_map,
01324 src_scope->class_perms_len * sizeof(*new_map));
01325 if (new_map == NULL) {
01326 yyerror("Out of memory!");
01327 return -1;
01328 }
01329 dest_scope->class_perms_map = new_map;
01330 for (i = dest_scope->class_perms_len; i < src_scope->class_perms_len; i++) {
01331 ebitmap_init(dest_scope->class_perms_map + i);
01332 }
01333 dest_scope->class_perms_len = src_scope->class_perms_len;
01334 }
01335 for (i = 0; i < src_scope->class_perms_len; i++) {
01336 ebitmap_t *src_bitmap = &src_scope->class_perms_map[i];
01337 ebitmap_t *dest_bitmap = &dest_scope->class_perms_map[i];
01338 if (ebitmap_union(dest_bitmap, src_bitmap)) {
01339 yyerror("Out of memory!");
01340 return -1;
01341 }
01342 }
01343 }
01344 return copy_requirements(dest, stack->parent);
01345 }
01346
01347
01348
01349
01350
01351 int end_avrule_block(int pass)
01352 {
01353 avrule_decl_t *decl = stack_top->decl;
01354 assert(stack_top->type == 1);
01355 if (pass == 2) {
01356
01357
01358 if (copy_requirements(decl, stack_top->parent) == -1) {
01359 return -1;
01360 }
01361 return 0;
01362 }
01363 if (!stack_top->in_else && !stack_top->require_given) {
01364 if (policydbp->policy_type == POLICY_BASE && stack_top->parent != NULL) {
01365
01366 return 0;
01367 } else {
01368
01369 yyerror("This block has no require section.");
01370 return -1;
01371 }
01372 }
01373 return 0;
01374 }
01375
01376
01377
01378 static int push_stack(int stack_type, ...)
01379 {
01380 scope_stack_t *s = calloc(1, sizeof(*s));
01381 va_list ap;
01382 if (s == NULL) {
01383 return -1;
01384 }
01385 va_start(ap, stack_type);
01386 switch (s->type = stack_type) {
01387 case 1:
01388 {
01389 s->u.avrule = va_arg(ap, avrule_block_t *);
01390 s->decl = va_arg(ap, avrule_decl_t *);
01391 break;
01392 }
01393 case 2:
01394 {
01395 s->u.cond_list = va_arg(ap, cond_list_t *);
01396 break;
01397 }
01398 default:
01399
01400 assert(0);
01401 }
01402 va_end(ap);
01403 s->parent = stack_top;
01404 s->child = NULL;
01405 stack_top = s;
01406 return 0;
01407 }
01408
01409
01410
01411 static void pop_stack(void)
01412 {
01413 scope_stack_t *parent;
01414 assert(stack_top != NULL);
01415 parent = stack_top->parent;
01416 if (parent != NULL) {
01417 parent->child = NULL;
01418 }
01419 free(stack_top);
01420 stack_top = parent;
01421 }