/src/selinux/libsepol/src/avrule_block.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Authors: Jason Tang <jtang@tresys.com> |
2 | | * |
3 | | * Functions that manipulate a logical block (conditional, optional, |
4 | | * or global scope) for a policy module. |
5 | | * |
6 | | * Copyright (C) 2005 Tresys Technology, LLC |
7 | | * |
8 | | * This library is free software; you can redistribute it and/or |
9 | | * modify it under the terms of the GNU Lesser General Public |
10 | | * License as published by the Free Software Foundation; either |
11 | | * version 2.1 of the License, or (at your option) any later version. |
12 | | * |
13 | | * This library is distributed in the hope that it will be useful, |
14 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
16 | | * Lesser General Public License for more details. |
17 | | * |
18 | | * You should have received a copy of the GNU Lesser General Public |
19 | | * License along with this library; if not, write to the Free Software |
20 | | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
21 | | */ |
22 | | |
23 | | #include <sepol/policydb/policydb.h> |
24 | | #include <sepol/policydb/conditional.h> |
25 | | #include <sepol/policydb/avrule_block.h> |
26 | | |
27 | | #include <assert.h> |
28 | | #include <stdlib.h> |
29 | | |
30 | | /* It is anticipated that there be less declarations within an avrule |
31 | | * block than the global policy. Thus the symbol table sizes are |
32 | | * smaller than those listed in policydb.c */ |
33 | | static const unsigned int symtab_sizes[SYM_NUM] = { |
34 | | 2, |
35 | | 4, |
36 | | 8, |
37 | | 32, |
38 | | 16, |
39 | | 4, |
40 | | 2, |
41 | | 2, |
42 | | }; |
43 | | |
44 | | avrule_block_t *avrule_block_create(void) |
45 | 2.77k | { |
46 | 2.77k | avrule_block_t *block; |
47 | 2.77k | if ((block = calloc(1, sizeof(*block))) == NULL) { |
48 | 0 | return NULL; |
49 | 0 | } |
50 | 2.77k | return block; |
51 | 2.77k | } |
52 | | |
53 | | avrule_decl_t *avrule_decl_create(uint32_t decl_id) |
54 | 2.77k | { |
55 | 2.77k | avrule_decl_t *decl; |
56 | 2.77k | int i; |
57 | 2.77k | if ((decl = calloc(1, sizeof(*decl))) == NULL) { |
58 | 0 | return NULL; |
59 | 0 | } |
60 | 2.77k | decl->decl_id = decl_id; |
61 | 24.9k | for (i = 0; i < SYM_NUM; i++) { |
62 | 22.1k | if (symtab_init(&decl->symtab[i], symtab_sizes[i])) { |
63 | 0 | avrule_decl_destroy(decl); |
64 | 0 | return NULL; |
65 | 0 | } |
66 | 22.1k | } |
67 | | |
68 | 24.9k | for (i = 0; i < SYM_NUM; i++) { |
69 | 22.1k | ebitmap_init(&decl->required.scope[i]); |
70 | 22.1k | ebitmap_init(&decl->declared.scope[i]); |
71 | 22.1k | } |
72 | 2.77k | return decl; |
73 | 2.77k | } |
74 | | |
75 | | /* note that unlike the other destroy functions, this one does /NOT/ |
76 | | * destroy the pointer itself */ |
77 | | static void scope_index_destroy(scope_index_t * scope) |
78 | 5.54k | { |
79 | 5.54k | unsigned int i; |
80 | 5.54k | if (scope == NULL) { |
81 | 0 | return; |
82 | 0 | } |
83 | 49.9k | for (i = 0; i < SYM_NUM; i++) { |
84 | 44.3k | ebitmap_destroy(scope->scope + i); |
85 | 44.3k | } |
86 | 5.54k | if (scope->class_perms_map) { |
87 | 0 | for (i = 0; i < scope->class_perms_len; i++) { |
88 | 0 | ebitmap_destroy(scope->class_perms_map + i); |
89 | 0 | } |
90 | 0 | } |
91 | 5.54k | free(scope->class_perms_map); |
92 | 5.54k | } |
93 | | |
94 | | void avrule_decl_destroy(avrule_decl_t * x) |
95 | 2.77k | { |
96 | 2.77k | if (x == NULL) { |
97 | 0 | return; |
98 | 0 | } |
99 | 2.77k | cond_list_destroy(x->cond_list); |
100 | 2.77k | avrule_list_destroy(x->avrules); |
101 | 2.77k | role_trans_rule_list_destroy(x->role_tr_rules); |
102 | 2.77k | filename_trans_rule_list_destroy(x->filename_trans_rules); |
103 | 2.77k | role_allow_rule_list_destroy(x->role_allow_rules); |
104 | 2.77k | range_trans_rule_list_destroy(x->range_tr_rules); |
105 | 2.77k | scope_index_destroy(&x->required); |
106 | 2.77k | scope_index_destroy(&x->declared); |
107 | 2.77k | symtabs_destroy(x->symtab); |
108 | 2.77k | free(x->module_name); |
109 | 2.77k | free(x); |
110 | 2.77k | } |
111 | | |
112 | | void avrule_block_destroy(avrule_block_t * x) |
113 | 2.77k | { |
114 | 2.77k | avrule_decl_t *decl; |
115 | 2.77k | if (x == NULL) { |
116 | 0 | return; |
117 | 0 | } |
118 | 2.77k | decl = x->branch_list; |
119 | 5.54k | while (decl != NULL) { |
120 | 2.77k | avrule_decl_t *next_decl = decl->next; |
121 | 2.77k | avrule_decl_destroy(decl); |
122 | 2.77k | decl = next_decl; |
123 | 2.77k | } |
124 | 2.77k | free(x); |
125 | 2.77k | } |
126 | | |
127 | | void avrule_block_list_destroy(avrule_block_t * x) |
128 | 2.77k | { |
129 | 5.54k | while (x != NULL) { |
130 | 2.77k | avrule_block_t *next = x->next; |
131 | 2.77k | avrule_block_destroy(x); |
132 | 2.77k | x = next; |
133 | 2.77k | } |
134 | 2.77k | } |
135 | | |
136 | | /* Get a conditional node from a avrule_decl with the same expression. |
137 | | * If that expression does not exist then create one. */ |
138 | | cond_list_t *get_decl_cond_list(policydb_t * p, avrule_decl_t * decl, |
139 | | cond_list_t * cond) |
140 | 0 | { |
141 | 0 | cond_list_t *result; |
142 | 0 | int was_created; |
143 | 0 | result = cond_node_find(p, cond, decl->cond_list, &was_created); |
144 | 0 | if (result != NULL && was_created) { |
145 | 0 | result->next = decl->cond_list; |
146 | 0 | decl->cond_list = result; |
147 | 0 | } |
148 | 0 | return result; |
149 | 0 | } |
150 | | |
151 | | /* Look up an identifier in a policy's scoping table. If it is there, |
152 | | * marked as SCOPE_DECL, and any of its declaring block has been enabled, |
153 | | * then return 1. Otherwise return 0. Can only be called after the |
154 | | * decl_val_to_struct index has been created */ |
155 | | int is_id_enabled(const char *id, const policydb_t * p, int symbol_table) |
156 | 0 | { |
157 | 0 | const scope_datum_t *scope = |
158 | 0 | (scope_datum_t *) hashtab_search(p->scope[symbol_table].table, id); |
159 | 0 | const avrule_decl_t *decl; |
160 | 0 | uint32_t len; |
161 | |
|
162 | 0 | if (scope == NULL) { |
163 | 0 | return 0; |
164 | 0 | } |
165 | 0 | if (scope->scope != SCOPE_DECL) { |
166 | 0 | return 0; |
167 | 0 | } |
168 | | |
169 | 0 | len = scope->decl_ids_len; |
170 | 0 | if (len < 1) { |
171 | 0 | return 0; |
172 | 0 | } |
173 | | |
174 | 0 | if (symbol_table == SYM_ROLES || symbol_table == SYM_USERS) { |
175 | 0 | uint32_t i; |
176 | 0 | for (i = 0; i < len; i++) { |
177 | 0 | decl = p->decl_val_to_struct[scope->decl_ids[i] - 1]; |
178 | 0 | if (decl != NULL && decl->enabled) { |
179 | 0 | return 1; |
180 | 0 | } |
181 | 0 | } |
182 | 0 | } else { |
183 | 0 | decl = p->decl_val_to_struct[scope->decl_ids[len-1] - 1]; |
184 | 0 | if (decl != NULL && decl->enabled) { |
185 | 0 | return 1; |
186 | 0 | } |
187 | 0 | } |
188 | | |
189 | 0 | return 0; |
190 | 0 | } |
191 | | |
192 | | /* Check if a particular permission is present within the given class. |
193 | | * Whether the class is enabled is NOT checked. |
194 | | * Returns 1 if permission is present, 0 otherwise */ |
195 | | int is_perm_existent(const class_datum_t *cladatum, const char *perm_id) |
196 | 0 | { |
197 | 0 | const perm_datum_t *perm; |
198 | |
|
199 | 0 | perm = hashtab_search(cladatum->permissions.table, perm_id); |
200 | 0 | if (perm == NULL && cladatum->comdatum != 0) { |
201 | | /* permission was not in this class. before giving |
202 | | * up, check the class's parent */ |
203 | 0 | perm = |
204 | 0 | hashtab_search(cladatum->comdatum->permissions.table, |
205 | 0 | perm_id); |
206 | 0 | } |
207 | 0 | if (perm == NULL) { |
208 | 0 | return 0; |
209 | 0 | } |
210 | 0 | return 1; |
211 | 0 | } |