113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Authors: Jason Tang <jtang@tresys.com>
213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *
313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Functions that manipulate a logical block (conditional, optional,
413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * or global scope) for a policy module.
513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *
613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Copyright (C) 2005 Tresys Technology, LLC
713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *
813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *  This library is free software; you can redistribute it and/or
913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *  modify it under the terms of the GNU Lesser General Public
1013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *  License as published by the Free Software Foundation; either
1113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *  version 2.1 of the License, or (at your option) any later version.
1213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *
1313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *  This library is distributed in the hope that it will be useful,
1413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *  but WITHOUT ANY WARRANTY; without even the implied warranty of
1513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *  Lesser General Public License for more details.
1713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *
1813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *  You should have received a copy of the GNU Lesser General Public
1913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *  License along with this library; if not, write to the Free Software
2013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
2113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */
2213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
2313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/policydb/policydb.h>
2413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/policydb/conditional.h>
2513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/policydb/avrule_block.h>
2613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
2713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <assert.h>
2813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <stdlib.h>
2913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
3013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* It is anticipated that there be less declarations within an avrule
3113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * block than the global policy.  Thus the symbol table sizes are
3213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * smaller than those listed in policydb.c */
3313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic unsigned int symtab_sizes[SYM_NUM] = {
3413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	2,
3513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	4,
3613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	8,
3713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	32,
3813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	16,
3913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	4,
4013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	2,
4113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	2,
4213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle};
4313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
4413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleavrule_block_t *avrule_block_create(void)
4513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
4613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	avrule_block_t *block;
4713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if ((block = calloc(1, sizeof(*block))) == NULL) {
4813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return NULL;
4913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
5013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return block;
5113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
5213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
5313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleavrule_decl_t *avrule_decl_create(uint32_t decl_id)
5413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
5513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	avrule_decl_t *decl;
5613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int i;
5713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if ((decl = calloc(1, sizeof(*decl))) == NULL) {
5813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return NULL;
5913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
6013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	decl->decl_id = decl_id;
6113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	for (i = 0; i < SYM_NUM; i++) {
6213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (symtab_init(&decl->symtab[i], symtab_sizes[i])) {
6313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			avrule_decl_destroy(decl);
6413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			return NULL;
6513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
6613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
6713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
6813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	for (i = 0; i < SYM_NUM; i++) {
6913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		ebitmap_init(&decl->required.scope[i]);
7013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		ebitmap_init(&decl->declared.scope[i]);
7113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
7213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return decl;
7313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
7413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
7513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* note that unlike the other destroy functions, this one does /NOT/
7613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * destroy the pointer itself */
7713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic void scope_index_destroy(scope_index_t * scope)
7813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
7913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	unsigned int i;
8013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (scope == NULL) {
8113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return;
8213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
8313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	for (i = 0; i < SYM_NUM; i++) {
8413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		ebitmap_destroy(scope->scope + i);
8513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
8613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	for (i = 0; i < scope->class_perms_len; i++) {
8713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		ebitmap_destroy(scope->class_perms_map + i);
8813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
8913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	free(scope->class_perms_map);
9013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
9113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
9213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlevoid avrule_decl_destroy(avrule_decl_t * x)
9313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
9413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (x == NULL) {
9513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return;
9613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
9713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	cond_list_destroy(x->cond_list);
9813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	avrule_list_destroy(x->avrules);
9913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	role_trans_rule_list_destroy(x->role_tr_rules);
1006eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris	filename_trans_rule_list_destroy(x->filename_trans_rules);
10113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	role_allow_rule_list_destroy(x->role_allow_rules);
10213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	range_trans_rule_list_destroy(x->range_tr_rules);
10313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	scope_index_destroy(&x->required);
10413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	scope_index_destroy(&x->declared);
10513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	symtabs_destroy(x->symtab);
10613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	free(x->module_name);
10713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	free(x);
10813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
10913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
11013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlevoid avrule_block_destroy(avrule_block_t * x)
11113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
11213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	avrule_decl_t *decl;
11313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (x == NULL) {
11413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return;
11513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
11613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	decl = x->branch_list;
11713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	while (decl != NULL) {
11813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		avrule_decl_t *next_decl = decl->next;
11913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		avrule_decl_destroy(decl);
12013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		decl = next_decl;
12113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
12213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	free(x);
12313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
12413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
12513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlevoid avrule_block_list_destroy(avrule_block_t * x)
12613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
12713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	while (x != NULL) {
12813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		avrule_block_t *next = x->next;
12913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		avrule_block_destroy(x);
13013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		x = next;
13113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
13213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
13313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
13413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Get a conditional node from a avrule_decl with the same expression.
13513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * If that expression does not exist then create one. */
13613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlecond_list_t *get_decl_cond_list(policydb_t * p, avrule_decl_t * decl,
13713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				cond_list_t * cond)
13813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
13913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	cond_list_t *result;
14013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int was_created;
14113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	result = cond_node_find(p, cond, decl->cond_list, &was_created);
14213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (result != NULL && was_created) {
14313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		result->next = decl->cond_list;
14413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		decl->cond_list = result;
14513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
14613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return result;
14713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
14813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
14913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Look up an identifier in a policy's scoping table.  If it is there,
15013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * marked as SCOPE_DECL, and any of its declaring block has been enabled,
15113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * then return 1.  Otherwise return 0. Can only be called after the
15213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * decl_val_to_struct index has been created */
15313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint is_id_enabled(char *id, policydb_t * p, int symbol_table)
15413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
15513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	scope_datum_t *scope =
15613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	    (scope_datum_t *) hashtab_search(p->scope[symbol_table].table, id);
15713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	uint32_t i;
15813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (scope == NULL) {
15913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return 0;
16013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
16113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (scope->scope != SCOPE_DECL) {
16213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return 0;
16313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
16413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	for (i = 0; i < scope->decl_ids_len; i++) {
16513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		avrule_decl_t *decl =
16613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		    p->decl_val_to_struct[scope->decl_ids[i] - 1];
16713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (decl != NULL && decl->enabled) {
16813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			return 1;
16913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
17013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
17113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return 0;
17213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
17313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
17413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Check if a particular permission is present within the given class,
17513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * and that the class is enabled.  Returns 1 if both conditions are
17613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * true, 0 if neither could be found or if the class id disabled. */
17713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint is_perm_enabled(char *class_id, char *perm_id, policydb_t * p)
17813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
17913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	class_datum_t *cladatum;
18013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	perm_datum_t *perm;
18113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (!is_id_enabled(class_id, p, SYM_CLASSES)) {
18213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return 0;
18313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
18413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	cladatum =
18513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	    (class_datum_t *) hashtab_search(p->p_classes.table, class_id);
18613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (cladatum == NULL) {
18713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return 0;
18813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
18913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	perm = hashtab_search(cladatum->permissions.table, perm_id);
19013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (perm == NULL && cladatum->comdatum != 0) {
19113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		/* permission was not in this class.  before giving
19213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		 * up, check the class's parent */
19313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		perm =
19413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		    hashtab_search(cladatum->comdatum->permissions.table,
19513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				   perm_id);
19613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
19713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (perm == NULL) {
19813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return 0;
19913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
20013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return 1;
20113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
202