18c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android/* Author : Joshua Brindle <jbrindle@tresys.com> 28c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * Karl MacMillan <kmacmillan@tresys.com> 38c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * Jason Tang <jtang@tresys.com> 48c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * Added support for binary policy modules 58c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * 68c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * Copyright (C) 2004 - 2005 Tresys Technology, LLC 78c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * This program is free software; you can redistribute it and/or modify 88c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * it under the terms of the GNU General Public License as published by 98c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * the Free Software Foundation, version 2. 108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android */ 118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android#include <assert.h> 138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android#include <stdarg.h> 148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android#include <stdlib.h> 158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android#include <string.h> 168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android#include <sepol/policydb/policydb.h> 188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android#include <sepol/policydb/avrule_block.h> 198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android#include <sepol/policydb/conditional.h> 208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android#include "queue.h" 228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android#include "module_compiler.h" 238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidunion stack_item_u { 258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android avrule_block_t *avrule; 268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android cond_list_t *cond_list; 278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}; 288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidtypedef struct scope_stack { 308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android union stack_item_u u; 318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android int type; /* for above union: 1 = avrule block, 2 = conditional */ 328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android avrule_decl_t *decl; /* if in an avrule block, which 338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * declaration is current */ 348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android avrule_t *last_avrule; 358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android int in_else; /* if in an avrule block, within ELSE branch */ 368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android int require_given; /* 1 if this block had at least one require */ 378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android struct scope_stack *parent, *child; 388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} scope_stack_t; 398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidextern policydb_t *policydbp; 418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidextern queue_t id_queue; 428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidextern int yyerror(char *msg); 438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidextern void yyerror2(char *fmt, ...); 448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic int push_stack(int stack_type, ...); 468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic void pop_stack(void); 478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android/* keep track of the last item added to the stack */ 498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic scope_stack_t *stack_top = NULL; 508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic avrule_block_t *last_block; 518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic uint32_t next_decl_id = 1; 528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_policy(int pass, int module_header_given) 548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android char *id; 568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (module_header_given) { 588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (policydbp->policy_type != POLICY_MOD) { 598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror 608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android ("Module specification found while not building a policy module.\n"); 618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (pass == 2) { 658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android while ((id = queue_remove(id_queue)) != NULL) 668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(id); 678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else { 688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android id = (char *)queue_remove(id_queue); 698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (!id) { 708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("no module name"); 718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android policydbp->name = id; 748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if ((policydbp->version = 758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android queue_remove(id_queue)) == NULL) { 768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror 778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android ("Expected a module version but none was found."); 788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else { 828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (policydbp->policy_type == POLICY_MOD) { 838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror 848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android ("Building a policy module, but no module specification found.\n"); 858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* the first declaration within the global avrule 898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android block will always have an id of 1 */ 908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android next_decl_id = 2; 918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* reset the scoping stack */ 938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android while (stack_top != NULL) { 948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android pop_stack(); 958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (push_stack(1, policydbp->global, policydbp->global->branch_list) == 978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android -1) { 988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 1008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android last_block = policydbp->global; 1018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; 1028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 1038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 1048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android/* Given the current parse stack, returns 1 if a declaration would be 1058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * allowed here or 0 if not. For example, declarations are not 1068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * allowed in conditionals, so if there are any conditionals in the 1078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * current scope stack then this would return a 0. 1088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android */ 1098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic int is_declaration_allowed(void) 1108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 1118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (stack_top->type != 1 || stack_top->in_else) { 1128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; 1138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 1148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 1; 1158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 1168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 1178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android/* Attempt to declare a symbol within the current declaration. If 1188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * currently within a non-conditional and in a non-else branch then 1198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * insert the symbol, return 0 on success if symbol was undeclared. 1208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * For roles and users, it is legal to have multiple declarations; as 1218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * such return 1 to indicate that caller must free() the datum because 1228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * it was not added. If symbols may not be declared here return -1. 1238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * For duplicate declarations return -2. For all else, including out 1248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * of memory, return -3. Note that dest_value and datum_value might 1258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * not be restricted pointers. */ 1268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint declare_symbol(uint32_t symbol_type, 1278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android hashtab_key_t key, hashtab_datum_t datum, 1288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android uint32_t * dest_value, uint32_t * datum_value) 1298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 1308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android avrule_decl_t *decl = stack_top->decl; 1318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android int retval; 1328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 1338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* first check that symbols may be declared here */ 1348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (!is_declaration_allowed()) { 1358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 1368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 1378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android retval = symtab_insert(policydbp, symbol_type, key, datum, 1388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android SCOPE_DECL, decl->decl_id, dest_value); 1398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (retval == 1 && dest_value) { 1408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android symtab_datum_t *s = 1418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android (symtab_datum_t *) hashtab_search(policydbp-> 1428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android symtab[symbol_type].table, 1438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android key); 1448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android assert(s != NULL); 1458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 1468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (symbol_type == SYM_LEVELS) { 1478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android *dest_value = ((level_datum_t *)s)->level->sens; 1488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else { 1498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android *dest_value = s->value; 1508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 1518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else if (retval == -2) { 1528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -2; 1538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else if (retval < 0) { 1548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -3; 1558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else { /* fall through possible if retval is 0 */ 1568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 1578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (datum_value != NULL) { 1588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (ebitmap_set_bit(decl->declared.scope + symbol_type, 1598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android *datum_value - 1, 1)) { 1608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -3; 1618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 1628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 1638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return retval; 1648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 1658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 1668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic int role_implicit_bounds(hashtab_t roles_tab, 1678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android char *role_id, role_datum_t *role) 1688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 1698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android role_datum_t *bounds; 1708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android char *bounds_id, *delim; 1718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 1728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android delim = strrchr(role_id, '.'); 1738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (!delim) 1748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; /* no implicit boundary */ 1758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 1768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android bounds_id = strdup(role_id); 1778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (!bounds_id) { 1788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("out of memory"); 1798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 1808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 1818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android bounds_id[(size_t)(delim - role_id)] = '\0'; 1828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 1838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android bounds = hashtab_search(roles_tab, bounds_id); 1848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (!bounds) { 1858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror2("role %s doesn't exist, is implicit bounds of %s", 1868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android bounds_id, role_id); 1878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 1888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 1898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 1908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (!role->bounds) 1918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android role->bounds = bounds->s.value; 1928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android else if (role->bounds != bounds->s.value) { 1938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror2("role %s has inconsistent bounds %s/%s", 1948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android role_id, bounds_id, 1958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android policydbp->p_role_val_to_name[role->bounds - 1]); 1968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 1978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 1988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(bounds_id); 1998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 2008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; 2018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 2028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 2038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidrole_datum_t *declare_role(unsigned char isattr) 2048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 2058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android char *id = queue_remove(id_queue), *dest_id = NULL; 2068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android role_datum_t *role = NULL, *dest_role = NULL; 2078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android int retval; 2088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android uint32_t value; 2098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 2108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (id == NULL) { 2118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("no role name"); 2128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return NULL; 2138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 2148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if ((role = (role_datum_t *) malloc(sizeof(*role))) == NULL) { 2158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 2168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(id); 2178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return NULL; 2188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 2198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android role_datum_init(role); 2208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android role->flavor = isattr ? ROLE_ATTRIB : ROLE_ROLE; 2218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android retval = 2228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android declare_symbol(SYM_ROLES, id, (hashtab_datum_t *) role, &value, 2238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android &value); 2248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (retval == 0) { 2258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android role->s.value = value; 2268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if ((dest_id = strdup(id)) == NULL) { 2278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 2288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return NULL; 2298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 2308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else { 2318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* this role was already declared in this module, or error */ 2328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android dest_id = id; 2338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android role_datum_destroy(role); 2348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(role); 2358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 2368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (retval == 0 || retval == 1) { 2378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* create a new role_datum_t for this decl, if necessary */ 2388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android hashtab_t roles_tab; 2398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android assert(stack_top->type == 1); 2408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (stack_top->parent == NULL) { 2418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* in parent, so use global symbol table */ 2428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android roles_tab = policydbp->p_roles.table; 2438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else { 2448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android roles_tab = stack_top->decl->p_roles.table; 2458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 2468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android dest_role = (role_datum_t *) hashtab_search(roles_tab, dest_id); 2478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (dest_role == NULL) { 2488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if ((dest_role = 2498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android (role_datum_t *) malloc(sizeof(*dest_role))) == 2508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android NULL) { 2518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 2528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(dest_id); 2538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return NULL; 2548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 2558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android role_datum_init(dest_role); 2568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android dest_role->s.value = value; 2578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android dest_role->flavor = isattr ? ROLE_ATTRIB : ROLE_ROLE; 2588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (role_implicit_bounds(roles_tab, dest_id, dest_role)) { 2598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(dest_id); 2608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android role_datum_destroy(dest_role); 2618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(dest_role); 2628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return NULL; 2638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 2648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (hashtab_insert(roles_tab, dest_id, dest_role)) { 2658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 2668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(dest_id); 2678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android role_datum_destroy(dest_role); 2688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(dest_role); 2698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return NULL; 2708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 2718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else { 2728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(dest_id); 2738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 2748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else { 2758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(dest_id); 2768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 2778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android switch (retval) { 2788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case -3:{ 2798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 2808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return NULL; 2818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 2828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case -2:{ 2838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("duplicate declaration of role"); 2848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return NULL; 2858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 2868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case -1:{ 2878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("could not declare role here"); 2888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return NULL; 2898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 2908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case 0:{ 2918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (ebitmap_set_bit 2928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android (&dest_role->dominates, role->s.value - 1, 1)) { 2938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("out of memory"); 2948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return NULL; 2958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 2968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return dest_role; 2978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 2988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case 1:{ 2998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return dest_role; /* role already declared for this block */ 3008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 3018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android default:{ 3028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android assert(0); /* should never get here */ 3038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 3048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 3058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 3068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 3078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidtype_datum_t *declare_type(unsigned char primary, unsigned char isattr) 3088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 3098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android char *id; 3108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android type_datum_t *typdatum; 3118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android int retval; 3128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android uint32_t value = 0; 3138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 3148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android id = (char *)queue_remove(id_queue); 3158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (!id) { 3168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("no type/attribute name?"); 3178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return NULL; 3188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 3198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (strcmp(id, "self") == 0) { 3208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror 3218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android ("'self' is a reserved type name and may not be declared."); 3228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(id); 3238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return NULL; 3248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 3258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 3268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android typdatum = (type_datum_t *) malloc(sizeof(type_datum_t)); 3278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (!typdatum) { 3288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 3298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(id); 3308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return NULL; 3318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 3328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android type_datum_init(typdatum); 3338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android typdatum->primary = primary; 3348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android typdatum->flavor = isattr ? TYPE_ATTRIB : TYPE_TYPE; 3358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 3368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android retval = declare_symbol(SYM_TYPES, id, typdatum, &value, &value); 3378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (retval == 0 || retval == 1) { 3388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (typdatum->primary) { 3398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android typdatum->s.value = value; 3408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 3418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else { 3428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* error occurred (can't have duplicate type declarations) */ 3438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(id); 3448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android type_datum_destroy(typdatum); 3458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(typdatum); 3468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 3478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android switch (retval) { 3488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case -3:{ 3498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 3508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return NULL; 3518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 3528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case -2:{ 3538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror2("duplicate declaration of type/attribute"); 3548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return NULL; 3558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 3568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case -1:{ 3578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("could not declare type/attribute here"); 3588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return NULL; 3598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 3608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case 0: 3618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case 1:{ 3628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return typdatum; 3638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 3648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android default:{ 3658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android assert(0); /* should never get here */ 3668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 3678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 3688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 3698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 3708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic int user_implicit_bounds(hashtab_t users_tab, 3718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android char *user_id, user_datum_t *user) 3728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 3738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android user_datum_t *bounds; 3748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android char *bounds_id, *delim; 3758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 3768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android delim = strrchr(user_id, '.'); 3778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (!delim) 3788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; /* no implicit boundary */ 3798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 3808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android bounds_id = strdup(user_id); 3818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (!bounds_id) { 3828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("out of memory"); 3838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 3848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 3858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android bounds_id[(size_t)(delim - user_id)] = '\0'; 3868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 3878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android bounds = hashtab_search(users_tab, bounds_id); 3888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (!bounds) { 3898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror2("user %s doesn't exist, is implicit bounds of %s", 3908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android bounds_id, user_id); 3918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 3928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 3938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 3948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (!user->bounds) 3958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android user->bounds = bounds->s.value; 3968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android else if (user->bounds != bounds->s.value) { 3978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror2("user %s has inconsistent bounds %s/%s", 3988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android user_id, bounds_id, 3998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android policydbp->p_role_val_to_name[user->bounds - 1]); 4008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 4018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 4028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(bounds_id); 4038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 4048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; 4058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 4068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 4078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androiduser_datum_t *declare_user(void) 4088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 4098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android char *id = queue_remove(id_queue), *dest_id = NULL; 4108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android user_datum_t *user = NULL, *dest_user = NULL; 4118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android int retval; 4128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android uint32_t value = 0; 4138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 4148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (id == NULL) { 4158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("no user name"); 4168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return NULL; 4178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 4188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if ((user = (user_datum_t *) malloc(sizeof(*user))) == NULL) { 4198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 4208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(id); 4218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return NULL; 4228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 4238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android user_datum_init(user); 4248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 4258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android retval = 4268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android declare_symbol(SYM_USERS, id, (hashtab_datum_t *) user, &value, 4278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android &value); 4288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 4298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (retval == 0) { 4308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android user->s.value = value; 4318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if ((dest_id = strdup(id)) == NULL) { 4328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 4338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return NULL; 4348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 4358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else { 4368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* this user was already declared in this module, or error */ 4378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android dest_id = id; 4388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android user_datum_destroy(user); 4398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(user); 4408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 4418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (retval == 0 || retval == 1) { 4428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* create a new user_datum_t for this decl, if necessary */ 4438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android hashtab_t users_tab; 4448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android assert(stack_top->type == 1); 4458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (stack_top->parent == NULL) { 4468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* in parent, so use global symbol table */ 4478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android users_tab = policydbp->p_users.table; 4488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else { 4498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android users_tab = stack_top->decl->p_users.table; 4508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 4518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android dest_user = (user_datum_t *) hashtab_search(users_tab, dest_id); 4528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (dest_user == NULL) { 4538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if ((dest_user = 4548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android (user_datum_t *) malloc(sizeof(*dest_user))) == 4558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android NULL) { 4568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 4578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(dest_id); 4588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return NULL; 4598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 4608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android user_datum_init(dest_user); 4618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android dest_user->s.value = value; 4628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (user_implicit_bounds(users_tab, dest_id, dest_user)) { 4638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(dest_id); 4648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android user_datum_destroy(dest_user); 4658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(dest_user); 4668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return NULL; 4678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 4688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (hashtab_insert(users_tab, dest_id, dest_user)) { 4698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 4708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(dest_id); 4718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android user_datum_destroy(dest_user); 4728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(dest_user); 4738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return NULL; 4748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 4758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else { 4768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(dest_id); 4778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 4788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else { 4798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(dest_id); 4808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 4818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android switch (retval) { 4828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case -3:{ 4838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 4848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return NULL; 4858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 4868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case -2:{ 4878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("duplicate declaration of user"); 4888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return NULL; 4898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 4908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case -1:{ 4918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("could not declare user here"); 4928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return NULL; 4938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 4948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case 0:{ 4958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return dest_user; 4968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 4978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case 1:{ 4988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return dest_user; /* user already declared for this block */ 4998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 5008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android default:{ 5018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android assert(0); /* should never get here */ 5028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 5038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 5048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 5058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 5068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android/* Return a type_datum_t for the local avrule_decl with the given ID. 5078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * If it does not exist, create one with the same value as 'value'. 5088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * This function assumes that the ID is within scope. c.f., 5098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * is_id_in_scope(). 5108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * 5118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * NOTE: this function usurps ownership of id afterwards. The caller 5128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * shall not reference it nor free() it afterwards. 5138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android */ 5148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidtype_datum_t *get_local_type(char *id, uint32_t value, unsigned char isattr) 5158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 5168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android type_datum_t *dest_typdatum; 5178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android hashtab_t types_tab; 5188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android assert(stack_top->type == 1); 5198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (stack_top->parent == NULL) { 5208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* in global, so use global symbol table */ 5218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android types_tab = policydbp->p_types.table; 5228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else { 5238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android types_tab = stack_top->decl->p_types.table; 5248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 5258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android dest_typdatum = hashtab_search(types_tab, id); 5268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (!dest_typdatum) { 5278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android dest_typdatum = (type_datum_t *) malloc(sizeof(type_datum_t)); 5288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (dest_typdatum == NULL) { 5298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(id); 5308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return NULL; 5318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 5328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android type_datum_init(dest_typdatum); 5338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android dest_typdatum->s.value = value; 5348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android dest_typdatum->flavor = isattr ? TYPE_ATTRIB : TYPE_TYPE; 5358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android dest_typdatum->primary = 1; 5368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (hashtab_insert(types_tab, id, dest_typdatum)) { 5378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(id); 5388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android type_datum_destroy(dest_typdatum); 5398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(dest_typdatum); 5408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return NULL; 5418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 5428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 5438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else { 5448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(id); 5458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (dest_typdatum->flavor != isattr ? TYPE_ATTRIB : TYPE_TYPE) { 5468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return NULL; 5478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 5488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 5498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return dest_typdatum; 5508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 5518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 5528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android/* Return a role_datum_t for the local avrule_decl with the given ID. 5538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * If it does not exist, create one with the same value as 'value'. 5548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * This function assumes that the ID is within scope. c.f., 5558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * is_id_in_scope(). 5568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * 5578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * NOTE: this function usurps ownership of id afterwards. The caller 5588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * shall not reference it nor free() it afterwards. 5598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android */ 5608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidrole_datum_t *get_local_role(char *id, uint32_t value, unsigned char isattr) 5618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 5628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android role_datum_t *dest_roledatum; 5638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android hashtab_t roles_tab; 5648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 5658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android assert(stack_top->type == 1); 5668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 5678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (stack_top->parent == NULL) { 5688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* in global, so use global symbol table */ 5698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android roles_tab = policydbp->p_roles.table; 5708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else { 5718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android roles_tab = stack_top->decl->p_roles.table; 5728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 5738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 5748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android dest_roledatum = hashtab_search(roles_tab, id); 5758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (!dest_roledatum) { 5768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android dest_roledatum = (role_datum_t *)malloc(sizeof(role_datum_t)); 5778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (dest_roledatum == NULL) { 5788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(id); 5798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return NULL; 5808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 5818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 5828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android role_datum_init(dest_roledatum); 5838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android dest_roledatum->s.value = value; 5848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android dest_roledatum->flavor = isattr ? ROLE_ATTRIB : ROLE_ROLE; 5858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 5868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (hashtab_insert(roles_tab, id, dest_roledatum)) { 5878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(id); 5888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android role_datum_destroy(dest_roledatum); 5898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(dest_roledatum); 5908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return NULL; 5918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 5928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else { 5938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(id); 5948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (dest_roledatum->flavor != isattr ? ROLE_ATTRIB : ROLE_ROLE) 5958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return NULL; 5968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 5978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 5988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return dest_roledatum; 5998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 6008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 6018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android/* Given the current parse stack, returns 1 if a requirement would be 6028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * allowed here or 0 if not. For example, the ELSE branch may never 6038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * have its own requirements. 6048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android */ 6058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic int is_require_allowed(void) 6068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 6078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (stack_top->type == 1 && !stack_top->in_else) { 6088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 1; 6098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 6108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; 6118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 6128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 6138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android/* Attempt to require a symbol within the current scope. If currently 6148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * within an optional (and not its else branch), add the symbol to the 6158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * required list. Return 0 on success, 1 if caller needs to free() 6168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * datum. If symbols may not be declared here return -1. For duplicate 6178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * declarations return -2. For all else, including out of memory, 6188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * return -3.. Note that dest_value and datum_value might not be 6198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * restricted pointers. 6208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android */ 6218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint require_symbol(uint32_t symbol_type, 6228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android hashtab_key_t key, hashtab_datum_t datum, 6238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android uint32_t * dest_value, uint32_t * datum_value) 6248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 6258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android avrule_decl_t *decl = stack_top->decl; 6268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android int retval; 6278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 6288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* first check that symbols may be required here */ 6298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (!is_require_allowed()) { 6308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 6318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 6328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android retval = symtab_insert(policydbp, symbol_type, key, datum, 6338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android SCOPE_REQ, decl->decl_id, dest_value); 6348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (retval == 1) { 6358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android symtab_datum_t *s = 6368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android (symtab_datum_t *) hashtab_search(policydbp-> 6378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android symtab[symbol_type].table, 6388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android key); 6398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android assert(s != NULL); 6408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 6418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (symbol_type == SYM_LEVELS) { 6428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android *dest_value = ((level_datum_t *)s)->level->sens; 6438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else { 6448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android *dest_value = s->value; 6458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 6468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else if (retval == -2) { 6478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* ignore require statements if that symbol was 6488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * previously declared and is in current scope */ 6498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android int prev_declaration_ok = 0; 6508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (is_id_in_scope(symbol_type, key)) { 6518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (symbol_type == SYM_TYPES) { 6528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* check that previous symbol has same 6538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * type/attribute-ness */ 6548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android unsigned char new_isattr = 6558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android ((type_datum_t *) datum)->flavor; 6568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android type_datum_t *old_datum = 6578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android (type_datum_t *) hashtab_search(policydbp-> 6588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android symtab 6598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android [SYM_TYPES]. 6608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android table, key); 6618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android assert(old_datum != NULL); 6628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android unsigned char old_isattr = old_datum->flavor; 6638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android prev_declaration_ok = 6648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android (old_isattr == new_isattr ? 1 : 0); 6658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else { 6668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android prev_declaration_ok = 1; 6678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 6688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 6698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (prev_declaration_ok) { 6708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* ignore this require statement because it 6718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * was already declared within my scope */ 6728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android stack_top->require_given = 1; 6738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 1; 6748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else { 6758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* previous declaration was not in scope or 6768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * had a mismatched type/attribute, so 6778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * generate an error */ 6788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -2; 6798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 6808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else if (retval < 0) { 6818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -3; 6828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else { /* fall through possible if retval is 0 or 1 */ 6838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 6848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (datum_value != NULL) { 6858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (ebitmap_set_bit(decl->required.scope + symbol_type, 6868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android *datum_value - 1, 1)) { 6878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -3; 6888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 6898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 6908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android stack_top->require_given = 1; 6918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return retval; 6928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 6938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 6948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint add_perm_to_class(uint32_t perm_value, uint32_t class_value) 6958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 6968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android avrule_decl_t *decl = stack_top->decl; 6978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android scope_index_t *scope; 6988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 6998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android assert(perm_value >= 1); 7008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android assert(class_value >= 1); 7018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android scope = &decl->required; 7028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (class_value > scope->class_perms_len) { 7038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android int i; 7048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android ebitmap_t *new_map = realloc(scope->class_perms_map, 7058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android class_value * sizeof(*new_map)); 7068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (new_map == NULL) { 7078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 7088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 7098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android scope->class_perms_map = new_map; 7108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android for (i = scope->class_perms_len; i < class_value; i++) { 7118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android ebitmap_init(scope->class_perms_map + i); 7128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 7138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android scope->class_perms_len = class_value; 7148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 7158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (ebitmap_set_bit(scope->class_perms_map + class_value - 1, 7168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android perm_value - 1, 1)) { 7178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 7188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 7198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; 7208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 7218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 7228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic int perm_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p 7238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android __attribute__ ((unused))) 7248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 7258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (key) 7268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(key); 7278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(datum); 7288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; 7298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 7308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 7318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic void class_datum_destroy(class_datum_t * cladatum) 7328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 7338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (cladatum != NULL) { 7348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android hashtab_map(cladatum->permissions.table, perm_destroy, NULL); 7358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android hashtab_destroy(cladatum->permissions.table); 7368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(cladatum); 7378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 7388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 7398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 7408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint require_class(int pass) 7418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 7428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android char *class_id = queue_remove(id_queue); 7438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android char *perm_id = NULL; 7448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android class_datum_t *datum = NULL; 7458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android perm_datum_t *perm = NULL; 7468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android int ret; 7478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 7488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (pass == 2) { 7498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(class_id); 7508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android while ((perm_id = queue_remove(id_queue)) != NULL) 7518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(perm_id); 7528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; 7538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 7548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 7558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* first add the class if it is not already there */ 7568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (class_id == NULL) { 7578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("no class name for class definition?"); 7588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 7598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 7608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 7618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if ((datum = calloc(1, sizeof(*datum))) == NULL || 7628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android symtab_init(&datum->permissions, PERM_SYMTAB_SIZE)) { 7638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 7648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android goto cleanup; 7658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 7668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android ret = 7678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android require_symbol(SYM_CLASSES, class_id, datum, &datum->s.value, 7688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android &datum->s.value); 7698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android switch (ret) { 7708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case -3:{ 7718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 7728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(class_id); 7738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android class_datum_destroy(datum); 7748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android goto cleanup; 7758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 7768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case -2:{ 7778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("duplicate declaration of class"); 7788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(class_id); 7798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android class_datum_destroy(datum); 7808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android goto cleanup; 7818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 7828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case -1:{ 7838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("could not require class here"); 7848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(class_id); 7858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android class_datum_destroy(datum); 7868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android goto cleanup; 7878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 7888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case 0:{ 7898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* a new class was added; reindex everything */ 7908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (policydb_index_classes(policydbp)) { 7918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 7928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android goto cleanup; 7938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 7948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android break; 7958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 7968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case 1:{ 7978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android class_datum_destroy(datum); 7988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android datum = 7998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android hashtab_search(policydbp->p_classes.table, 8008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android class_id); 8018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android assert(datum); /* the class datum should have existed */ 8028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(class_id); 8038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android break; 8048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 8058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android default:{ 8068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android assert(0); /* should never get here */ 8078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 8088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 8098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 8108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* now add each of the permissions to this class's requirements */ 8118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android while ((perm_id = queue_remove(id_queue)) != NULL) { 8128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android int allocated = 0; 8138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 8148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* Is the permission already in the table? */ 8158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android perm = hashtab_search(datum->permissions.table, perm_id); 8168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (!perm && datum->comdatum) 8178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android perm = 8188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android hashtab_search(datum->comdatum->permissions.table, 8198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android perm_id); 8208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (perm) { 8218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* Yes, drop the name. */ 8228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(perm_id); 8238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else { 8248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* No - allocate and insert an entry for it. */ 8258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (policydbp->policy_type == POLICY_BASE) { 8268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror2 8278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android ("Base policy - require of permission %s without prior declaration.", 8288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android perm_id); 8298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(perm_id); 8308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android goto cleanup; 8318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 8328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android allocated = 1; 8338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if ((perm = malloc(sizeof(*perm))) == NULL) { 8348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 8358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(perm_id); 8368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android goto cleanup; 8378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 8388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android memset(perm, 0, sizeof(*perm)); 8398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android ret = 8408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android hashtab_insert(datum->permissions.table, perm_id, 8418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android perm); 8428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (ret) { 8438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 8448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(perm_id); 8458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(perm); 8468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android goto cleanup; 8478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 8488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android perm->s.value = datum->permissions.nprim + 1; 8498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 8508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 8518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (add_perm_to_class(perm->s.value, datum->s.value) == -1) { 8528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 8538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android goto cleanup; 8548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 8558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 8568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* Update number of primitives if we allocated one. */ 8578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (allocated) 8588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android datum->permissions.nprim++; 8598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 8608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; 8618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android cleanup: 8628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 8638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 8648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 8658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic int require_role_or_attribute(int pass, unsigned char isattr) 8668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 8678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android char *id = queue_remove(id_queue); 8688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android role_datum_t *role = NULL; 8698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android int retval; 8708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (pass == 2) { 8718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(id); 8728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; 8738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 8748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (id == NULL) { 8758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("no role name"); 8768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 8778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 8788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if ((role = malloc(sizeof(*role))) == NULL) { 8798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(id); 8808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 8818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 8828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 8838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android role_datum_init(role); 8848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android role->flavor = isattr ? ROLE_ATTRIB : ROLE_ROLE; 8858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android retval = 8868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android require_symbol(SYM_ROLES, id, (hashtab_datum_t *) role, 8878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android &role->s.value, &role->s.value); 8888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (retval != 0) { 8898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(id); 8908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android role_datum_destroy(role); 8918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(role); 8928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 8938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android switch (retval) { 8948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case -3:{ 8958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 8968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 8978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 8988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case -2:{ 8998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("duplicate declaration of role"); 9008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 9018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 9028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case -1:{ 9038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("could not require role here"); 9048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 9058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 9068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case 0:{ 9078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* all roles dominate themselves */ 9088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (ebitmap_set_bit 9098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android (&role->dominates, role->s.value - 1, 1)) { 9108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory"); 9118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 9128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 9138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; 9148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 9158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case 1:{ 9168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; /* role already required */ 9178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 9188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android default:{ 9198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android assert(0); /* should never get here */ 9208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 9218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 9228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 9238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 9248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint require_role(int pass) 9258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 9268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return require_role_or_attribute(pass, 0); 9278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 9288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 9298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint require_attribute_role(int pass) 9308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 9318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return require_role_or_attribute(pass, 1); 9328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 9338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 9348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic int require_type_or_attribute(int pass, unsigned char isattr) 9358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 9368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android char *id = queue_remove(id_queue); 9378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android type_datum_t *type = NULL; 9388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android int retval; 9398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (pass == 2) { 9408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(id); 9418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; 9428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 9438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (id == NULL) { 9448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("no type name"); 9458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 9468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 9478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if ((type = malloc(sizeof(*type))) == NULL) { 9488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(id); 9498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 9508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 9518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 9528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android type_datum_init(type); 9538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android type->primary = 1; 9548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android type->flavor = isattr ? TYPE_ATTRIB : TYPE_TYPE; 9558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android retval = 9568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android require_symbol(SYM_TYPES, id, (hashtab_datum_t *) type, 9578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android &type->s.value, &type->s.value); 9588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (retval != 0) { 9598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(id); 9608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(type); 9618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 9628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android switch (retval) { 9638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case -3:{ 9648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 9658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 9668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 9678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case -2:{ 9688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("duplicate declaration of type/attribute"); 9698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 9708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 9718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case -1:{ 9728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("could not require type/attribute here"); 9738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 9748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 9758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case 0:{ 9768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; 9778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 9788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case 1:{ 9798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; /* type already required */ 9808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 9818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android default:{ 9828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android assert(0); /* should never get here */ 9838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 9848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 9858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 9868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 9878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint require_type(int pass) 9888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 9898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return require_type_or_attribute(pass, 0); 9908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 9918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 9928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint require_attribute(int pass) 9938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 9948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return require_type_or_attribute(pass, 1); 9958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 9968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 9978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint require_user(int pass) 9988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 9998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android char *id = queue_remove(id_queue); 10008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android user_datum_t *user = NULL; 10018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android int retval; 10028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (pass == 1) { 10038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(id); 10048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; 10058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 10068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (id == NULL) { 10078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("no user name"); 10088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 10098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 10108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if ((user = malloc(sizeof(*user))) == NULL) { 10118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(id); 10128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 10138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 10148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 10158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android user_datum_init(user); 10168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android retval = 10178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android require_symbol(SYM_USERS, id, (hashtab_datum_t *) user, 10188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android &user->s.value, &user->s.value); 10198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (retval != 0) { 10208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(id); 10218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android user_datum_destroy(user); 10228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 10238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android switch (retval) { 10248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case -3:{ 10258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 10268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 10278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 10288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case -2:{ 10298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("duplicate declaration of user"); 10308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 10318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 10328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case -1:{ 10338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("could not require user here"); 10348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 10358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 10368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case 0:{ 10378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; 10388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 10398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case 1:{ 10408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; /* user already required */ 10418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 10428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android default:{ 10438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android assert(0); /* should never get here */ 10448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 10458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 10468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 10478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 1048cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalleystatic int require_bool_tunable(int pass, int is_tunable) 10498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 10508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android char *id = queue_remove(id_queue); 10518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android cond_bool_datum_t *booldatum = NULL; 10528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android int retval; 10538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (pass == 2) { 10548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(id); 10558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; 10568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 10578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (id == NULL) { 10588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("no boolean name"); 10598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 10608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 10618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if ((booldatum = calloc(1, sizeof(*booldatum))) == NULL) { 10628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android cond_destroy_bool(id, booldatum, NULL); 10638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 10648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 10658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 1066cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley if (is_tunable) 1067cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley booldatum->flags |= COND_BOOL_FLAGS_TUNABLE; 10688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android retval = 10698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android require_symbol(SYM_BOOLS, id, (hashtab_datum_t *) booldatum, 10708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android &booldatum->s.value, &booldatum->s.value); 10718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (retval != 0) { 10728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android cond_destroy_bool(id, booldatum, NULL); 10738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 10748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android switch (retval) { 10758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case -3:{ 10768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 10778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 10788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 10798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case -2:{ 10808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("duplicate declaration of boolean"); 10818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 10828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 10838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case -1:{ 10848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("could not require boolean here"); 10858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 10868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 10878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case 0:{ 10888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; 10898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 10908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case 1:{ 10918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; /* boolean already required */ 10928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 10938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android default:{ 10948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android assert(0); /* should never get here */ 10958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 10968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 10978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 10988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 1099cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalleyint require_bool(int pass) 1100cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley{ 1101cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley return require_bool_tunable(pass, 0); 1102cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley} 1103cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley 1104cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalleyint require_tunable(int pass) 1105cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley{ 1106cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley return require_bool_tunable(pass, 1); 1107cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley} 1108cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley 11098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint require_sens(int pass) 11108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 11118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android char *id = queue_remove(id_queue); 11128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android level_datum_t *level = NULL; 11138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android int retval; 11148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (pass == 2) { 11158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(id); 11168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; 11178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 11188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (!id) { 11198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("no sensitivity name"); 11208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 11218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 11228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android level = malloc(sizeof(level_datum_t)); 11238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (!level) { 11248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(id); 11258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 11268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 11278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 11288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android level_datum_init(level); 11298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android level->level = malloc(sizeof(mls_level_t)); 11308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (!level->level) { 11318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(id); 11328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android level_datum_destroy(level); 11338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(level); 11348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 11358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 11368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 11378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android mls_level_init(level->level); 11388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android retval = require_symbol(SYM_LEVELS, id, (hashtab_datum_t *) level, 11398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android &level->level->sens, &level->level->sens); 11408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (retval != 0) { 11418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(id); 11428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android mls_level_destroy(level->level); 11438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(level->level); 11448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android level_datum_destroy(level); 11458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(level); 11468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 11478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android switch (retval) { 11488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case -3:{ 11498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 11508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 11518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 11528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case -2:{ 11538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("duplicate declaration of sensitivity"); 11548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 11558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 11568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case -1:{ 11578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("could not require sensitivity here"); 11588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 11598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 11608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case 0:{ 11618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; 11628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 11638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case 1:{ 11648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; /* sensitivity already required */ 11658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 11668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android default:{ 11678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android assert(0); /* should never get here */ 11688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 11698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 11708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 11718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 11728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint require_cat(int pass) 11738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 11748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android char *id = queue_remove(id_queue); 11758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android cat_datum_t *cat = NULL; 11768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android int retval; 11778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (pass == 2) { 11788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(id); 11798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; 11808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 11818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (!id) { 11828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("no category name"); 11838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 11848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 11858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android cat = malloc(sizeof(cat_datum_t)); 11868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (!cat) { 11878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(id); 11888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 11898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 11908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 11918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android cat_datum_init(cat); 11928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 11938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android retval = require_symbol(SYM_CATS, id, (hashtab_datum_t *) cat, 11948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android &cat->s.value, &cat->s.value); 11958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (retval != 0) { 11968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(id); 11978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android cat_datum_destroy(cat); 11988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(cat); 11998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 12008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android switch (retval) { 12018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case -3:{ 12028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 12038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 12048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 12058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case -2:{ 12068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("duplicate declaration of category"); 12078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 12088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 12098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case -1:{ 12108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("could not require category here"); 12118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 12128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 12138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case 0:{ 12148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; 12158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 12168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case 1:{ 12178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; /* category already required */ 12188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 12198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android default:{ 12208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android assert(0); /* should never get here */ 12218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 12228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 12238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 12248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 12258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic int is_scope_in_stack(scope_datum_t * scope, scope_stack_t * stack) 12268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 12278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android int i; 12288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (stack == NULL) { 12298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; /* no matching scope found */ 12308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 12318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (stack->type == 1) { 12328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android avrule_decl_t *decl = stack->decl; 12338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android for (i = 0; i < scope->decl_ids_len; i++) { 12348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (scope->decl_ids[i] == decl->decl_id) { 12358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 1; 12368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 12378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 12388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else { 12398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* note that conditionals can't declare or require 12408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * symbols, so skip this level */ 12418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 12428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 12438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* not within scope of this stack, so try its parent */ 12448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return is_scope_in_stack(scope, stack->parent); 12458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 12468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 12478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint is_id_in_scope(uint32_t symbol_type, hashtab_key_t id) 12488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 12498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android scope_datum_t *scope = 12508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android (scope_datum_t *) hashtab_search(policydbp->scope[symbol_type]. 12518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android table, id); 12528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (scope == NULL) { 12538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 1; /* id is not known, so return success */ 12548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 12558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return is_scope_in_stack(scope, stack_top); 12568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 12578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 12588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic int is_perm_in_scope_index(uint32_t perm_value, uint32_t class_value, 12598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android scope_index_t * scope) 12608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 12618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (class_value > scope->class_perms_len) { 12628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 1; 12638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 12648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (ebitmap_get_bit(scope->class_perms_map + class_value - 1, 12658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android perm_value - 1)) { 12668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 1; 12678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 12688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; 12698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 12708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 12718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic int is_perm_in_stack(uint32_t perm_value, uint32_t class_value, 12728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android scope_stack_t * stack) 12738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 12748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (stack == NULL) { 12758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; /* no matching scope found */ 12768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 12778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (stack->type == 1) { 12788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android avrule_decl_t *decl = stack->decl; 12798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (is_perm_in_scope_index 12808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android (perm_value, class_value, &decl->required) 12818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android || is_perm_in_scope_index(perm_value, class_value, 12828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android &decl->declared)) { 12838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 1; 12848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 12858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else { 12868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* note that conditionals can't declare or require 12878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * symbols, so skip this level */ 12888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 12898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 12908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* not within scope of this stack, so try its parent */ 12918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return is_perm_in_stack(perm_value, class_value, stack->parent); 12928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 12938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 12948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint is_perm_in_scope(hashtab_key_t perm_id, hashtab_key_t class_id) 12958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 12968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android class_datum_t *cladatum = 12978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android (class_datum_t *) hashtab_search(policydbp->p_classes.table, 12988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android class_id); 12998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android perm_datum_t *perdatum; 13008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (cladatum == NULL) { 13018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 1; 13028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 13038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android perdatum = (perm_datum_t *) hashtab_search(cladatum->permissions.table, 13048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android perm_id); 13058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (perdatum == NULL) { 13068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 1; 13078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 13088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return is_perm_in_stack(perdatum->s.value, cladatum->s.value, 13098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android stack_top); 13108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 13118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 13128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidcond_list_t *get_current_cond_list(cond_list_t * cond) 13138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 13148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* FIX ME: do something different here if in a nested 13158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * conditional? */ 13168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android avrule_decl_t *decl = stack_top->decl; 13178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return get_decl_cond_list(policydbp, decl, cond); 13188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 13198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 13208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android/* Append the new conditional node to the existing ones. During 13218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * expansion the list will be reversed -- i.e., the last AV rule will 13228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * be the first one listed in the policy. This matches the behavior 13238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * of the upstream compiler. */ 13248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidvoid append_cond_list(cond_list_t * cond) 13258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 13268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android cond_list_t *old_cond = get_current_cond_list(cond); 13278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android avrule_t *tmp; 13288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android assert(old_cond != NULL); /* probably out of memory */ 13298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (old_cond->avtrue_list == NULL) { 13308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android old_cond->avtrue_list = cond->avtrue_list; 13318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else { 13328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android for (tmp = old_cond->avtrue_list; tmp->next != NULL; 13338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android tmp = tmp->next) ; 13348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android tmp->next = cond->avtrue_list; 13358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 13368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (old_cond->avfalse_list == NULL) { 13378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android old_cond->avfalse_list = cond->avfalse_list; 13388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else { 13398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android for (tmp = old_cond->avfalse_list; tmp->next != NULL; 13408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android tmp = tmp->next) ; 13418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android tmp->next = cond->avfalse_list; 13428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 1343cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley 1344cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley old_cond->flags |= cond->flags; 13458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 13468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 13478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidvoid append_avrule(avrule_t * avrule) 13488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 13498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android avrule_decl_t *decl = stack_top->decl; 13508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 13518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* currently avrules follow a completely different code path 13528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * for handling avrules and compute types 13538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * (define_cond_avrule_te_avtab, define_cond_compute_type); 13548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * therefore there ought never be a conditional on top of the 13558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * scope stack */ 13568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android assert(stack_top->type == 1); 13578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 13588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (stack_top->last_avrule == NULL) { 13598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android decl->avrules = avrule; 13608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else { 13618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android stack_top->last_avrule->next = avrule; 13628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 13638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android stack_top->last_avrule = avrule; 13648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 13658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 13668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android/* this doesn't actually append, but really prepends it */ 13678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidvoid append_role_trans(role_trans_rule_t * role_tr_rules) 13688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 13698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android avrule_decl_t *decl = stack_top->decl; 13708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 13718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* role transitions are not allowed within conditionals */ 13728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android assert(stack_top->type == 1); 13738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 13748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android role_tr_rules->next = decl->role_tr_rules; 13758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android decl->role_tr_rules = role_tr_rules; 13768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 13778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 13788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android/* this doesn't actually append, but really prepends it */ 13798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidvoid append_role_allow(role_allow_rule_t * role_allow_rules) 13808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 13818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android avrule_decl_t *decl = stack_top->decl; 13828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 13838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* role allows are not allowed within conditionals */ 13848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android assert(stack_top->type == 1); 13858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 13868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android role_allow_rules->next = decl->role_allow_rules; 13878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android decl->role_allow_rules = role_allow_rules; 13888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 13898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 13908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android/* this doesn't actually append, but really prepends it */ 13918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidvoid append_filename_trans(filename_trans_rule_t * filename_trans_rules) 13928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 13938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android avrule_decl_t *decl = stack_top->decl; 13948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 13958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* filename transitions are not allowed within conditionals */ 13968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android assert(stack_top->type == 1); 13978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 13988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android filename_trans_rules->next = decl->filename_trans_rules; 13998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android decl->filename_trans_rules = filename_trans_rules; 14008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 14018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 14028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android/* this doesn't actually append, but really prepends it */ 14038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidvoid append_range_trans(range_trans_rule_t * range_tr_rules) 14048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 14058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android avrule_decl_t *decl = stack_top->decl; 14068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 14078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* range transitions are not allowed within conditionals */ 14088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android assert(stack_top->type == 1); 14098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 14108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android range_tr_rules->next = decl->range_tr_rules; 14118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android decl->range_tr_rules = range_tr_rules; 14128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 14138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 14148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint begin_optional(int pass) 14158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 14168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android avrule_block_t *block = NULL; 14178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android avrule_decl_t *decl; 14188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (pass == 1) { 14198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* allocate a new avrule block for this optional block */ 14208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if ((block = avrule_block_create()) == NULL || 14218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android (decl = avrule_decl_create(next_decl_id)) == NULL) { 14228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android goto cleanup; 14238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 14248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android block->flags |= AVRULE_OPTIONAL; 14258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android block->branch_list = decl; 14268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android last_block->next = block; 14278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else { 14288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* select the next block from the chain built during pass 1 */ 14298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android block = last_block->next; 14308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android assert(block != NULL && 14318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android block->branch_list != NULL && 14328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android block->branch_list->decl_id == next_decl_id); 14338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android decl = block->branch_list; 14348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 14358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (push_stack(1, block, decl) == -1) { 14368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android goto cleanup; 14378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 14388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android stack_top->last_avrule = NULL; 14398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android last_block = block; 14408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android next_decl_id++; 14418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; 14428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android cleanup: 14438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 14448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android avrule_block_destroy(block); 14458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 14468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 14478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 14488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint end_optional(int pass) 14498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 14508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* once nested conditionals are allowed, do the stack unfolding here */ 14518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android pop_stack(); 14528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; 14538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 14548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 14558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint begin_optional_else(int pass) 14568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 14578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android avrule_decl_t *decl; 14588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android assert(stack_top->type == 1 && stack_top->in_else == 0); 14598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (pass == 1) { 14608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* allocate a new declaration and add it to the 14618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * current chain */ 14628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if ((decl = avrule_decl_create(next_decl_id)) == NULL) { 14638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 14648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 14658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 14668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android stack_top->decl->next = decl; 14678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else { 14688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* pick the (hopefully last) declaration of this 14698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android avrule block, built from pass 1 */ 14708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android decl = stack_top->decl->next; 14718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android assert(decl != NULL && 14728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android decl->next == NULL && decl->decl_id == next_decl_id); 14738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 14748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android stack_top->in_else = 1; 14758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android stack_top->decl = decl; 14768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android stack_top->last_avrule = NULL; 14778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android stack_top->require_given = 0; 14788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android next_decl_id++; 14798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; 14808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 14818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 14828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic int copy_requirements(avrule_decl_t * dest, scope_stack_t * stack) 14838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 14848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android int i; 14858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (stack == NULL) { 14868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; 14878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 14888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (stack->type == 1) { 14898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android scope_index_t *src_scope = &stack->decl->required; 14908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android scope_index_t *dest_scope = &dest->required; 14918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android for (i = 0; i < SYM_NUM; i++) { 14928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android ebitmap_t *src_bitmap = &src_scope->scope[i]; 14938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android ebitmap_t *dest_bitmap = &dest_scope->scope[i]; 14948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (ebitmap_union(dest_bitmap, src_bitmap)) { 14958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 14968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 14978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 14988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 14998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* now copy class permissions */ 15008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (src_scope->class_perms_len > dest_scope->class_perms_len) { 15018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android ebitmap_t *new_map = 15028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android realloc(dest_scope->class_perms_map, 15038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android src_scope->class_perms_len * 15048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android sizeof(*new_map)); 15058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (new_map == NULL) { 15068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 15078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 15088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 15098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android dest_scope->class_perms_map = new_map; 15108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android for (i = dest_scope->class_perms_len; 15118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android i < src_scope->class_perms_len; i++) { 15128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android ebitmap_init(dest_scope->class_perms_map + i); 15138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 15148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android dest_scope->class_perms_len = 15158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android src_scope->class_perms_len; 15168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 15178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android for (i = 0; i < src_scope->class_perms_len; i++) { 15188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android ebitmap_t *src_bitmap = &src_scope->class_perms_map[i]; 15198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android ebitmap_t *dest_bitmap = 15208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android &dest_scope->class_perms_map[i]; 15218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (ebitmap_union(dest_bitmap, src_bitmap)) { 15228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("Out of memory!"); 15238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 15248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 15258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 15268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 15278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return copy_requirements(dest, stack->parent); 15288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 15298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 15308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android/* During pass 1, check that at least one thing was required within 15318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * this block, for those places where a REQUIRED is necessary. During 15328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * pass 2, have this block inherit its parents' requirements. Return 15338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * 0 on success, -1 on failure. */ 15348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint end_avrule_block(int pass) 15358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 15368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android avrule_decl_t *decl = stack_top->decl; 15378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android assert(stack_top->type == 1); 15388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (pass == 2) { 15398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* this avrule_decl inherits all of its parents' 15408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * requirements */ 15418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (copy_requirements(decl, stack_top->parent) == -1) { 15428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 15438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 15448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; 15458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 15468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (!stack_top->in_else && !stack_top->require_given) { 15478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (policydbp->policy_type == POLICY_BASE 15488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android && stack_top->parent != NULL) { 15498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* if this is base no require should be in the global block */ 15508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; 15518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } else { 15528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* non-ELSE branches must have at least one thing required */ 15538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android yyerror("This block has no require section."); 15548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 15558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 15568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 15578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; 15588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 15598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 15608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android/* Push a new scope on to the stack and update the 'last' pointer. 15618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * Return 0 on success, -1 if out * of memory. */ 15628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic int push_stack(int stack_type, ...) 15638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 15648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android scope_stack_t *s = calloc(1, sizeof(*s)); 15658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android va_list ap; 15668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (s == NULL) { 15678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return -1; 15688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 15698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android va_start(ap, stack_type); 15708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android switch (s->type = stack_type) { 15718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case 1:{ 15728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android s->u.avrule = va_arg(ap, avrule_block_t *); 15738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android s->decl = va_arg(ap, avrule_decl_t *); 15748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android break; 15758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 15768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android case 2:{ 15778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android s->u.cond_list = va_arg(ap, cond_list_t *); 15788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android break; 15798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 15808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android default: 15818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android /* invalid stack type given */ 15828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android assert(0); 15838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 15848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android va_end(ap); 15858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android s->parent = stack_top; 15868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android s->child = NULL; 15878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android stack_top = s; 15888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android return 0; 15898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 15908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android 15918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android/* Pop off the most recently added from the stack. Update the 'last' 15928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * pointer. */ 15938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic void pop_stack(void) 15948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{ 15958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android scope_stack_t *parent; 15968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android assert(stack_top != NULL); 15978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android parent = stack_top->parent; 15988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android if (parent != NULL) { 15998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android parent->child = NULL; 16008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android } 16018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android free(stack_top); 16028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android stack_top = parent; 16038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android} 1604