113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Author : Joshua Brindle <jbrindle@tresys.com> 213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Karl MacMillan <kmacmillan@tresys.com> 313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Jason Tang <jtang@tresys.com> 413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Added support for binary policy modules 513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Copyright (C) 2004 - 2005 Tresys Technology, LLC 713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * This program is free software; you can redistribute it and/or modify 813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * it under the terms of the GNU General Public License as published by 913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * the Free Software Foundation, version 2. 1013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 1113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 1213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <assert.h> 1313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <stdarg.h> 1413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <stdlib.h> 1513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <string.h> 1613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 1713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/policydb/policydb.h> 1813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/policydb/avrule_block.h> 1913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/policydb/conditional.h> 2013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 2113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "queue.h" 2213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "module_compiler.h" 2313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 2413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleunion stack_item_u { 2513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_block_t *avrule; 2613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond_list_t *cond_list; 2713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}; 2813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 2913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindletypedef struct scope_stack { 3013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle union stack_item_u u; 3113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int type; /* for above union: 1 = avrule block, 2 = conditional */ 3213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_t *decl; /* if in an avrule block, which 3313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * declaration is current */ 3413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_t *last_avrule; 3513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int in_else; /* if in an avrule block, within ELSE branch */ 3613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int require_given; /* 1 if this block had at least one require */ 3713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle struct scope_stack *parent, *child; 3813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} scope_stack_t; 3913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 4013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleextern policydb_t *policydbp; 4113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleextern queue_t id_queue; 42832e7017f881f0a66e24170b7a2ff1cd9b113239Nicolas Ioossextern int yyerror(const char *msg); 438db96d0cb4feb1323488a5e04a3d4623ba22ffceNicolas Iooss__attribute__ ((format(printf, 1, 2))) 44832e7017f881f0a66e24170b7a2ff1cd9b113239Nicolas Ioossextern void yyerror2(const char *fmt, ...); 4513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 4613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int push_stack(int stack_type, ...); 4713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic void pop_stack(void); 4813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 4913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* keep track of the last item added to the stack */ 5013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic scope_stack_t *stack_top = NULL; 5113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic avrule_block_t *last_block; 5213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic uint32_t next_decl_id = 1; 5313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 5413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint define_policy(int pass, int module_header_given) 5513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 5613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id; 5713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 5813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (module_header_given) { 5913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (policydbp->policy_type != POLICY_MOD) { 6013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror 6113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ("Module specification found while not building a policy module.\n"); 6213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 6313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 6413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 6513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (pass == 2) { 6613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while ((id = queue_remove(id_queue)) != NULL) 6713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(id); 6813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 6913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle id = (char *)queue_remove(id_queue); 7013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!id) { 7113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("no module name"); 7213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 7313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 7413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policydbp->name = id; 7513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((policydbp->version = 7613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle queue_remove(id_queue)) == NULL) { 7713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror 7813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ("Expected a module version but none was found."); 7913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 8013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 8113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 8213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 8313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (policydbp->policy_type == POLICY_MOD) { 8413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror 8513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ("Building a policy module, but no module specification found.\n"); 8613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 8713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 8813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 8913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* the first declaration within the global avrule 9013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle block will always have an id of 1 */ 9113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle next_decl_id = 2; 9213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 9313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* reset the scoping stack */ 9413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (stack_top != NULL) { 9513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle pop_stack(); 9613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 9713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (push_stack(1, policydbp->global, policydbp->global->branch_list) == 9813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle -1) { 9913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 10013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 10113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle last_block = policydbp->global; 10213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 10313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 10413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 10513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Given the current parse stack, returns 1 if a declaration would be 10613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * allowed here or 0 if not. For example, declarations are not 10713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * allowed in conditionals, so if there are any conditionals in the 10813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * current scope stack then this would return a 0. 10913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 11013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int is_declaration_allowed(void) 11113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 11213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (stack_top->type != 1 || stack_top->in_else) { 11313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 11413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 11513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 1; 11613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 11713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 11813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Attempt to declare a symbol within the current declaration. If 11913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * currently within a non-conditional and in a non-else branch then 12013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * insert the symbol, return 0 on success if symbol was undeclared. 12113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * For roles and users, it is legal to have multiple declarations; as 12213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * such return 1 to indicate that caller must free() the datum because 12313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * it was not added. If symbols may not be declared here return -1. 12413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * For duplicate declarations return -2. For all else, including out 12513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * of memory, return -3. Note that dest_value and datum_value might 12613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * not be restricted pointers. */ 12713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint declare_symbol(uint32_t symbol_type, 12813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle hashtab_key_t key, hashtab_datum_t datum, 12913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t * dest_value, uint32_t * datum_value) 13013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 13113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_t *decl = stack_top->decl; 13213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int retval; 13313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 13413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* first check that symbols may be declared here */ 13513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!is_declaration_allowed()) { 13613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 13713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 13813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle retval = symtab_insert(policydbp, symbol_type, key, datum, 13913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle SCOPE_DECL, decl->decl_id, dest_value); 140f7917ea9cf6af752de98a1e742152d813028c669Caleb Case if (retval == 1 && dest_value) { 14113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle symtab_datum_t *s = 14213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (symtab_datum_t *) hashtab_search(policydbp-> 14313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle symtab[symbol_type].table, 14413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle key); 14513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(s != NULL); 14613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 14713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (symbol_type == SYM_LEVELS) { 14813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *dest_value = ((level_datum_t *)s)->level->sens; 14913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 15013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *dest_value = s->value; 15113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 15213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else if (retval == -2) { 15313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -2; 15413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else if (retval < 0) { 15513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -3; 15613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { /* fall through possible if retval is 0 */ 15713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 15813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (datum_value != NULL) { 15913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_set_bit(decl->declared.scope + symbol_type, 16013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *datum_value - 1, 1)) { 16113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -3; 16213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 16313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 16413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return retval; 16513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 16613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 16745728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindlestatic int role_implicit_bounds(hashtab_t roles_tab, 16845728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle char *role_id, role_datum_t *role) 16945728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle{ 17045728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle role_datum_t *bounds; 17145728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle char *bounds_id, *delim; 17245728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle 17345728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle delim = strrchr(role_id, '.'); 17445728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle if (!delim) 17545728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle return 0; /* no implicit boundary */ 17645728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle 17745728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle bounds_id = strdup(role_id); 17845728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle if (!bounds_id) { 17945728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle yyerror("out of memory"); 18045728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle return -1; 18145728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle } 18245728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle bounds_id[(size_t)(delim - role_id)] = '\0'; 18345728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle 18445728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle bounds = hashtab_search(roles_tab, bounds_id); 18545728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle if (!bounds) { 18645728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle yyerror2("role %s doesn't exist, is implicit bounds of %s", 18745728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle bounds_id, role_id); 18845728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle return -1; 18945728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle } 19045728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle 19145728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle if (!role->bounds) 19245728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle role->bounds = bounds->s.value; 19345728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle else if (role->bounds != bounds->s.value) { 19445728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle yyerror2("role %s has inconsistent bounds %s/%s", 19545728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle role_id, bounds_id, 19645728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle policydbp->p_role_val_to_name[role->bounds - 1]); 19745728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle return -1; 19845728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle } 19945728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle free(bounds_id); 20045728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle 20145728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle return 0; 20245728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle} 20345728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle 20416675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciaorole_datum_t *declare_role(unsigned char isattr) 20513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 20613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id = queue_remove(id_queue), *dest_id = NULL; 20713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_datum_t *role = NULL, *dest_role = NULL; 20813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int retval; 20913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t value; 21013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 21113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (id == NULL) { 21213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("no role name"); 21313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 21413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 21513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((role = (role_datum_t *) malloc(sizeof(*role))) == NULL) { 21613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 21713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(id); 21813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 21913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 22013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_datum_init(role); 22116675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao role->flavor = isattr ? ROLE_ATTRIB : ROLE_ROLE; 22213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle retval = 22313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle declare_symbol(SYM_ROLES, id, (hashtab_datum_t *) role, &value, 22413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &value); 22513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (retval == 0) { 22613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role->s.value = value; 22713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((dest_id = strdup(id)) == NULL) { 22813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 22913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 23013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 23113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 23213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* this role was already declared in this module, or error */ 23313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dest_id = id; 23413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_datum_destroy(role); 23513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(role); 23613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 23713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (retval == 0 || retval == 1) { 23813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* create a new role_datum_t for this decl, if necessary */ 23913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle hashtab_t roles_tab; 24013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(stack_top->type == 1); 24113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (stack_top->parent == NULL) { 24213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* in parent, so use global symbol table */ 24313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle roles_tab = policydbp->p_roles.table; 24413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 24513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle roles_tab = stack_top->decl->p_roles.table; 24613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 24713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dest_role = (role_datum_t *) hashtab_search(roles_tab, dest_id); 24813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (dest_role == NULL) { 24913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((dest_role = 25013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (role_datum_t *) malloc(sizeof(*dest_role))) == 25113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle NULL) { 25213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 25313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(dest_id); 25413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 25513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 25613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_datum_init(dest_role); 25713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dest_role->s.value = value; 25816675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao dest_role->flavor = isattr ? ROLE_ATTRIB : ROLE_ROLE; 25945728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle if (role_implicit_bounds(roles_tab, dest_id, dest_role)) { 26045728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle free(dest_id); 26145728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle role_datum_destroy(dest_role); 26245728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle free(dest_role); 26345728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle return NULL; 26445728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle } 26513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (hashtab_insert(roles_tab, dest_id, dest_role)) { 26613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 26713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(dest_id); 26813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_datum_destroy(dest_role); 26913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(dest_role); 27013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 27113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 27213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 27313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(dest_id); 27413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 27513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 27613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(dest_id); 27713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 27813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle switch (retval) { 27913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case -3:{ 28013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 28113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 28213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 28313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case -2:{ 28413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("duplicate declaration of role"); 28513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 28613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 28713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case -1:{ 28813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("could not declare role here"); 28913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 29013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 29113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case 0:{ 29213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_set_bit 29313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (&dest_role->dominates, role->s.value - 1, 1)) { 29413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("out of memory"); 29513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 29613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 29713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return dest_role; 29813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 29913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case 1:{ 30013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return dest_role; /* role already declared for this block */ 30113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 30213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle default:{ 303099223bd1f08ce0bc897f1a9f47852621bc946c9Dan Albert abort(); /* should never get here */ 30413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 30513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 30613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 30713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 30813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindletype_datum_t *declare_type(unsigned char primary, unsigned char isattr) 30913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 31013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id; 31113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type_datum_t *typdatum; 31213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int retval; 31313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t value = 0; 31413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 31513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle id = (char *)queue_remove(id_queue); 31613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!id) { 31713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("no type/attribute name?"); 31813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 31913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 32013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (strcmp(id, "self") == 0) { 32113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror 32213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ("'self' is a reserved type name and may not be declared."); 32313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(id); 32413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 32513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 32613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 32713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle typdatum = (type_datum_t *) malloc(sizeof(type_datum_t)); 32813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!typdatum) { 32913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 33013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(id); 33113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 33213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 33313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type_datum_init(typdatum); 33413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle typdatum->primary = primary; 33513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle typdatum->flavor = isattr ? TYPE_ATTRIB : TYPE_TYPE; 33613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 33713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle retval = declare_symbol(SYM_TYPES, id, typdatum, &value, &value); 33813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (retval == 0 || retval == 1) { 33913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (typdatum->primary) { 34013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle typdatum->s.value = value; 34113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 34213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 34313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* error occurred (can't have duplicate type declarations) */ 34413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(id); 34513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type_datum_destroy(typdatum); 34613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(typdatum); 34713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 34813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle switch (retval) { 34913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case -3:{ 35013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 35113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 35213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 35313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case -2:{ 35413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror2("duplicate declaration of type/attribute"); 35513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 35613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 35713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case -1:{ 35813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("could not declare type/attribute here"); 35913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 36013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 36113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case 0: 36213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case 1:{ 36313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return typdatum; 36413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 36513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle default:{ 366099223bd1f08ce0bc897f1a9f47852621bc946c9Dan Albert abort(); /* should never get here */ 36713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 36813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 36913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 37013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 37145728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindlestatic int user_implicit_bounds(hashtab_t users_tab, 37245728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle char *user_id, user_datum_t *user) 37345728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle{ 37445728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle user_datum_t *bounds; 37545728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle char *bounds_id, *delim; 37645728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle 37745728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle delim = strrchr(user_id, '.'); 37845728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle if (!delim) 37945728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle return 0; /* no implicit boundary */ 38045728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle 38145728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle bounds_id = strdup(user_id); 38245728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle if (!bounds_id) { 38345728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle yyerror("out of memory"); 38445728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle return -1; 38545728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle } 38645728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle bounds_id[(size_t)(delim - user_id)] = '\0'; 38745728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle 38845728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle bounds = hashtab_search(users_tab, bounds_id); 38945728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle if (!bounds) { 39045728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle yyerror2("user %s doesn't exist, is implicit bounds of %s", 39145728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle bounds_id, user_id); 39245728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle return -1; 39345728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle } 39445728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle 39545728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle if (!user->bounds) 39645728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle user->bounds = bounds->s.value; 39745728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle else if (user->bounds != bounds->s.value) { 39845728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle yyerror2("user %s has inconsistent bounds %s/%s", 39945728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle user_id, bounds_id, 40045728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle policydbp->p_role_val_to_name[user->bounds - 1]); 40145728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle return -1; 40245728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle } 40345728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle free(bounds_id); 40445728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle 40545728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle return 0; 40645728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle} 40745728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle 40813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleuser_datum_t *declare_user(void) 40913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 41013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id = queue_remove(id_queue), *dest_id = NULL; 41113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle user_datum_t *user = NULL, *dest_user = NULL; 41213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int retval; 41313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t value = 0; 41413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 41513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (id == NULL) { 41613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("no user name"); 41713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 41813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 41913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((user = (user_datum_t *) malloc(sizeof(*user))) == NULL) { 42013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 42113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(id); 42213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 42313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 42413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle user_datum_init(user); 42513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 42613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle retval = 42713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle declare_symbol(SYM_USERS, id, (hashtab_datum_t *) user, &value, 42813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &value); 42913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 43013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (retval == 0) { 43113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle user->s.value = value; 43213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((dest_id = strdup(id)) == NULL) { 43313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 43413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 43513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 43613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 43713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* this user was already declared in this module, or error */ 43813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dest_id = id; 43913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle user_datum_destroy(user); 44013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(user); 44113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 44213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (retval == 0 || retval == 1) { 44313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* create a new user_datum_t for this decl, if necessary */ 44413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle hashtab_t users_tab; 44513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(stack_top->type == 1); 44613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (stack_top->parent == NULL) { 44713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* in parent, so use global symbol table */ 44813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle users_tab = policydbp->p_users.table; 44913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 45013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle users_tab = stack_top->decl->p_users.table; 45113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 45213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dest_user = (user_datum_t *) hashtab_search(users_tab, dest_id); 45313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (dest_user == NULL) { 45413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((dest_user = 45513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (user_datum_t *) malloc(sizeof(*dest_user))) == 45613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle NULL) { 45713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 45813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(dest_id); 45913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 46013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 46113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle user_datum_init(dest_user); 46213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dest_user->s.value = value; 46345728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle if (user_implicit_bounds(users_tab, dest_id, dest_user)) { 46445728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle free(dest_id); 46545728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle user_datum_destroy(dest_user); 46645728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle free(dest_user); 46745728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle return NULL; 46845728407d60a5297deac7aa65fd92adf2412d5f7Joshua Brindle } 46913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (hashtab_insert(users_tab, dest_id, dest_user)) { 47013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 47113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(dest_id); 47213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle user_datum_destroy(dest_user); 47313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(dest_user); 47413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 47513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 47613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 47713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(dest_id); 47813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 47913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 48013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(dest_id); 48113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 48213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle switch (retval) { 48313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case -3:{ 48413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 48513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 48613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 48713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case -2:{ 48813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("duplicate declaration of user"); 48913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 49013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 49113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case -1:{ 49213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("could not declare user here"); 49313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 49413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 49513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case 0:{ 49613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return dest_user; 49713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 49813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case 1:{ 49913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return dest_user; /* user already declared for this block */ 50013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 50113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle default:{ 502099223bd1f08ce0bc897f1a9f47852621bc946c9Dan Albert abort(); /* should never get here */ 50313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 50413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 50513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 50613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 50713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Return a type_datum_t for the local avrule_decl with the given ID. 50813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * If it does not exist, create one with the same value as 'value'. 50913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * This function assumes that the ID is within scope. c.f., 51013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * is_id_in_scope(). 51113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 51213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * NOTE: this function usurps ownership of id afterwards. The caller 51313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * shall not reference it nor free() it afterwards. 51413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 51513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindletype_datum_t *get_local_type(char *id, uint32_t value, unsigned char isattr) 51613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 51713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type_datum_t *dest_typdatum; 51813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle hashtab_t types_tab; 51913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(stack_top->type == 1); 52013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (stack_top->parent == NULL) { 52113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* in global, so use global symbol table */ 52213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle types_tab = policydbp->p_types.table; 52313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 52413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle types_tab = stack_top->decl->p_types.table; 52513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 52613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dest_typdatum = hashtab_search(types_tab, id); 52713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!dest_typdatum) { 52813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dest_typdatum = (type_datum_t *) malloc(sizeof(type_datum_t)); 52913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (dest_typdatum == NULL) { 53013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(id); 53113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 53213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 53313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type_datum_init(dest_typdatum); 53413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dest_typdatum->s.value = value; 53513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dest_typdatum->flavor = isattr ? TYPE_ATTRIB : TYPE_TYPE; 53613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dest_typdatum->primary = 1; 53713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (hashtab_insert(types_tab, id, dest_typdatum)) { 53813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(id); 53913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type_datum_destroy(dest_typdatum); 54013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(dest_typdatum); 54113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 54213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 54313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 54413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 54513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(id); 54613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (dest_typdatum->flavor != isattr ? TYPE_ATTRIB : TYPE_TYPE) { 54713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 54813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 54913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 55013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return dest_typdatum; 55113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 55213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 55316675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao/* Return a role_datum_t for the local avrule_decl with the given ID. 55416675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao * If it does not exist, create one with the same value as 'value'. 55516675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao * This function assumes that the ID is within scope. c.f., 55616675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao * is_id_in_scope(). 55716675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao * 55816675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao * NOTE: this function usurps ownership of id afterwards. The caller 55916675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao * shall not reference it nor free() it afterwards. 56016675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao */ 56116675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciaorole_datum_t *get_local_role(char *id, uint32_t value, unsigned char isattr) 56216675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao{ 56316675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao role_datum_t *dest_roledatum; 56416675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao hashtab_t roles_tab; 56516675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao 56616675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao assert(stack_top->type == 1); 56716675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao 56816675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao if (stack_top->parent == NULL) { 56916675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao /* in global, so use global symbol table */ 57016675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao roles_tab = policydbp->p_roles.table; 57116675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao } else { 57216675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao roles_tab = stack_top->decl->p_roles.table; 57316675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao } 57416675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao 57516675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao dest_roledatum = hashtab_search(roles_tab, id); 57616675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao if (!dest_roledatum) { 57716675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao dest_roledatum = (role_datum_t *)malloc(sizeof(role_datum_t)); 57816675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao if (dest_roledatum == NULL) { 57916675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao free(id); 58016675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao return NULL; 58116675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao } 58216675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao 58316675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao role_datum_init(dest_roledatum); 58416675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao dest_roledatum->s.value = value; 58516675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao dest_roledatum->flavor = isattr ? ROLE_ATTRIB : ROLE_ROLE; 58616675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao 58716675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao if (hashtab_insert(roles_tab, id, dest_roledatum)) { 58816675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao free(id); 58916675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao role_datum_destroy(dest_roledatum); 59016675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao free(dest_roledatum); 59116675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao return NULL; 59216675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao } 59316675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao } else { 59416675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao free(id); 59516675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao if (dest_roledatum->flavor != isattr ? ROLE_ATTRIB : ROLE_ROLE) 59616675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao return NULL; 59716675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao } 59816675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao 59916675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao return dest_roledatum; 60016675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao} 60116675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao 60213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Given the current parse stack, returns 1 if a requirement would be 60313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * allowed here or 0 if not. For example, the ELSE branch may never 60413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * have its own requirements. 60513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 60613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int is_require_allowed(void) 60713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 60813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (stack_top->type == 1 && !stack_top->in_else) { 60913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 1; 61013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 61113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 61213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 61313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 61413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Attempt to require a symbol within the current scope. If currently 61513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * within an optional (and not its else branch), add the symbol to the 61613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * required list. Return 0 on success, 1 if caller needs to free() 61713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * datum. If symbols may not be declared here return -1. For duplicate 61813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * declarations return -2. For all else, including out of memory, 61913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * return -3.. Note that dest_value and datum_value might not be 62013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * restricted pointers. 62113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 62213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint require_symbol(uint32_t symbol_type, 62313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle hashtab_key_t key, hashtab_datum_t datum, 62413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t * dest_value, uint32_t * datum_value) 62513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 62613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_t *decl = stack_top->decl; 62713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int retval; 62813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 62913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* first check that symbols may be required here */ 63013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!is_require_allowed()) { 63113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 63213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 63313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle retval = symtab_insert(policydbp, symbol_type, key, datum, 63413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle SCOPE_REQ, decl->decl_id, dest_value); 63513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (retval == 1) { 63613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle symtab_datum_t *s = 63713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (symtab_datum_t *) hashtab_search(policydbp-> 63813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle symtab[symbol_type].table, 63913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle key); 64013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(s != NULL); 64113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 64213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (symbol_type == SYM_LEVELS) { 64313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *dest_value = ((level_datum_t *)s)->level->sens; 64413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 64513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *dest_value = s->value; 64613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 64713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else if (retval == -2) { 64813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* ignore require statements if that symbol was 64913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * previously declared and is in current scope */ 65013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int prev_declaration_ok = 0; 65113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (is_id_in_scope(symbol_type, key)) { 65213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (symbol_type == SYM_TYPES) { 65313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* check that previous symbol has same 65413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * type/attribute-ness */ 65513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned char new_isattr = 65613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ((type_datum_t *) datum)->flavor; 65713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type_datum_t *old_datum = 65813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (type_datum_t *) hashtab_search(policydbp-> 65913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle symtab 66013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle [SYM_TYPES]. 66113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle table, key); 66213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(old_datum != NULL); 66313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned char old_isattr = old_datum->flavor; 66413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle prev_declaration_ok = 66513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (old_isattr == new_isattr ? 1 : 0); 66613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 66713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle prev_declaration_ok = 1; 66813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 66913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 67013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (prev_declaration_ok) { 67113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* ignore this require statement because it 67213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * was already declared within my scope */ 67313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle stack_top->require_given = 1; 67413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 1; 67513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 67613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* previous declaration was not in scope or 67713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * had a mismatched type/attribute, so 67813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * generate an error */ 67913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -2; 68013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 68113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else if (retval < 0) { 68213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -3; 68313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { /* fall through possible if retval is 0 or 1 */ 68413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 68513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (datum_value != NULL) { 68613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_set_bit(decl->required.scope + symbol_type, 68713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *datum_value - 1, 1)) { 68813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -3; 68913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 69013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 69113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle stack_top->require_given = 1; 69213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return retval; 69313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 69413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 69513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint add_perm_to_class(uint32_t perm_value, uint32_t class_value) 69613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 69713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_t *decl = stack_top->decl; 69813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle scope_index_t *scope; 69913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 70013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(perm_value >= 1); 70113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(class_value >= 1); 70213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle scope = &decl->required; 70313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (class_value > scope->class_perms_len) { 704581d3eb1281f7c970376649f5027df012269935aNicolas Iooss uint32_t i; 70513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_t *new_map = realloc(scope->class_perms_map, 70613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle class_value * sizeof(*new_map)); 70713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (new_map == NULL) { 70813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 70913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 71013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle scope->class_perms_map = new_map; 71113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = scope->class_perms_len; i < class_value; i++) { 71213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_init(scope->class_perms_map + i); 71313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 71413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle scope->class_perms_len = class_value; 71513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 71613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_set_bit(scope->class_perms_map + class_value - 1, 71713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle perm_value - 1, 1)) { 71813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 71913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 72013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 72113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 72213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 72313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int perm_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p 72413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle __attribute__ ((unused))) 72513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 72613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (key) 72713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(key); 72813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(datum); 72913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 73013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 73113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 73213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic void class_datum_destroy(class_datum_t * cladatum) 73313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 73413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (cladatum != NULL) { 73513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle hashtab_map(cladatum->permissions.table, perm_destroy, NULL); 73613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle hashtab_destroy(cladatum->permissions.table); 73713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(cladatum); 73813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 73913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 74013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 74113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint require_class(int pass) 74213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 74313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *class_id = queue_remove(id_queue); 74413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *perm_id = NULL; 74513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle class_datum_t *datum = NULL; 74613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle perm_datum_t *perm = NULL; 74713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int ret; 74813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 74913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (pass == 2) { 75013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(class_id); 75113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while ((perm_id = queue_remove(id_queue)) != NULL) 75213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(perm_id); 75313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 75413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 75513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 75613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* first add the class if it is not already there */ 75713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (class_id == NULL) { 75813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("no class name for class definition?"); 75913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 76013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 76113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 76213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((datum = calloc(1, sizeof(*datum))) == NULL || 76313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle symtab_init(&datum->permissions, PERM_SYMTAB_SIZE)) { 76413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 76513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 76613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 76713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = 76813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle require_symbol(SYM_CLASSES, class_id, datum, &datum->s.value, 76913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &datum->s.value); 77013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle switch (ret) { 77113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case -3:{ 77213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 77313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(class_id); 77413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle class_datum_destroy(datum); 77513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 77613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 77713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case -2:{ 77813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("duplicate declaration of class"); 77913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(class_id); 78013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle class_datum_destroy(datum); 78113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 78213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 78313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case -1:{ 78413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("could not require class here"); 78513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(class_id); 78613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle class_datum_destroy(datum); 78713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 78813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 78913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case 0:{ 79013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* a new class was added; reindex everything */ 79113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (policydb_index_classes(policydbp)) { 79213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 79313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 79413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 79513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 79613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 79713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case 1:{ 79813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle class_datum_destroy(datum); 79913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle datum = 80013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle hashtab_search(policydbp->p_classes.table, 80113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle class_id); 80213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(datum); /* the class datum should have existed */ 80313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(class_id); 80413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 80513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 80613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle default:{ 807099223bd1f08ce0bc897f1a9f47852621bc946c9Dan Albert abort(); /* should never get here */ 80813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 80913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 81013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 81113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* now add each of the permissions to this class's requirements */ 81213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while ((perm_id = queue_remove(id_queue)) != NULL) { 81313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int allocated = 0; 81413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 81513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Is the permission already in the table? */ 81613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle perm = hashtab_search(datum->permissions.table, perm_id); 81713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!perm && datum->comdatum) 81813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle perm = 81913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle hashtab_search(datum->comdatum->permissions.table, 82013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle perm_id); 82113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (perm) { 82213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Yes, drop the name. */ 82313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(perm_id); 82413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 82513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* No - allocate and insert an entry for it. */ 82613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (policydbp->policy_type == POLICY_BASE) { 82713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror2 82813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ("Base policy - require of permission %s without prior declaration.", 82913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle perm_id); 83013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(perm_id); 83113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 83213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 83313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle allocated = 1; 83413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((perm = malloc(sizeof(*perm))) == NULL) { 83513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 83613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(perm_id); 83713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 83813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 83913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle memset(perm, 0, sizeof(*perm)); 84013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = 84113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle hashtab_insert(datum->permissions.table, perm_id, 84213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle perm); 84313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ret) { 84413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 84513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(perm_id); 84613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(perm); 84713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 84813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 84913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle perm->s.value = datum->permissions.nprim + 1; 85013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 85113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 85213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (add_perm_to_class(perm->s.value, datum->s.value) == -1) { 85313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 85413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 85513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 85613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 85713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Update number of primitives if we allocated one. */ 85813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (allocated) 85913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle datum->permissions.nprim++; 86013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 86113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 86213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cleanup: 86313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 86413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 86513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 86616675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciaostatic int require_role_or_attribute(int pass, unsigned char isattr) 86713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 86813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id = queue_remove(id_queue); 86913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_datum_t *role = NULL; 87013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int retval; 87113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (pass == 2) { 87213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(id); 87313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 87413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 87513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (id == NULL) { 87613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("no role name"); 87713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 87813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 87913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((role = malloc(sizeof(*role))) == NULL) { 88013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(id); 88113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 88213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 88313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 88413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_datum_init(role); 88516675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao role->flavor = isattr ? ROLE_ATTRIB : ROLE_ROLE; 88613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle retval = 88713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle require_symbol(SYM_ROLES, id, (hashtab_datum_t *) role, 88813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &role->s.value, &role->s.value); 88913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (retval != 0) { 89013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(id); 89113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_datum_destroy(role); 89213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(role); 89313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 89413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle switch (retval) { 89513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case -3:{ 89613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 89713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 89813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 89913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case -2:{ 90013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("duplicate declaration of role"); 90113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 90213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 90313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case -1:{ 90413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("could not require role here"); 90513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 90613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 90713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case 0:{ 90813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* all roles dominate themselves */ 90913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_set_bit 91013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (&role->dominates, role->s.value - 1, 1)) { 91113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory"); 91213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 91313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 91413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 91513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 91613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case 1:{ 91713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; /* role already required */ 91813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 91913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle default:{ 920099223bd1f08ce0bc897f1a9f47852621bc946c9Dan Albert abort(); /* should never get here */ 92113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 92213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 92313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 92413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 92516675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciaoint require_role(int pass) 92616675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao{ 92716675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao return require_role_or_attribute(pass, 0); 92816675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao} 92916675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao 93016675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciaoint require_attribute_role(int pass) 93116675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao{ 93216675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao return require_role_or_attribute(pass, 1); 93316675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao} 93416675b7f96b7a61ac64180b1824ec04984b72b3bHarry Ciao 93513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int require_type_or_attribute(int pass, unsigned char isattr) 93613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 93713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id = queue_remove(id_queue); 93813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type_datum_t *type = NULL; 93913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int retval; 94013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (pass == 2) { 94113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(id); 94213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 94313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 94413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (id == NULL) { 94513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("no type name"); 94613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 94713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 94813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((type = malloc(sizeof(*type))) == NULL) { 94913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(id); 95013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 95113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 95213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 95313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type_datum_init(type); 95413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type->primary = 1; 95513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type->flavor = isattr ? TYPE_ATTRIB : TYPE_TYPE; 95613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle retval = 95713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle require_symbol(SYM_TYPES, id, (hashtab_datum_t *) type, 95813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &type->s.value, &type->s.value); 95913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (retval != 0) { 96013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(id); 96113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(type); 96213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 96313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle switch (retval) { 96413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case -3:{ 96513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 96613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 96713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 96813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case -2:{ 96913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("duplicate declaration of type/attribute"); 97013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 97113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 97213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case -1:{ 97313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("could not require type/attribute here"); 97413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 97513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 97613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case 0:{ 97713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 97813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 97913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case 1:{ 98013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; /* type already required */ 98113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 98213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle default:{ 983099223bd1f08ce0bc897f1a9f47852621bc946c9Dan Albert abort(); /* should never get here */ 98413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 98513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 98613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 98713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 98813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint require_type(int pass) 98913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 99013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return require_type_or_attribute(pass, 0); 99113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 99213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 99313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint require_attribute(int pass) 99413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 99513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return require_type_or_attribute(pass, 1); 99613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 99713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 99813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint require_user(int pass) 99913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 100013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id = queue_remove(id_queue); 100113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle user_datum_t *user = NULL; 100213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int retval; 100313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (pass == 1) { 100413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(id); 100513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 100613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 100713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (id == NULL) { 100813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("no user name"); 100913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 101013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 101113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((user = malloc(sizeof(*user))) == NULL) { 101213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(id); 101313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 101413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 101513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 101613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle user_datum_init(user); 101713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle retval = 101813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle require_symbol(SYM_USERS, id, (hashtab_datum_t *) user, 101913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &user->s.value, &user->s.value); 102013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (retval != 0) { 102113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(id); 102213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle user_datum_destroy(user); 102313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 102413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle switch (retval) { 102513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case -3:{ 102613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 102713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 102813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 102913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case -2:{ 103013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("duplicate declaration of user"); 103113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 103213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 103313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case -1:{ 103413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("could not require user here"); 103513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 103613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 103713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case 0:{ 103813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 103913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 104013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case 1:{ 104113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; /* user already required */ 104213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 104313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle default:{ 1044099223bd1f08ce0bc897f1a9f47852621bc946c9Dan Albert abort(); /* should never get here */ 104513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 104613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 104713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 104813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 104980f26c5ee865993264ef638480c6a05ab574f7c0Harry Ciaostatic int require_bool_tunable(int pass, int is_tunable) 105013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 105113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id = queue_remove(id_queue); 105213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond_bool_datum_t *booldatum = NULL; 105313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int retval; 105413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (pass == 2) { 105513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(id); 105613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 105713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 105813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (id == NULL) { 105913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("no boolean name"); 106013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 106113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 106213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((booldatum = calloc(1, sizeof(*booldatum))) == NULL) { 106313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond_destroy_bool(id, booldatum, NULL); 106413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 106513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 106613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 106780f26c5ee865993264ef638480c6a05ab574f7c0Harry Ciao if (is_tunable) 106880f26c5ee865993264ef638480c6a05ab574f7c0Harry Ciao booldatum->flags |= COND_BOOL_FLAGS_TUNABLE; 106913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle retval = 107013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle require_symbol(SYM_BOOLS, id, (hashtab_datum_t *) booldatum, 107113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &booldatum->s.value, &booldatum->s.value); 107213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (retval != 0) { 107313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond_destroy_bool(id, booldatum, NULL); 107413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 107513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle switch (retval) { 107613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case -3:{ 107713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 107813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 107913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 108013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case -2:{ 108113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("duplicate declaration of boolean"); 108213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 108313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 108413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case -1:{ 108513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("could not require boolean here"); 108613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 108713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 108813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case 0:{ 108913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 109013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 109113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case 1:{ 109213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; /* boolean already required */ 109313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 109413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle default:{ 1095099223bd1f08ce0bc897f1a9f47852621bc946c9Dan Albert abort(); /* should never get here */ 109613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 109713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 109813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 109913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 110080f26c5ee865993264ef638480c6a05ab574f7c0Harry Ciaoint require_bool(int pass) 110180f26c5ee865993264ef638480c6a05ab574f7c0Harry Ciao{ 110280f26c5ee865993264ef638480c6a05ab574f7c0Harry Ciao return require_bool_tunable(pass, 0); 110380f26c5ee865993264ef638480c6a05ab574f7c0Harry Ciao} 110480f26c5ee865993264ef638480c6a05ab574f7c0Harry Ciao 110580f26c5ee865993264ef638480c6a05ab574f7c0Harry Ciaoint require_tunable(int pass) 110680f26c5ee865993264ef638480c6a05ab574f7c0Harry Ciao{ 110780f26c5ee865993264ef638480c6a05ab574f7c0Harry Ciao return require_bool_tunable(pass, 1); 110880f26c5ee865993264ef638480c6a05ab574f7c0Harry Ciao} 110980f26c5ee865993264ef638480c6a05ab574f7c0Harry Ciao 111013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint require_sens(int pass) 111113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 111213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id = queue_remove(id_queue); 111313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle level_datum_t *level = NULL; 111413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int retval; 111513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (pass == 2) { 111613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(id); 111713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 111813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 111913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!id) { 112013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("no sensitivity name"); 112113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 112213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 112313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle level = malloc(sizeof(level_datum_t)); 112413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!level) { 112513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(id); 112613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 112713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 112813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 112913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle level_datum_init(level); 113013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle level->level = malloc(sizeof(mls_level_t)); 113113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!level->level) { 113213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(id); 113313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle level_datum_destroy(level); 113413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(level); 113513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 113613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 113713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 113813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mls_level_init(level->level); 113913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle retval = require_symbol(SYM_LEVELS, id, (hashtab_datum_t *) level, 114013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &level->level->sens, &level->level->sens); 114113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (retval != 0) { 114213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(id); 114313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mls_level_destroy(level->level); 114413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(level->level); 114513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle level_datum_destroy(level); 114613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(level); 114713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 114813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle switch (retval) { 114913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case -3:{ 115013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 115113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 115213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 115313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case -2:{ 115413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("duplicate declaration of sensitivity"); 115513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 115613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 115713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case -1:{ 115813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("could not require sensitivity here"); 115913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 116013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 116113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case 0:{ 116213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 116313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 116413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case 1:{ 116513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; /* sensitivity already required */ 116613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 116713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle default:{ 1168099223bd1f08ce0bc897f1a9f47852621bc946c9Dan Albert abort(); /* should never get here */ 116913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 117013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 117113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 117213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 117313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint require_cat(int pass) 117413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 117513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id = queue_remove(id_queue); 117613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cat_datum_t *cat = NULL; 117713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int retval; 117813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (pass == 2) { 117913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(id); 118013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 118113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 118213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!id) { 118313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("no category name"); 118413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 118513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 118613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cat = malloc(sizeof(cat_datum_t)); 118713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!cat) { 118813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(id); 118913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 119013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 119113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 119213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cat_datum_init(cat); 119313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 119413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle retval = require_symbol(SYM_CATS, id, (hashtab_datum_t *) cat, 119513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &cat->s.value, &cat->s.value); 119613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (retval != 0) { 119713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(id); 119813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cat_datum_destroy(cat); 119913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(cat); 120013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 120113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle switch (retval) { 120213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case -3:{ 120313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 120413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 120513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 120613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case -2:{ 120713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("duplicate declaration of category"); 120813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 120913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 121013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case -1:{ 121113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("could not require category here"); 121213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 121313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 121413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case 0:{ 121513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 121613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 121713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case 1:{ 121813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; /* category already required */ 121913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 122013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle default:{ 1221099223bd1f08ce0bc897f1a9f47852621bc946c9Dan Albert abort(); /* should never get here */ 122213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 122313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 122413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 122513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 122613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int is_scope_in_stack(scope_datum_t * scope, scope_stack_t * stack) 122713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 1228581d3eb1281f7c970376649f5027df012269935aNicolas Iooss uint32_t i; 122913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (stack == NULL) { 123013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; /* no matching scope found */ 123113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 123213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (stack->type == 1) { 123313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_t *decl = stack->decl; 123413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < scope->decl_ids_len; i++) { 123513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (scope->decl_ids[i] == decl->decl_id) { 123613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 1; 123713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 123813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 123913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 124013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* note that conditionals can't declare or require 124113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * symbols, so skip this level */ 124213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 124313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 124413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* not within scope of this stack, so try its parent */ 124513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return is_scope_in_stack(scope, stack->parent); 124613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 124713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 124813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint is_id_in_scope(uint32_t symbol_type, hashtab_key_t id) 124913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 125013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle scope_datum_t *scope = 125113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (scope_datum_t *) hashtab_search(policydbp->scope[symbol_type]. 125213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle table, id); 125313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (scope == NULL) { 125413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 1; /* id is not known, so return success */ 125513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 125613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return is_scope_in_stack(scope, stack_top); 125713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 125813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 125913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int is_perm_in_scope_index(uint32_t perm_value, uint32_t class_value, 126013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle scope_index_t * scope) 126113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 126213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (class_value > scope->class_perms_len) { 126313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 1; 126413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 126513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_get_bit(scope->class_perms_map + class_value - 1, 126613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle perm_value - 1)) { 126713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 1; 126813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 126913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 127013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 127113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 127213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int is_perm_in_stack(uint32_t perm_value, uint32_t class_value, 127313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle scope_stack_t * stack) 127413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 127513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (stack == NULL) { 127613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; /* no matching scope found */ 127713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 127813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (stack->type == 1) { 127913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_t *decl = stack->decl; 128013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (is_perm_in_scope_index 128113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (perm_value, class_value, &decl->required) 128213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle || is_perm_in_scope_index(perm_value, class_value, 128313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &decl->declared)) { 128413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 1; 128513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 128613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 128713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* note that conditionals can't declare or require 128813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * symbols, so skip this level */ 128913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 129013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 129113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* not within scope of this stack, so try its parent */ 129213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return is_perm_in_stack(perm_value, class_value, stack->parent); 129313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 129413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 129513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint is_perm_in_scope(hashtab_key_t perm_id, hashtab_key_t class_id) 129613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 129713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle class_datum_t *cladatum = 129813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (class_datum_t *) hashtab_search(policydbp->p_classes.table, 129913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle class_id); 130013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle perm_datum_t *perdatum; 130113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (cladatum == NULL) { 130213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 1; 130313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 130413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle perdatum = (perm_datum_t *) hashtab_search(cladatum->permissions.table, 130513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle perm_id); 130613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (perdatum == NULL) { 130713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 1; 130813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 130913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return is_perm_in_stack(perdatum->s.value, cladatum->s.value, 131013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle stack_top); 131113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 131213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 131313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlecond_list_t *get_current_cond_list(cond_list_t * cond) 131413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 131513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* FIX ME: do something different here if in a nested 131613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * conditional? */ 131713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_t *decl = stack_top->decl; 131813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return get_decl_cond_list(policydbp, decl, cond); 131913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 132013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 132113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Append the new conditional node to the existing ones. During 132213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * expansion the list will be reversed -- i.e., the last AV rule will 132313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * be the first one listed in the policy. This matches the behavior 132413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * of the upstream compiler. */ 132513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlevoid append_cond_list(cond_list_t * cond) 132613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 132713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond_list_t *old_cond = get_current_cond_list(cond); 132813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_t *tmp; 132913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(old_cond != NULL); /* probably out of memory */ 133013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (old_cond->avtrue_list == NULL) { 133113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle old_cond->avtrue_list = cond->avtrue_list; 133213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 133313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (tmp = old_cond->avtrue_list; tmp->next != NULL; 133413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle tmp = tmp->next) ; 133513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle tmp->next = cond->avtrue_list; 133613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 133713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (old_cond->avfalse_list == NULL) { 133813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle old_cond->avfalse_list = cond->avfalse_list; 133913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 134013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (tmp = old_cond->avfalse_list; tmp->next != NULL; 134113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle tmp = tmp->next) ; 134213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle tmp->next = cond->avfalse_list; 134313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 134480f26c5ee865993264ef638480c6a05ab574f7c0Harry Ciao 134580f26c5ee865993264ef638480c6a05ab574f7c0Harry Ciao old_cond->flags |= cond->flags; 134613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 134713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 134813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlevoid append_avrule(avrule_t * avrule) 134913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 135013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_t *decl = stack_top->decl; 135113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 135213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* currently avrules follow a completely different code path 135313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * for handling avrules and compute types 135413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * (define_cond_avrule_te_avtab, define_cond_compute_type); 135513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * therefore there ought never be a conditional on top of the 135613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * scope stack */ 135713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(stack_top->type == 1); 135813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 135913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (stack_top->last_avrule == NULL) { 136013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle decl->avrules = avrule; 136113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 136213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle stack_top->last_avrule->next = avrule; 136313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 136413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle stack_top->last_avrule = avrule; 136513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 136613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 136713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* this doesn't actually append, but really prepends it */ 136813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlevoid append_role_trans(role_trans_rule_t * role_tr_rules) 136913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 137013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_t *decl = stack_top->decl; 137113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 137213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* role transitions are not allowed within conditionals */ 137313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(stack_top->type == 1); 137413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 137513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_tr_rules->next = decl->role_tr_rules; 137613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle decl->role_tr_rules = role_tr_rules; 137713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 137813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 137913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* this doesn't actually append, but really prepends it */ 138013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlevoid append_role_allow(role_allow_rule_t * role_allow_rules) 138113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 138213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_t *decl = stack_top->decl; 138313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 138413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* role allows are not allowed within conditionals */ 138513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(stack_top->type == 1); 138613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 138713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_allow_rules->next = decl->role_allow_rules; 138813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle decl->role_allow_rules = role_allow_rules; 138913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 139013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 139113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* this doesn't actually append, but really prepends it */ 1392516cb2a264448421bff692f47f61e8cf2a74237eEric Parisvoid append_filename_trans(filename_trans_rule_t * filename_trans_rules) 1393516cb2a264448421bff692f47f61e8cf2a74237eEric Paris{ 1394516cb2a264448421bff692f47f61e8cf2a74237eEric Paris avrule_decl_t *decl = stack_top->decl; 1395516cb2a264448421bff692f47f61e8cf2a74237eEric Paris 1396516cb2a264448421bff692f47f61e8cf2a74237eEric Paris /* filename transitions are not allowed within conditionals */ 1397516cb2a264448421bff692f47f61e8cf2a74237eEric Paris assert(stack_top->type == 1); 1398516cb2a264448421bff692f47f61e8cf2a74237eEric Paris 1399516cb2a264448421bff692f47f61e8cf2a74237eEric Paris filename_trans_rules->next = decl->filename_trans_rules; 1400516cb2a264448421bff692f47f61e8cf2a74237eEric Paris decl->filename_trans_rules = filename_trans_rules; 1401516cb2a264448421bff692f47f61e8cf2a74237eEric Paris} 1402516cb2a264448421bff692f47f61e8cf2a74237eEric Paris 1403516cb2a264448421bff692f47f61e8cf2a74237eEric Paris/* this doesn't actually append, but really prepends it */ 140413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlevoid append_range_trans(range_trans_rule_t * range_tr_rules) 140513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 140613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_t *decl = stack_top->decl; 140713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 140813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* range transitions are not allowed within conditionals */ 140913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(stack_top->type == 1); 141013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 141113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle range_tr_rules->next = decl->range_tr_rules; 141213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle decl->range_tr_rules = range_tr_rules; 141313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 141413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 141513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint begin_optional(int pass) 141613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 141713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_block_t *block = NULL; 141813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_t *decl; 141913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (pass == 1) { 142013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* allocate a new avrule block for this optional block */ 142113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((block = avrule_block_create()) == NULL || 142213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (decl = avrule_decl_create(next_decl_id)) == NULL) { 142313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 142413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 142513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle block->flags |= AVRULE_OPTIONAL; 142613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle block->branch_list = decl; 142713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle last_block->next = block; 142813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 142913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* select the next block from the chain built during pass 1 */ 143013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle block = last_block->next; 143113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(block != NULL && 143213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle block->branch_list != NULL && 143313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle block->branch_list->decl_id == next_decl_id); 143413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle decl = block->branch_list; 143513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 143613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (push_stack(1, block, decl) == -1) { 143713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 143813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 143913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle stack_top->last_avrule = NULL; 144013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle last_block = block; 144113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle next_decl_id++; 144213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 144313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cleanup: 144413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 144513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_block_destroy(block); 144613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 144713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 144813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 14495af8c5adb274cc45d3a41ce9b1ab2c7573463d74Nicolas Ioossint end_optional(int pass __attribute__ ((unused))) 145013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 145113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* once nested conditionals are allowed, do the stack unfolding here */ 145213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle pop_stack(); 145313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 145413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 145513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 145613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint begin_optional_else(int pass) 145713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 145813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_t *decl; 145913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(stack_top->type == 1 && stack_top->in_else == 0); 146013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (pass == 1) { 146113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* allocate a new declaration and add it to the 146213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * current chain */ 146313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((decl = avrule_decl_create(next_decl_id)) == NULL) { 146413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 146513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 146613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 146713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle stack_top->decl->next = decl; 146813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 146913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* pick the (hopefully last) declaration of this 147013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule block, built from pass 1 */ 147113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle decl = stack_top->decl->next; 147213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(decl != NULL && 147313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle decl->next == NULL && decl->decl_id == next_decl_id); 147413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 147513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle stack_top->in_else = 1; 147613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle stack_top->decl = decl; 147713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle stack_top->last_avrule = NULL; 147813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle stack_top->require_given = 0; 147913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle next_decl_id++; 148013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 148113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 148213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 148313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int copy_requirements(avrule_decl_t * dest, scope_stack_t * stack) 148413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 1485581d3eb1281f7c970376649f5027df012269935aNicolas Iooss uint32_t i; 148613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (stack == NULL) { 148713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 148813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 148913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (stack->type == 1) { 149013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle scope_index_t *src_scope = &stack->decl->required; 149113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle scope_index_t *dest_scope = &dest->required; 149213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < SYM_NUM; i++) { 149313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_t *src_bitmap = &src_scope->scope[i]; 149413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_t *dest_bitmap = &dest_scope->scope[i]; 149513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_union(dest_bitmap, src_bitmap)) { 149613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 149713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 149813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 149913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 150013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* now copy class permissions */ 150113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (src_scope->class_perms_len > dest_scope->class_perms_len) { 150213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_t *new_map = 150313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle realloc(dest_scope->class_perms_map, 150413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle src_scope->class_perms_len * 150513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sizeof(*new_map)); 150613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (new_map == NULL) { 150713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 150813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 150913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 151013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dest_scope->class_perms_map = new_map; 151113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = dest_scope->class_perms_len; 151213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i < src_scope->class_perms_len; i++) { 151313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_init(dest_scope->class_perms_map + i); 151413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 151513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dest_scope->class_perms_len = 151613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle src_scope->class_perms_len; 151713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 151813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < src_scope->class_perms_len; i++) { 151913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_t *src_bitmap = &src_scope->class_perms_map[i]; 152013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_t *dest_bitmap = 152113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &dest_scope->class_perms_map[i]; 152213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_union(dest_bitmap, src_bitmap)) { 152313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("Out of memory!"); 152413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 152513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 152613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 152713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 152813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return copy_requirements(dest, stack->parent); 152913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 153013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 153113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* During pass 1, check that at least one thing was required within 153213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * this block, for those places where a REQUIRED is necessary. During 153313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * pass 2, have this block inherit its parents' requirements. Return 153413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 0 on success, -1 on failure. */ 153513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint end_avrule_block(int pass) 153613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 153713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_t *decl = stack_top->decl; 153813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(stack_top->type == 1); 153913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (pass == 2) { 154013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* this avrule_decl inherits all of its parents' 154113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * requirements */ 154213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (copy_requirements(decl, stack_top->parent) == -1) { 154313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 154413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 154513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 154613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 154713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!stack_top->in_else && !stack_top->require_given) { 154813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (policydbp->policy_type == POLICY_BASE 154913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle && stack_top->parent != NULL) { 155013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* if this is base no require should be in the global block */ 155113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 155213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 155313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* non-ELSE branches must have at least one thing required */ 155413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle yyerror("This block has no require section."); 155513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 155613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 155713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 155813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 155913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 156013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 156113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Push a new scope on to the stack and update the 'last' pointer. 156213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Return 0 on success, -1 if out * of memory. */ 156313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int push_stack(int stack_type, ...) 156413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 156513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle scope_stack_t *s = calloc(1, sizeof(*s)); 156613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle va_list ap; 156713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (s == NULL) { 156813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 156913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 157013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle va_start(ap, stack_type); 157113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle switch (s->type = stack_type) { 157213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case 1:{ 157313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle s->u.avrule = va_arg(ap, avrule_block_t *); 157413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle s->decl = va_arg(ap, avrule_decl_t *); 157513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 157613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 157713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case 2:{ 157813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle s->u.cond_list = va_arg(ap, cond_list_t *); 157913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 158013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 158113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle default: 158213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* invalid stack type given */ 158313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(0); 158413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 158513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle va_end(ap); 158613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle s->parent = stack_top; 158713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle s->child = NULL; 158813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle stack_top = s; 158913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 159013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 159113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 159213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Pop off the most recently added from the stack. Update the 'last' 159313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * pointer. */ 159413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic void pop_stack(void) 159513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 159613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle scope_stack_t *parent; 159713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(stack_top != NULL); 159813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle parent = stack_top->parent; 159913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (parent != NULL) { 160013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle parent->child = NULL; 160113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 160213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(stack_top); 160313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle stack_top = parent; 160413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 1605