Jason Tang jtang@tresys.com
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Definition in file domain-trans-analysis.c.
#include "policy-query-internal.h"
#include "domain-trans-analysis-internal.h"
#include <apol/domain-trans-analysis.h>
#include <apol/bst.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <stdbool.h>
Go to the source code of this file.
Classes | |
| struct | apol_domain_trans_table |
| struct | dom_node |
| struct | ep_node |
| struct | avrule_node |
| struct | terule_node |
| struct | apol_domain_trans_analysis |
| struct | apol_domain_trans_result |
| struct | rule_map_data |
Typedefs | |
| typedef dom_node | dom_node_t |
| typedef ep_node | ep_node_t |
| typedef avrule_node | avrule_node_t |
| typedef terule_node | terule_node_t |
Functions | |
| int | avrule_node_cmp (const void *a, const void *b, void *data __attribute__((unused))) |
| int | avrule_node_reset (void *a, void *b __attribute__((unused))) |
| avrule_node_t * | avrule_node_create (const qpol_type_t *type, const qpol_avrule_t *rule) |
| int | terule_node_cmp (const void *a, const void *b, void *data __attribute__((unused))) |
| int | terule_node_reset (void *a, void *b __attribute__((unused))) |
| terule_node_t * | terule_node_create (const qpol_type_t *src, const qpol_type_t *dflt, const qpol_terule_t *rule) |
| int | dom_node_cmp (const void *a, const void *b, void *data __attribute__((unused))) |
| void | dom_node_free (void *x) |
| int | dom_node_reset (void *a, void *b __attribute__((unused))) |
| dom_node_t * | dom_node_create (const qpol_type_t *type) |
| int | ep_node_cmp (const void *a, const void *b, void *data __attribute__((unused))) |
| void | ep_node_free (void *x) |
| int | ep_node_reset (void *a, void *b __attribute__((unused))) |
| ep_node_t * | ep_node_create (const qpol_type_t *type) |
| apol_domain_trans_table_t * | apol_domain_trans_table_new (apol_policy_t *policy) |
| int | table_add_avrule (apol_policy_t *policy, apol_domain_trans_table_t *dta_table, const qpol_avrule_t *rule) |
| int | table_add_terule (apol_policy_t *policy, apol_domain_trans_table_t *dta_table, const qpol_terule_t *rule) |
| apol_domain_trans_result_t * | domain_trans_result_create () |
| int | apol_policy_build_domain_trans_table (apol_policy_t *policy) |
| Build the table of domain transitions for a policy if not already built. | |
| int | apol_policy_domain_trans_table_build (apol_policy_t *policy) |
| void | domain_trans_table_destroy (apol_domain_trans_table_t **table) |
| Destroy the domain transition table freeing all memory used. | |
| void | apol_policy_reset_domain_trans_table (apol_policy_t *policy) |
| Reset the state of the domain transition table in a policy. | |
| void | apol_domain_trans_table_reset (apol_policy_t *policy) |
| apol_domain_trans_analysis_t * | apol_domain_trans_analysis_create (void) |
| Allocate and return a new domain transition analysis structure. | |
| void | apol_domain_trans_analysis_destroy (apol_domain_trans_analysis_t **dta) |
| Deallocate all memory associated with the referenced domain transition analysis structure, and then set it to NULL. | |
| int | apol_domain_trans_analysis_set_direction (const apol_policy_t *policy, apol_domain_trans_analysis_t *dta, unsigned char direction) |
| Set the direction of the transitions with respect to the start type. | |
| int | apol_domain_trans_analysis_set_valid (const apol_policy_t *policy, apol_domain_trans_analysis_t *dta, unsigned char valid) |
| Set the analysis to search for transitions based upon whether they would be permitted. | |
| int | apol_domain_trans_analysis_set_start_type (const apol_policy_t *policy, apol_domain_trans_analysis_t *dta, const char *type_name) |
| Set the analysis to begin searching using a given type. | |
| int | apol_domain_trans_analysis_set_result_regex (const apol_policy_t *policy, apol_domain_trans_analysis_t *dta, const char *regex) |
| Set the analysis to return only types matching a regular expression. | |
| int | apol_domain_trans_analysis_append_access_type (const apol_policy_t *policy, apol_domain_trans_analysis_t *dta, const char *type_name) |
| Set the analysis to return only types having access (via allow rules) to this type. | |
| int | apol_domain_trans_analysis_append_class_perm (const apol_policy_t *policy, apol_domain_trans_analysis_t *dta, const char *class_name, const char *perm_name) |
| Set the analysis to return only types having access (via allow rules) to this class with the given permission. | |
| int | apol_domain_trans_analysis_append_class (const apol_policy_t *policy, apol_domain_trans_analysis_t *dta, const char *class_name) |
| Set the analysis to return only types having access (via allow rules) to this class. | |
| int | apol_domain_trans_analysis_append_perm (const apol_policy_t *policy, apol_domain_trans_analysis_t *dta, const char *perm_name) |
| Set the analysis to return only types having access (via allow rules) to this permission. | |
| bool | requires_setexec_or_type_trans (apol_policy_t *policy) |
| int | node_list_map_fn (void *node, void *data) |
| apol_vector_t * | find_avrules_in_node (void *node, unsigned int rule_type, const qpol_type_t *search) |
| apol_vector_t * | find_terules_in_node (ep_node_t *node, const qpol_type_t *search, const qpol_type_t *dflt) |
| apol_domain_trans_result_t * | find_result (apol_vector_t *local_results, const qpol_type_t *src, const qpol_type_t *tgt, const qpol_type_t *dflt) |
| int | domain_trans_table_find_orphan_type_transitions (apol_policy_t *policy, apol_domain_trans_analysis_t *dta, apol_vector_t *local_results) |
| int | domain_trans_table_get_all_forward_trans (apol_policy_t *policy, apol_domain_trans_analysis_t *dta, apol_vector_t *local_results, const qpol_type_t *start_type) |
| int | domain_trans_table_get_all_reverse_trans (apol_policy_t *policy, apol_domain_trans_analysis_t *dta, apol_vector_t *local_results, const qpol_type_t *end_type) |
| int | apol_domain_trans_analysis_do (apol_policy_t *policy, apol_domain_trans_analysis_t *dta, apol_vector_t **results) |
| Execute a domain transition analysis against a particular policy. | |
| const qpol_type_t * | apol_domain_trans_result_get_start_type (const apol_domain_trans_result_t *dtr) |
| Return the start type of the transition in an apol_domain_trans_result node. | |
| const qpol_type_t * | apol_domain_trans_result_get_entrypoint_type (const apol_domain_trans_result_t *dtr) |
| Return the entrypoint type of the transition in an apol_domain_trans_result node. | |
| const qpol_type_t * | apol_domain_trans_result_get_end_type (const apol_domain_trans_result_t *dtr) |
| Return the end type of the transition in an apol_domain_trans_result node. | |
| const apol_vector_t * | apol_domain_trans_result_get_proc_trans_rules (const apol_domain_trans_result_t *dtr) |
| Return the vector of process transition rules (qpol_avrule_t pointers) in an apol_domain_trans_result node. | |
| const apol_vector_t * | apol_domain_trans_result_get_entrypoint_rules (const apol_domain_trans_result_t *dtr) |
| Return the vector of file entrypoint rules (qpol_avrule_t pointers) in an apol_domain_trans_result node. | |
| const apol_vector_t * | apol_domain_trans_result_get_exec_rules (const apol_domain_trans_result_t *dtr) |
| Return the vector of file execute rules (qpol_avrule_t pointers) in an apol_domain_trans_result node. | |
| const apol_vector_t * | apol_domain_trans_result_get_setexec_rules (const apol_domain_trans_result_t *dtr) |
| Return the vector of process setexec rules (qpol_avrule_t pointers) in an apol_domain_trans_result node. | |
| const apol_vector_t * | apol_domain_trans_result_get_type_trans_rules (const apol_domain_trans_result_t *dtr) |
| Return the vector of type_transition rules (qpol_terule_t pointers) in an apol_domain_trans_result node. | |
| int | apol_domain_trans_result_is_trans_valid (const apol_domain_trans_result_t *dtr) |
| Determine if the transition in an apol_domain_trans_result node is valid. | |
| const apol_vector_t * | apol_domain_trans_result_get_access_rules (const apol_domain_trans_result_t *dtr) |
| Return the vector of access rules which satisfied the access types, classes, and permissions specified in the query. | |
| int | apol_domain_trans_table_verify_trans (apol_policy_t *policy, const qpol_type_t *start_dom, const qpol_type_t *ep_type, const qpol_type_t *end_dom) |
| Verify that a transition using the given three types is valid in the given policy. | |
| apol_domain_trans_result_t * | apol_domain_trans_result_create_from_domain_trans_result (const apol_domain_trans_result_t *result) |
| Do a deep copy (i.e., a clone) of an apol_domain_trans_result_t object. | |
| void | domain_trans_result_free (void *dtr) |
| Free all memory associated with a domain transition result, including the pointer itself. | |
| void | apol_domain_trans_result_destroy (apol_domain_trans_result_t **res) |
| Free all memory used by an apol_domain_trans_result_t object and set it to NULL. | |
|
|
|
|
|
||||||||||||||||
|
Definition at line 105 of file domain-trans-analysis.c. References avrule_node_t, avrule_node::rule, and avrule_node::type. Referenced by dom_node_create(), and ep_node_create(). 00106 {
00107 const avrule_node_t *an = a;
00108 const avrule_node_t *bn = b;
00109 ssize_t retv = (const char *)an->type - (const char *)bn->type;
00110 if (retv > 0)
00111 return 1;
00112 else if (retv < 0)
00113 return -1;
00114 retv = (const char *)an->rule - (const char *)bn->rule;
00115 if (retv > 0)
00116 return 1;
00117 else if (retv < 0)
00118 return -1;
00119 return 0;
00120 }
|
|
||||||||||||
|
Definition at line 122 of file domain-trans-analysis.c. References avrule_node_t, and avrule_node::used. Referenced by dom_node_reset(), and ep_node_reset(). 00123 {
00124 avrule_node_t *an = a;
00125 if (!a)
00126 return -1;
00127 an->used = false;
00128 return 0;
00129 }
|
|
||||||||||||
|
Definition at line 131 of file domain-trans-analysis.c. References avrule_node_t, avrule_node::rule, and avrule_node::type. Referenced by table_add_avrule(). 00132 {
00133 avrule_node_t *n = calloc(1, sizeof(*n));
00134 if (!n)
00135 return NULL;
00136
00137 n->type = type;
00138 n->rule = rule;
00139
00140 return n;
00141 }
|
|
||||||||||||||||
|
Definition at line 144 of file domain-trans-analysis.c. References terule_node::dflt, terule_node::rule, terule_node::src, and terule_node_t. Referenced by ep_node_create(). 00145 {
00146 const terule_node_t *an = a;
00147 const terule_node_t *bn = b;
00148 ssize_t retv = (const char *)an->src - (const char *)bn->src;
00149 if (retv > 0)
00150 return 1;
00151 else if (retv < 0)
00152 return -1;
00153 retv = (const char *)an->dflt - (const char *)bn->dflt;
00154 if (retv > 0)
00155 return 1;
00156 else if (retv < 0)
00157 return -1;
00158 retv = (const char *)an->rule - (const char *)bn->rule;
00159 if (retv > 0)
00160 return 1;
00161 else if (retv < 0)
00162 return -1;
00163 return 0;
00164 }
|
|
||||||||||||
|
Definition at line 166 of file domain-trans-analysis.c. References terule_node_t, and terule_node::used. Referenced by ep_node_reset(). 00167 {
00168 terule_node_t *an = a;
00169 if (!a)
00170 return -1;
00171 an->used = false;
00172 return 0;
00173 }
|
|
||||||||||||||||
|
Definition at line 175 of file domain-trans-analysis.c. References terule_node::dflt, terule_node::rule, terule_node::src, and terule_node_t. Referenced by table_add_terule(). 00176 {
00177 terule_node_t *n = calloc(1, sizeof(*n));
00178 if (!n)
00179 return NULL;
00180
00181 n->src = src;
00182 n->dflt = dflt;
00183 n->rule = rule;
00184
00185 return n;
00186 }
|
|
||||||||||||||||
|
Definition at line 189 of file domain-trans-analysis.c. References dom_node_t, and dom_node::type. Referenced by apol_domain_trans_table_new(). 00190 {
00191 const dom_node_t *an = a;
00192 const dom_node_t *bn = b;
00193
00194 if ((const char *)(an->type) < (const char *)(bn->type))
00195 return -1;
00196 else if ((const char *)(an->type) > (const char *)(bn->type))
00197 return 1;
00198 return 0;
00199 }
|
|
|
Definition at line 201 of file domain-trans-analysis.c. References apol_bst_destroy(), apol_vector_destroy(), and dom_node_t. Referenced by apol_domain_trans_table_new(), and table_add_avrule(). 00202 {
00203 if (!x)
00204 return;
00205 apol_bst_destroy(&(((dom_node_t *) x)->process_transition_tree));
00206 apol_bst_destroy(&(((dom_node_t *) x)->entrypoint_tree));
00207 apol_vector_destroy(&(((dom_node_t *) x)->setexec_rules));
00208 free(x);
00209 }
|
|
||||||||||||
|
Definition at line 211 of file domain-trans-analysis.c. References apol_bst_inorder_map(), avrule_node_reset(), dom_node_t, dom_node::entrypoint_tree, and dom_node::process_transition_tree. Referenced by apol_policy_reset_domain_trans_table(). 00212 {
00213 dom_node_t *an = a;
00214 if (!a)
00215 return -1;
00216
00217 if (apol_bst_inorder_map(an->process_transition_tree, avrule_node_reset, NULL) < 0)
00218 return -1;
00219 if (apol_bst_inorder_map(an->entrypoint_tree, avrule_node_reset, NULL) < 0)
00220 return -1;
00221
00222 return 0;
00223 }
|
|
|
Definition at line 225 of file domain-trans-analysis.c. References apol_bst_create(), apol_bst_destroy(), apol_vector_create(), apol_vector_destroy(), avrule_node_cmp(), dom_node_t, and dom_node::type. Referenced by table_add_avrule(). 00226 {
00227 dom_node_t *n = calloc(1, sizeof(*n));
00228 if (!n)
00229 return NULL;
00230
00231 n->type = type;
00232 if (!(n->process_transition_tree = apol_bst_create(avrule_node_cmp, free)) ||
00233 !(n->entrypoint_tree = apol_bst_create(avrule_node_cmp, free)) || !(n->setexec_rules = apol_vector_create(NULL))) {
00234 apol_bst_destroy(&n->process_transition_tree);
00235 apol_bst_destroy(&n->entrypoint_tree);
00236 apol_vector_destroy(&n->setexec_rules);
00237 free(n);
00238 return NULL;
00239 }
00240
00241 return n;
00242 }
|
|
||||||||||||||||
|
Definition at line 245 of file domain-trans-analysis.c. References ep_node_t, and ep_node::type. Referenced by apol_domain_trans_table_new(). 00246 {
00247 const ep_node_t *an = a;
00248 const ep_node_t *bn = b;
00249
00250 if ((const char *)(an->type) < (const char *)(bn->type))
00251 return -1;
00252 else if ((const char *)(an->type) > (const char *)(bn->type))
00253 return 1;
00254 return 0;
00255 }
|
|
|
Definition at line 257 of file domain-trans-analysis.c. References apol_bst_destroy(), and ep_node_t. Referenced by apol_domain_trans_table_new(), table_add_avrule(), and table_add_terule(). 00258 {
00259 if (!x)
00260 return;
00261 apol_bst_destroy(&(((ep_node_t *) x)->type_transition_tree));
00262 apol_bst_destroy(&(((ep_node_t *) x)->execute_tree));
00263 free(x);
00264 }
|
|
||||||||||||
|
Definition at line 266 of file domain-trans-analysis.c. References apol_bst_inorder_map(), avrule_node_reset(), ep_node_t, ep_node::execute_tree, terule_node_reset(), and ep_node::type_transition_tree. Referenced by apol_policy_reset_domain_trans_table(). 00267 {
00268 ep_node_t *an = a;
00269 if (!a)
00270 return -1;
00271
00272 if (apol_bst_inorder_map(an->execute_tree, avrule_node_reset, NULL) < 0)
00273 return -1;
00274 if (apol_bst_inorder_map(an->type_transition_tree, terule_node_reset, NULL) < 0)
00275 return -1;
00276 return 0;
00277 }
|
|
|
Definition at line 279 of file domain-trans-analysis.c. References apol_bst_create(), apol_bst_destroy(), avrule_node_cmp(), ep_node_t, terule_node_cmp(), and ep_node::type. Referenced by table_add_avrule(), and table_add_terule(). 00280 {
00281 ep_node_t *n = calloc(1, sizeof(*n));
00282 if (!n)
00283 return NULL;
00284
00285 n->type = type;
00286 if (!(n->execute_tree = apol_bst_create(avrule_node_cmp, free)) ||
00287 !(n->type_transition_tree = apol_bst_create(terule_node_cmp, free))) {
00288 apol_bst_destroy(&n->execute_tree);
00289 apol_bst_destroy(&n->type_transition_tree);
00290 free(n);
00291 return NULL;
00292 }
00293
00294 return n;
00295 }
|
|
|
Definition at line 298 of file domain-trans-analysis.c. References apol_bst_create(), apol_domain_trans_table_t, apol_policy_t, dom_node_cmp(), dom_node_free(), apol_domain_trans_table::domain_table, domain_trans_table_destroy(), apol_domain_trans_table::entrypoint_table, ep_node_cmp(), ep_node_free(), and ERR. Referenced by apol_policy_build_domain_trans_table(). 00299 {
00300 apol_domain_trans_table_t *new_table = NULL;
00301 int error;
00302
00303 if (!policy) {
00304 ERR(policy, "%s", strerror(EINVAL));
00305 errno = EINVAL;
00306 return NULL;
00307 }
00308
00309 new_table = (apol_domain_trans_table_t *) calloc(1, sizeof(apol_domain_trans_table_t));
00310 if (!new_table) {
00311 ERR(policy, "%s", strerror(ENOMEM));
00312 error = ENOMEM;
00313 goto cleanup;
00314 }
00315
00316 if (!(new_table->domain_table = apol_bst_create(dom_node_cmp, dom_node_free))) {
00317 ERR(policy, "%s", strerror(ENOMEM));
00318 error = ENOMEM;
00319 goto cleanup;
00320 }
00321 if (!(new_table->entrypoint_table = apol_bst_create(ep_node_cmp, ep_node_free))) {
00322 ERR(policy, "%s", strerror(ENOMEM));
00323 error = ENOMEM;
00324 goto cleanup;
00325 }
00326
00327 return new_table;
00328 cleanup:
00329 domain_trans_table_destroy(&new_table);
00330 errno = error;
00331 return NULL;
00332 }
|
|
||||||||||||||||
|
Definition at line 334 of file domain-trans-analysis.c. References apol_bst_get_element(), apol_bst_insert(), apol_bst_insert_and_get(), apol_domain_trans_table_t, apol_policy_get_qpol(), apol_policy_t, apol_query_expand_type(), apol_vector_append_unique(), apol_vector_destroy(), apol_vector_get_element(), apol_vector_get_size(), apol_vector_t, avrule_node_create(), avrule_node_t, dom_node_create(), dom_node_free(), dom_node_t, apol_domain_trans_table::domain_table, apol_domain_trans_table::entrypoint_table, ep_node_create(), ep_node_free(), ep_node_t, qpol_avrule_get_perm_iter(), qpol_avrule_get_source_type(), qpol_avrule_get_target_type(), qpol_iterator_destroy(), qpol_iterator_end(), qpol_iterator_get_item(), qpol_iterator_next(), qpol_iterator_t, qpol_policy_t, qpol_type_t, ep_node::type, and dom_node::type. Referenced by apol_policy_build_domain_trans_table(). 00335 {
00336 qpol_policy_t *qp = apol_policy_get_qpol(policy);
00337 const qpol_type_t *src;
00338 const qpol_type_t *tgt;
00339 qpol_avrule_get_source_type(qp, rule, &src);
00340 qpol_avrule_get_target_type(qp, rule, &tgt);
00341 apol_vector_t *sources = apol_query_expand_type(policy, src);
00342 apol_vector_t *targets = apol_query_expand_type(policy, tgt);
00343 bool exec = false, ep = false, proc_trans = false, setexec = false;
00344 qpol_iterator_t *iter = NULL;
00345 int error = 0;
00346 qpol_avrule_get_perm_iter(qp, rule, &iter);
00347 if (!iter || !sources || !targets) {
00348 error = errno;
00349 goto err;
00350 }
00351
00352 for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
00353 void *x;
00354 qpol_iterator_get_item(iter, &x);
00355 char *perm = x;
00356 if (!strcmp("execute", perm))
00357 exec = true;
00358 if (!strcmp("entrypoint", perm))
00359 ep = true;
00360 if (!strcmp("transition", perm))
00361 proc_trans = true;
00362 if (!strcmp("setexec", perm))
00363 setexec = true;
00364 free(x);
00365 }
00366 qpol_iterator_destroy(&iter);
00367
00368 if (proc_trans || ep || setexec) {
00369 for (size_t i = 0; i < apol_vector_get_size(sources); i++) {
00370 dom_node_t *dnode = NULL;
00371 dom_node_t dummy = { apol_vector_get_element(sources, i), NULL, NULL, NULL };
00372 if (apol_bst_get_element(dta_table->domain_table, &dummy, NULL, (void **)&dnode)) {
00373 dom_node_t *new_dnode = NULL;
00374 if (!(new_dnode = dom_node_create(dummy.type)) ||
00375 apol_bst_insert(dta_table->domain_table, (void *)new_dnode, NULL)) {
00376 error = errno;
00377 dom_node_free(new_dnode);
00378 goto err;
00379 }
00380 dnode = new_dnode;
00381 }
00382 if (setexec) {
00383 if (apol_vector_append_unique(dnode->setexec_rules, (void *)rule, NULL, NULL)) {
00384 error = errno;
00385 goto err;
00386 }
00387 }
00388 for (size_t j = 0; j < apol_vector_get_size(targets); j++) {
00389 if (proc_trans) {
00390 avrule_node_t *new_node =
00391 avrule_node_create((const qpol_type_t *)apol_vector_get_element(targets, j), rule);
00392 if (!new_node ||
00393 apol_bst_insert_and_get(dnode->process_transition_tree, (void **)&new_node, NULL) < 0) {
00394 error = errno;
00395 free(new_node);
00396 goto err;
00397 }
00398 }
00399 if (ep) {
00400 avrule_node_t *new_node =
00401 avrule_node_create((const qpol_type_t *)apol_vector_get_element(targets, j), rule);
00402 if (!new_node ||
00403 apol_bst_insert_and_get(dnode->entrypoint_tree, (void **)&new_node, NULL) < 0) {
00404 error = errno;
00405 free(new_node);
00406 goto err;
00407 }
00408 }
00409 }
00410 }
00411 }
00412 if (exec) {
00413 for (size_t i = 0; i < apol_vector_get_size(targets); i++) {
00414 ep_node_t *enode = NULL;
00415 ep_node_t dummy = { apol_vector_get_element(targets, i), NULL, NULL };
00416 if (apol_bst_get_element(dta_table->entrypoint_table, &dummy, NULL, (void **)&enode)) {
00417 ep_node_t *new_enode = NULL;
00418 if (!(new_enode = ep_node_create(dummy.type)) ||
00419 apol_bst_insert(dta_table->entrypoint_table, (void *)new_enode, NULL)) {
00420 error = errno;
00421 ep_node_free(new_enode);
00422 goto err;
00423 }
00424 enode = new_enode;
00425 }
00426 for (size_t j = 0; j < apol_vector_get_size(sources); j++) {
00427 avrule_node_t *new_node =
00428 avrule_node_create((const qpol_type_t *)apol_vector_get_element(sources, j), rule);
00429 if (!new_node || apol_bst_insert_and_get(enode->execute_tree, (void **)&new_node, NULL) < 0) {
00430 error = errno;
00431 free(new_node);
00432 goto err;
00433 }
00434 }
00435 }
00436 }
00437
00438 apol_vector_destroy(&sources);
00439 apol_vector_destroy(&targets);
00440 return 0;
00441
00442 err:
00443 qpol_iterator_destroy(&iter);
00444 apol_vector_destroy(&sources);
00445 apol_vector_destroy(&targets);
00446 errno = error;
00447 return -1;
00448 }
|
|
||||||||||||||||
|
Definition at line 450 of file domain-trans-analysis.c. References apol_bst_get_element(), apol_bst_insert(), apol_bst_insert_and_get(), apol_domain_trans_table_t, apol_policy_get_qpol(), apol_policy_t, apol_query_expand_type(), apol_vector_destroy(), apol_vector_get_element(), apol_vector_get_size(), apol_vector_t, apol_domain_trans_table::entrypoint_table, ep_node_create(), ep_node_free(), ep_node_t, qpol_policy_t, qpol_terule_get_default_type(), qpol_terule_get_source_type(), qpol_terule_get_target_type(), qpol_type_t, terule_node_create(), terule_node_t, and ep_node::type. Referenced by apol_policy_build_domain_trans_table(). 00451 {
00452 qpol_policy_t *qp = apol_policy_get_qpol(policy);
00453 const qpol_type_t *src;
00454 const qpol_type_t *tgt;
00455 const qpol_type_t *dflt;
00456 qpol_terule_get_source_type(qp, rule, &src);
00457 qpol_terule_get_target_type(qp, rule, &tgt);
00458 qpol_terule_get_default_type(qp, rule, &dflt);
00459 apol_vector_t *sources = apol_query_expand_type(policy, src);
00460 apol_vector_t *targets = apol_query_expand_type(policy, tgt);
00461 int error = 0;
00462 for (size_t i = 0; i < apol_vector_get_size(targets); i++) {
00463 ep_node_t *enode = NULL;
00464 ep_node_t dummy = { apol_vector_get_element(targets, i), NULL, NULL };
00465 if (apol_bst_get_element(dta_table->entrypoint_table, &dummy, NULL, (void **)&enode)) {
00466 ep_node_t *new_enode = NULL;
00467 if (!(new_enode = ep_node_create(dummy.type)) ||
00468 apol_bst_insert(dta_table->entrypoint_table, (void *)new_enode, NULL)) {
00469 error = errno;
00470 ep_node_free(new_enode);
00471 goto err;
00472 }
00473 enode = new_enode;
00474 }
00475 for (size_t j = 0; j < apol_vector_get_size(sources); j++) {
00476 terule_node_t *new_node =
00477 terule_node_create((const qpol_type_t *)apol_vector_get_element(sources, j), dflt, rule);
00478 if (apol_bst_insert_and_get(enode->type_transition_tree, (void **)&new_node, NULL) < 0) {
00479 error = errno;
00480 free(new_node);
00481 goto err;
00482 }
00483 }
00484 }
00485
00486 apol_vector_destroy(&sources);
00487 apol_vector_destroy(&targets);
00488 return 0;
00489 err:
00490 apol_vector_destroy(&sources);
00491 apol_vector_destroy(&targets);
00492 errno = error;
00493 return -1;
00494 }
|
|
|
Definition at line 497 of file domain-trans-analysis.c. References apol_domain_trans_result_destroy(), apol_domain_trans_result_t, and apol_vector_create(). Referenced by domain_trans_table_find_orphan_type_transitions(), domain_trans_table_get_all_forward_trans(), and domain_trans_table_get_all_reverse_trans(). 00498 {
00499 apol_domain_trans_result_t *res = calloc(1, sizeof(*res));
00500 if (!res)
00501 return NULL;
00502
00503 int error = 0;
00504 if (!(res->proc_trans_rules = apol_vector_create(NULL)) || !(res->ep_rules = apol_vector_create(NULL)) ||
00505 !(res->exec_rules = apol_vector_create(NULL)) || !(res->setexec_rules = apol_vector_create(NULL)) ||
00506 !(res->type_trans_rules = apol_vector_create(NULL))) {
00507 error = errno;
00508 goto err;
00509 }
00510
00511 return res;
00512 err:
00513 apol_domain_trans_result_destroy(&res);
00514 errno = error;
00515 return NULL;
00516 }
|
|
|
Build the table of domain transitions for a policy if not already built.
Definition at line 520 of file domain-trans-analysis.c. References apol_avrule_get_by_query(), apol_avrule_query_append_class(), apol_avrule_query_append_perm(), apol_avrule_query_create(), apol_avrule_query_destroy(), apol_avrule_query_set_rules(), apol_avrule_query_t, apol_domain_trans_table_new(), apol_domain_trans_table_t, apol_policy_t, apol_terule_get_by_query(), apol_terule_query_append_class(), apol_terule_query_create(), apol_terule_query_destroy(), apol_terule_query_set_rules(), apol_terule_query_t, apol_vector_destroy(), apol_vector_get_element(), apol_vector_get_size(), apol_vector_t, apol_policy::domain_trans_table, domain_trans_table_destroy(), ERR, qpol_avrule_t, QPOL_RULE_ALLOW, QPOL_RULE_TYPE_TRANS, qpol_terule_t, table_add_avrule(), and table_add_terule(). Referenced by apol_domain_trans_analysis_do(), apol_policy_domain_trans_table_build(), apol_types_relation_domain(), dta_init(), and inc_dom_trans_run(). 00521 {
00522 int error = 0;
00523 apol_avrule_query_t *avq = NULL;
00524 apol_terule_query_t *teq = NULL;
00525 apol_vector_t *avrules = NULL;
00526 apol_vector_t *terules = NULL;
00527
00528 if (!policy) {
00529 ERR(policy, "%s", strerror(EINVAL));
00530 errno = EINVAL;
00531 return -1;
00532 }
00533
00534 if (policy->domain_trans_table) {
00535 return 0; /* already built */
00536 }
00537
00538 apol_domain_trans_table_t *dta_table = policy->domain_trans_table = apol_domain_trans_table_new(policy);
00539 if (!policy->domain_trans_table) {
00540 error = errno;
00541 goto err;
00542 }
00543
00544 avq = apol_avrule_query_create();
00545 apol_avrule_query_set_rules(policy, avq, QPOL_RULE_ALLOW);
00546 apol_avrule_query_append_class(policy, avq, "file");
00547 apol_avrule_query_append_class(policy, avq, "process");
00548 apol_avrule_query_append_perm(policy, avq, "execute");
00549 apol_avrule_query_append_perm(policy, avq, "entrypoint");
00550 apol_avrule_query_append_perm(policy, avq, "transition");
00551 apol_avrule_query_append_perm(policy, avq, "setexec");
00552 if (apol_avrule_get_by_query(policy, avq, &avrules)) {
00553 error = errno;
00554 goto err;
00555 }
00556 apol_avrule_query_destroy(&avq);
00557 for (size_t i = 0; i < apol_vector_get_size(avrules); i++) {
00558 if (table_add_avrule(policy, dta_table, (const qpol_avrule_t *)apol_vector_get_element(avrules, i))) {
00559 error = errno;
00560 goto err;
00561 }
00562 }
00563 apol_vector_destroy(&avrules);
00564
00565 teq = apol_terule_query_create();
00566 apol_terule_query_set_rules(policy, teq, QPOL_RULE_TYPE_TRANS);
00567 apol_terule_query_append_class(policy, teq, "process");
00568 if (apol_terule_get_by_query(policy, teq, &terules)) {
00569 error = errno;
00570 goto err;
00571 }
00572 apol_terule_query_destroy(&teq);
00573 for (size_t i = 0; i < apol_vector_get_size(terules); i++) {
00574 if (table_add_terule(policy, dta_table, (const qpol_terule_t *)apol_vector_get_element(terules, i))) {
00575 error = errno;
00576 goto err;
00577 }
00578 }
00579 apol_vector_destroy(&terules);
00580
00581 return 0;
00582
00583 err:
00584 apol_avrule_query_destroy(&avq);
00585 apol_vector_destroy(&avrules);
00586 apol_terule_query_destroy(&teq);
00587 apol_vector_destroy(&terules);
00588 domain_trans_table_destroy(&dta_table);
00589 policy->domain_trans_table = NULL;
00590 errno = error;
00591 return -1;
00592 }
|
|
|
Definition at line 594 of file domain-trans-analysis.c. References apol_policy_build_domain_trans_table(), and apol_policy_t. 00595 {
00596 return apol_policy_build_domain_trans_table(policy);
00597 }
|
|
|
Destroy the domain transition table freeing all memory used.
Definition at line 599 of file domain-trans-analysis.c. References apol_bst_destroy(), and apol_domain_trans_table_t. Referenced by apol_domain_trans_table_new(), apol_policy_build_domain_trans_table(), and apol_policy_destroy(). 00600 {
00601 if (!table || !(*table))
00602 return;
00603
00604 apol_bst_destroy(&(*table)->domain_table);
00605 apol_bst_destroy(&(*table)->entrypoint_table);
00606 free(*table);
00607 *table = NULL;
00608 }
|
|
|
Reset the state of the domain transition table in a policy. This is needed because by default subsequent calls to apol_domain_trans_analysis_do() will not produce results generated in a previous call. If calls are to be considered independent or calls in a different direction are desired, call this function prior to apol_domain_trans_analysis_do(). If the table was not built yet then this function does nothing.
Definition at line 610 of file domain-trans-analysis.c. References apol_bst_inorder_map(), apol_policy_t, dom_node_reset(), apol_domain_trans_table::domain_table, apol_policy::domain_trans_table, apol_domain_trans_table::entrypoint_table, and ep_node_reset(). Referenced by apol_domain_trans_table_reset(), apol_domain_trans_table_verify_trans(), apol_types_relation_domain(), dta_forward(), dta_forward_access(), dta_forward_multi_end(), dta_invalid(), dta_reflexive(), dta_reverse(), dta_reverse_regexp(), and unreachable_doms_run(). 00611 {
00612 if (!policy || !policy->domain_trans_table)
00613 return;
00614 apol_bst_inorder_map(policy->domain_trans_table->domain_table, dom_node_reset, NULL);
00615 apol_bst_inorder_map(policy->domain_trans_table->entrypoint_table, ep_node_reset, NULL);
00616 return;
00617 }
|
|
|
Definition at line 619 of file domain-trans-analysis.c. References apol_policy_reset_domain_trans_table(), and apol_policy_t. 00620 {
00621 apol_policy_reset_domain_trans_table(policy);
00622 }
|
|
|
Allocate and return a new domain transition analysis structure. All fields are cleared; one must fill in the details of the analysis before running it. The caller must call apol_domain_trans_analysis_destroy() upon the return value afterwards.
Definition at line 625 of file domain-trans-analysis.c. References apol_domain_trans_analysis_destroy(), apol_domain_trans_analysis_t, and apol_domain_trans_analysis::valid. Referenced by apol_types_relation_domain(), dta_forward(), dta_forward_access(), dta_forward_multi_end(), dta_invalid(), dta_reflexive(), dta_reverse(), dta_reverse_regexp(), inc_dom_trans_run(), and unreachable_doms_run(). 00626 {
00627 apol_domain_trans_analysis_t *new_dta = NULL;
00628 int error = 0;
00629
00630 if (!(new_dta = calloc(1, sizeof(apol_domain_trans_analysis_t)))) {
00631 error = errno;
00632 goto err;
00633 }
00634
00635 new_dta->valid = APOL_DOMAIN_TRANS_SEARCH_VALID; /* by default search only valid transitions */
00636
00637 return new_dta;
00638
00639 err:
00640 apol_domain_trans_analysis_destroy(&new_dta);
00641 errno = error;
00642 return NULL;
00643 }
|
|
|
Deallocate all memory associated with the referenced domain transition analysis structure, and then set it to NULL. This function does nothing if the analysis is already NULL.
Definition at line 645 of file domain-trans-analysis.c. References apol_domain_trans_analysis_t, apol_regex_destroy(), and apol_vector_destroy(). Referenced by apol_domain_trans_analysis_create(), apol_types_relation_domain(), dta_forward(), dta_forward_access(), dta_forward_multi_end(), dta_invalid(), dta_reflexive(), dta_reverse(), dta_reverse_regexp(), inc_dom_trans_run(), and unreachable_doms_run(). 00646 {
00647 if (!dta || !(*dta))
00648 return;
00649
00650 free((*dta)->start_type);
00651 free((*dta)->result);
00652 apol_vector_destroy(&((*dta)->access_types));
00653 apol_vector_destroy(&((*dta)->access_classes));
00654 apol_vector_destroy(&((*dta)->access_perms));
00655 apol_regex_destroy(&((*dta)->result_regex));
00656 free(*dta);
00657 *dta = NULL;
00658 }
|
|
||||||||||||||||
|
Set the direction of the transitions with respect to the start type. Must be either APOL_DOMAIN_TRANS_DIRECTION_FORWARD or APOL_DOMAIN_TRANS_DIRECTION_REVERSE.
Definition at line 660 of file domain-trans-analysis.c. References apol_domain_trans_analysis_t, APOL_DOMAIN_TRANS_DIRECTION_FORWARD, apol_policy_t, apol_domain_trans_analysis::direction, and ERR. Referenced by apol_types_relation_domain(), dta_forward(), dta_forward_access(), dta_forward_multi_end(), dta_invalid(), dta_reflexive(), dta_reverse(), dta_reverse_regexp(), inc_dom_trans_run(), and unreachable_doms_run(). 00662 {
00663 if (!dta || (direction != APOL_DOMAIN_TRANS_DIRECTION_FORWARD && direction != APOL_DOMAIN_TRANS_DIRECTION_REVERSE)) {
00664 ERR(policy, "Error setting analysis direction: %s", strerror(EINVAL));
00665 errno = EINVAL;
00666 return -1;
00667 }
00668
00669 dta->direction = direction;
00670
00671 return 0;
00672 }
|
|
||||||||||||||||
|
Set the analysis to search for transitions based upon whether they would be permitted. The value must be one of APOL_DOMAIN_TRANS_SEARCH_* defined above. The default for a newly created analysis is to search for only valid transitions (i.e. APOL_DOMAIN_TRANS_SEARCH_VALID).
Definition at line 674 of file domain-trans-analysis.c. References apol_domain_trans_analysis_t, apol_policy_t, ERR, and apol_domain_trans_analysis::valid. Referenced by dta_invalid(), inc_dom_trans_run(), and unreachable_doms_run(). 00675 {
00676 if (!dta || valid & ~(APOL_DOMAIN_TRANS_SEARCH_BOTH)) {
00677 ERR(policy, "Error setting analysis validity flag: %s", strerror(EINVAL));
00678 errno = EINVAL;
00679 return -1;
00680 }
00681
00682 dta->valid = valid;
00683
00684 return 0;
00685 }
|
|
||||||||||||||||
|
Set the analysis to begin searching using a given type. This function must be called prior to running the analysis. If a previous type was set, it will be free()'d first.
Definition at line 687 of file domain-trans-analysis.c. References apol_domain_trans_analysis_t, apol_policy_t, ERR, and apol_domain_trans_analysis::start_type. Referenced by apol_types_relation_domain(), dta_forward(), dta_forward_access(), dta_forward_multi_end(), dta_invalid(), dta_reflexive(), dta_reverse(), dta_reverse_regexp(), inc_dom_trans_run(), and unreachable_doms_run(). 00689 {
00690 char *tmp = NULL;
00691 int error = 0;
00692
00693 if (!dta || !type_name) {
00694 ERR(policy, "%s", strerror(EINVAL));
00695 errno = EINVAL;
00696 return -1;
00697 }
00698
00699 if (!(tmp = strdup(type_name))) {
00700 error = errno;
00701 ERR(policy, "%s", strerror(error));
00702 errno = error;
00703 return -1;
00704 }
00705
00706 free(dta->start_type);
00707 dta->start_type = tmp;
00708
00709 return 0;
00710 }
|
|
||||||||||||||||
|
Set the analysis to return only types matching a regular expression. Note that the regular expression will also match types' aliases.
Definition at line 712 of file domain-trans-analysis.c. References apol_domain_trans_analysis_t, apol_policy_t, apol_query_set(), apol_regex_destroy(), ERR, apol_domain_trans_analysis::result, and apol_domain_trans_analysis::result_regex. Referenced by dta_reverse_regexp(). 00713 {
00714 if (!dta) {
00715 ERR(policy, "%s", strerror(EINVAL));
00716 errno = EINVAL;
00717 return -1;
00718 }
00719
00720 if (!regex) {
00721 apol_regex_destroy(&dta->result_regex);
00722 return 0;
00723 }
00724
00725 return apol_query_set(policy, &dta->result, &dta->result_regex, regex);
00726 }
|
|
||||||||||||||||
|
Set the analysis to return only types having access (via allow rules) to this type. This is only valid for forward analysis. If more than one type is appended to the query, the resulting type must have access to at least one of the appended types. Pass a NULL to clear all previously appended types. If access types are appended, the caller must also call apol_domain_trans_analysis_append_class() at least once with a valid class and apol_domain_trans_analysis_append_perm() at least once with a valid permission.
Definition at line 728 of file domain-trans-analysis.c. References apol_domain_trans_analysis::access_types, apol_domain_trans_analysis_t, apol_policy_t, apol_vector_append(), apol_vector_create(), apol_vector_destroy(), and ERR. Referenced by dta_forward_access(). 00730 {
00731 char *tmp = NULL;
00732 int error = 0;
00733
00734 if (!dta) {
00735 ERR(policy, "Error appending type to analysis: %s", strerror(EINVAL));
00736 errno = EINVAL;
00737 return -1;
00738 }
00739
00740 if (!type_name) {
00741 apol_vector_destroy(&dta->access_types);
00742 return 0;
00743 }
00744
00745 if (!dta->access_types) {
00746 if (!(dta->access_types = apol_vector_create(free))) {
00747 error = errno;
00748 ERR(policy, "%s", strerror(error));
00749 errno = error;
00750 return -1;
00751 }
00752 }
00753
00754 if (!(tmp = strdup(type_name))) {
00755 error = errno;
00756 ERR(policy, "%s", strerror(error));
00757 errno = error;
00758 return -1;
00759 }
00760
00761 if (apol_vector_append(dta->access_types, tmp)) {
00762 error = errno;
00763 free(tmp);
00764 ERR(policy, "%s", strerror(error));
00765 errno = error;
00766 return -1;
00767 }
00768
00769 return 0;
00770 }
|
|
||||||||||||||||||||
|
Set the analysis to return only types having access (via allow rules) to this class with the given permission. This is only valid for forward analysis. If more than one class is appended to the query, the resulting type must have access to at least one of the appended classes. If more than one permission is appended for the same class, the resulting type must have at least one of the appended permissions for that class. Pass a NULL to both strings to clear all previously appended classes and permissions. If access classes and permissions are appended, the caller must also call apol_domain_trans_analysis_append_access_type() at least once with a valid type.
Definition at line 772 of file domain-trans-analysis.c. References apol_domain_trans_analysis_append_class(), apol_domain_trans_analysis_append_perm(), apol_domain_trans_analysis_t, and apol_policy_t. 00774 {
00775 if (apol_domain_trans_analysis_append_class(policy, dta, class_name))
00776 return -1;
00777 return apol_domain_trans_analysis_append_perm(policy, dta, perm_name);
00778 }
|
|
||||||||||||||||
|
Set the analysis to return only types having access (via allow rules) to this class. This is only valid for forward analysis. If more than one class is appended to the query, the resulting type must have access to at least one of the appended classes. Pass a NULL to clear all previously appended classes. If access classes are appended, the caller must also call apol_domain_trans_analysis_append_access_type() at least once with a valid type and apol_domain_trans_analysis_append_perm() with a valid permission.
Definition at line 780 of file domain-trans-analysis.c. References apol_domain_trans_analysis::access_classes, apol_domain_trans_analysis_t, apol_policy_t, apol_vector_append(), apol_vector_create(), apol_vector_destroy(), and ERR. Referenced by apol_domain_trans_analysis_append_class_perm(), and dta_forward_access(). 00782 {
00783 char *tmp = NULL;
00784 int error = 0;
00785
00786 if (!dta) {
00787 ERR(policy, "Error appending class to analysis: %s", strerror(EINVAL));
00788 errno = EINVAL;
00789 return -1;
00790 }
00791
00792 if (!class_name) {
00793 apol_vector_destroy(&dta->access_classes);
00794 return 0;
00795 }
00796
00797 if (!dta->access_classes) {
00798 if (!(dta->access_classes = apol_vector_create(free))) {
00799 error = errno;
00800 ERR(policy, "%s", strerror(error));
00801 errno = error;
00802 return -1;
00803 }
00804 }
00805
00806 if (!(tmp = strdup(class_name))) {
00807 error = errno;
00808 ERR(policy, "%s", strerror(error));
00809 errno = error;
00810 return -1;
00811 }
00812
00813 if (apol_vector_append(dta->access_classes, tmp)) {
00814 error = errno;
00815 free(tmp);
00816 ERR(policy, "%s", strerror(error));
00817 errno = error;
00818 return -1;
00819 }
00820
00821 return 0;
00822 }
|
|
||||||||||||||||
|
Set the analysis to return only types having access (via allow rules) to this permission. This is only valid for forward analysis. If more than one permission is appended the resulting type must have at least one of the appended permissions. Pass a NULL to clear all previously appended permissions. If access permissions are appended, the caller must also call apol_domain_trans_analysis_append_access_type() at least once with a valid type and apol_domain_trans_analysis_append_class() at least once with a valid class.
Definition at line 824 of file domain-trans-analysis.c. References apol_domain_trans_analysis::access_perms, apol_domain_trans_analysis_t, apol_policy_t, apol_vector_append(), apol_vector_create(), apol_vector_destroy(), and ERR. Referenced by apol_domain_trans_analysis_append_class_perm(), and dta_forward_access(). 00825 {
00826 char *tmp = NULL;
00827 int error = 0;
00828
00829 if (!dta) {
00830 ERR(policy, "Error appending perm to analysis: %s", strerror(EINVAL));
00831 errno = EINVAL;
00832 return -1;
00833 }
00834
00835 if (!perm_name) {
00836 apol_vector_destroy(&dta->access_perms);
00837 return 0;
00838 }
00839
00840 if (!dta->access_perms) {
00841 if (!(dta->access_perms = apol_vector_create(free))) {
00842 error = errno;
00843 ERR(policy, "%s", strerror(error));
00844 errno = error;
00845 return -1;
00846 }
00847 }
00848
00849 if (!(tmp = strdup(perm_name))) {
00850 error = errno;
00851 ERR(policy, "%s", strerror(error));
00852 errno = error;
00853 return -1;
00854 }
00855
00856 if (apol_vector_append(dta->access_perms, tmp)) {
00857 error = errno;
00858 free(tmp);
00859 ERR(policy, "%s", strerror(error));
00860 errno = error;
00861 return -1;
00862 }
00863
00864 return 0;
00865 }
|
|
|
Definition at line 867 of file domain-trans-analysis.c. References apol_policy_get_qpol(), apol_policy_t, apol_policy::p, QPOL_CAP_MODULES, qpol_policy_get_policy_version(), qpol_policy_has_capability(), and qpol_policy_t. Referenced by apol_domain_trans_table_verify_trans(), domain_trans_table_get_all_forward_trans(), and domain_trans_table_get_all_reverse_trans(). 00868 {
00869 const qpol_policy_t *qp = apol_policy_get_qpol(policy);
00870 unsigned int policy_version = 0;
00871 qpol_policy_get_policy_version(qp, &policy_version);
00872 int is_modular = qpol_policy_has_capability(policy->p, QPOL_CAP_MODULES);
00873 return (policy_version >= 15 || is_modular);
00874 }
|
|
||||||||||||
|
Definition at line 884 of file domain-trans-analysis.c. References apol_vector_append(), avrule_node_t, terule_node::dflt, rule_map_data::dflt, rule_map_data::is_avnode, rule_map_data::node_list, rule_map_data::search, terule_node::src, terule_node_t, avrule_node::type, terule_node::used, and avrule_node::used. Referenced by find_avrules_in_node(), and find_terules_in_node(). 00885 {
00886 struct rule_map_data *rm = data;
00887 if (rm->is_avnode) {
00888 avrule_node_t *anode = node;
00889 if (anode->type == rm->search && !anode->used)
00890 if (apol_vector_append(rm->node_list, node))
00891 return -1;
00892 return 0;
00893 } else {
00894 terule_node_t *tnode = node;
00895 if ((!rm->search || (rm->search == tnode->src)) && (!rm->dflt || (rm->dflt == tnode->dflt)) &&
00896 rm->search != rm->dflt && !tnode->used)
00897 if (apol_vector_append(rm->node_list, node))
00898 return -1;
00899 return 0;
00900 }
00901 }
|
|
||||||||||||||||
|
Definition at line 903 of file domain-trans-analysis.c. References apol_bst_inorder_map(), APOL_DOMAIN_TRANS_RULE_ENTRYPOINT, APOL_DOMAIN_TRANS_RULE_EXEC, APOL_DOMAIN_TRANS_RULE_PROC_TRANS, apol_vector_create(), apol_vector_destroy(), apol_vector_t, dom_node_t, dom_node::entrypoint_tree, ep_node_t, ep_node::execute_tree, node_list_map_fn(), and dom_node::process_transition_tree. Referenced by apol_domain_trans_table_verify_trans(), domain_trans_table_find_orphan_type_transitions(), domain_trans_table_get_all_forward_trans(), and domain_trans_table_get_all_reverse_trans(). 00904 {
00905 int error = 0;
00906 apol_vector_t *rule_nodes = apol_vector_create(NULL); //shallow copies only
00907 struct rule_map_data data = { search, NULL, rule_nodes, true };
00908 switch (rule_type) {
00909 case APOL_DOMAIN_TRANS_RULE_PROC_TRANS:
00910 {
00911 dom_node_t *dnode = node;
00912 if (apol_bst_inorder_map(dnode->process_transition_tree, node_list_map_fn, (void *)&data) < 0) {
00913 error = errno;
00914 goto err;
00915 }
00916 break;
00917 }
00918 case APOL_DOMAIN_TRANS_RULE_ENTRYPOINT:
00919 {
00920 dom_node_t *dnode = node;
00921 if (apol_bst_inorder_map(dnode->entrypoint_tree, node_list_map_fn, (void *)&data) < 0) {
00922 error = errno;
00923 goto err;
00924 }
00925 break;
00926 }
00927 case APOL_DOMAIN_TRANS_RULE_EXEC:
00928 {
00929 ep_node_t *enode = node;
00930 if (apol_bst_inorder_map(enode->execute_tree, node_list_map_fn, (void *)&data) < 0) {
00931 error = errno;
00932 goto err;
00933 }
00934 break;
00935 }
00936 default:
00937 {
00938 error = EINVAL;
00939 goto err;
00940 }
00941 }
00942
00943 return rule_nodes;
00944
00945 err:
00946 apol_vector_destroy(&rule_nodes);
00947 errno = error;
00948 return NULL;
00949 }
|
|
||||||||||||||||
|
Definition at line 951 of file domain-trans-analysis.c. References apol_bst_inorder_map(), apol_vector_create(), apol_vector_destroy(), apol_vector_t, ep_node_t, node_list_map_fn(), and ep_node::type_transition_tree. Referenced by apol_domain_trans_table_verify_trans(), domain_trans_table_find_orphan_type_transitions(), domain_trans_table_get_all_forward_trans(), and domain_trans_table_get_all_reverse_trans(). 00952 {
00953 int error = 0;
00954 apol_vector_t *rule_nodes = apol_vector_create(NULL); //shallow copies only
00955 struct rule_map_data data = { search, dflt, rule_nodes, false };
00956 if (apol_bst_inorder_map(node->type_transition_tree, node_list_map_fn, (void *)&data) < 0) {
00957 error = errno;
00958 goto err;
00959 }
00960
00961 return rule_nodes;
00962
00963 err:
00964 apol_vector_destroy(&rule_nodes);
00965 errno = error;
00966 return NULL;
00967 }
|
|
||||||||||||||||||||
|
Definition at line 969 of file domain-trans-analysis.c. References apol_domain_trans_result_t, apol_vector_get_element(), apol_vector_get_size(), apol_vector_t, apol_domain_trans_result::end_type, apol_domain_trans_result::ep_type, and apol_domain_trans_result::start_type. Referenced by domain_trans_table_find_orphan_type_transitions(). 00971 {
00972 for (size_t i = 0; i < apol_vector_get_size(local_results); i++) {
00973 apol_domain_trans_result_t *res = apol_vector_get_element(local_results, i);
00974 if (res->start_type == src && res->end_type == dflt && res->ep_type == tgt)
00975 return res;
00976 }
00977 return NULL;
00978 }
|
|
||||||||||||||||
|
Definition at line 980 of file domain-trans-analysis.c. References apol_bst_get_element(), apol_bst_get_vector(), apol_domain_trans_analysis_t, apol_domain_trans_result_destroy(), apol_domain_trans_result_t, APOL_DOMAIN_TRANS_RULE_EXEC, APOL_DOMAIN_TRANS_RULE_PROC_TRANS, apol_policy_get_qpol(), apol_policy_t, apol_vector_append(), apol_vector_cat(), apol_vector_destroy(), apol_vector_get_element(), apol_vector_get_size(), apol_vector_sort_uniquify(), apol_vector_t, avrule_node_t, terule_node::dflt, apol_domain_trans_analysis::direction, dom_node_t, apol_domain_trans_table::domain_table, domain_trans_result_create(), apol_policy::domain_trans_table, apol_domain_trans_result::end_type, apol_domain_trans_table::entrypoint_table, ep_node_t, apol_domain_trans_result::ep_type, apol_domain_trans_result::exec_rules, find_avrules_in_node(), find_result(), find_terules_in_node(), apol_domain_trans_result::proc_trans_rules, qpol_policy_get_type_by_name(), qpol_type_t, avrule_node::rule, apol_domain_trans_result::setexec_rules, terule_node::src, apol_domain_trans_result::start_type, apol_domain_trans_analysis::start_type, terule_node_t, ep_node::type, and terule_node::used. Referenced by domain_trans_table_get_all_forward_trans(), and domain_trans_table_get_all_reverse_trans(). 00982 {
00983 int error = 0;
00984 const qpol_type_t *search = NULL;
00985 qpol_policy_get_type_by_name(apol_policy_get_qpol(policy), dta->start_type, &search);
00986 apol_domain_trans_result_t *tmp_result = NULL;
00987 //walk ep table
00988 apol_vector_t *epnodes = apol_bst_get_vector(policy->domain_trans_table->entrypoint_table, 0);
00989 if (!epnodes)
00990 return -1;
00991 for (size_t i = 0; i < apol_vector_get_size(epnodes); i++) {
00992 ep_node_t *node = apol_vector_get_element(epnodes, i);
00993 //find any unused type transitions
00994 apol_vector_t *ttnodes = NULL;
00995 if (dta->direction == APOL_DOMAIN_TRANS_DIRECTION_FORWARD)
00996 ttnodes = find_terules_in_node(node, search, NULL);
00997 else
00998 ttnodes = find_terules_in_node(node, NULL, search);
00999 for (size_t j = 0; j < apol_vector_get_size(ttnodes); j++) {
01000 bool add = false;
01001 terule_node_t *tn = apol_vector_get_element(ttnodes, j);
01002 tn->used = true;
01003 //if missing an entrypoint rule this transition may have already been added to the results
01004 tmp_result = find_result(local_results, tn->src, node->type, tn->dflt);
01005 if (!tmp_result) {
01006 add = true;
01007 tmp_result = domain_trans_result_create();
01008 }
01009 if (!tmp_result) {
01010 error = errno;
01011 apol_vector_destroy(&ttnodes);
01012 goto err;
01013 }
01014 tmp_result->start_type = tn->src;
01015 tmp_result->end_type = tn->dflt;
01016 tmp_result->ep_type = node->type;
01017 //check for exec
01018 apol_vector_t *execrules =
01019 find_avrules_in_node((void *)node, APOL_DOMAIN_TRANS_RULE_EXEC, tmp_result->start_type);
01020 for (size_t k = 0; k < apol_vector_get_size(execrules); k++) {
01021 avrule_node_t *n = apol_vector_get_element(execrules, k);
01022 if (apol_vector_append(tmp_result->exec_rules, (void *)n->rule)) {
01023 error = errno;
01024 apol_vector_destroy(&execrules);
01025 if (!add)
01026 tmp_result = NULL;
01027 goto err;
01028 }
01029 }
01030 apol_vector_destroy(&execrules);
01031 //check for proc_trans and setexec
01032 dom_node_t dummy = { tmp_result->start_type, NULL, NULL, NULL };
01033 dom_node_t *start_node = NULL;
01034 apol_bst_get_element(policy->domain_trans_table->domain_table, (void *)&dummy, NULL, (void **)&start_node);
01035 if (start_node) {
01036 //only copy setexec_rules if a new result will be added
01037 if (add && apol_vector_get_size(start_node->setexec_rules)) {
01038 if (apol_vector_cat(tmp_result->setexec_rules, start_node->setexec_rules)) {
01039 error = errno;
01040 goto err;
01041 }
01042 }
01043 //add any unused proc_trans rules
01044 apol_vector_t *proc_trans_rules =
01045 find_avrules_in_node((void *)start_node, APOL_DOMAIN_TRANS_RULE_PROC_TRANS,
01046 tmp_result->end_type);
01047 for (size_t k = 0; k < apol_vector_get_size(proc_trans_rules); k++) {
01048 avrule_node_t *avr = apol_vector_get_element(proc_trans_rules, k);
01049 if (apol_vector_append(tmp_result->proc_trans_rules, (void *)avr->rule)) {
01050 error = errno;
01051 if (!add)
01052 tmp_result = NULL;
01053 apol_vector_destroy(&proc_trans_rules);
01054 goto err;
01055 }
01056 }
01057 apol_vector_destroy(&proc_trans_rules);
01058 apol_vector_sort_uniquify(tmp_result->proc_trans_rules, NULL, NULL);
01059 }
01060 if (add) {
01061 if (apol_vector_append(local_results, (void *)tmp_result)) {
01062 error = errno;
01063 goto err;
01064 }
01065 }
01066 tmp_result = NULL;
01067 }
01068 apol_vector_destroy(&ttnodes);
01069 }
01070 apol_vector_destroy(&epnodes);
01071
01072 return 0;
01073
01074 err:
01075 apol_vector_destroy(&epnodes);
01076 apol_domain_trans_result_destroy(&tmp_result);
01077 errno = error;
01078 return -1;
01079 }
|
|
||||||||||||||||||||
|
Definition at line 1081 of file domain-trans-analysis.c. References apol_bst_get_element(), apol_bst_get_vector(), apol_domain_trans_analysis_t, apol_domain_trans_result_create_from_domain_trans_result(), apol_domain_trans_result_destroy(), apol_domain_trans_result_t, APOL_DOMAIN_TRANS_RULE_ENTRYPOINT, APOL_DOMAIN_TRANS_RULE_EXEC, APOL_DOMAIN_TRANS_RULE_PROC_TRANS, apol_policy_t, apol_vector_append(), apol_vector_cat(), apol_vector_create(), apol_vector_destroy(), apol_vector_get_element(), apol_vector_get_size(), apol_vector_sort_uniquify(), apol_vector_t, avrule_node_t, dom_node_t, apol_domain_trans_table::domain_table, domain_trans_result_create(), apol_policy::domain_trans_table, domain_trans_table_find_orphan_type_transitions(), apol_domain_trans_result::end_type, apol_domain_trans_table::entrypoint_table, ep_node_t, apol_domain_trans_result::ep_rules, apol_domain_trans_result::ep_type, apol_domain_trans_result::exec_rules, find_avrules_in_node(), find_terules_in_node(), apol_domain_trans_result::proc_trans_rules, qpol_type_t, requires_setexec_or_type_trans(), terule_node::rule, avrule_node::rule, apol_domain_trans_result::setexec_rules, apol_domain_trans_result::start_type, terule_node_t, avrule_node::type, apol_domain_trans_result::type_trans_rules, avrule_node::used, apol_domain_trans_analysis::valid, and apol_domain_trans_result::valid. Referenced by apol_domain_trans_analysis_do(). 01083 {
01084 int error = 0;
01085 //create template result this will hold common data for each step and be copied as needed
01086 apol_domain_trans_result_t *tmpl_result = domain_trans_result_create();
01087 if (!tmpl_result) {
01088 error = errno;
01089 goto err;
01090 }
01091 //find start node
01092 dom_node_t dummy = { start_type, NULL, NULL, NULL };
01093 dom_node_t *start_node = NULL;
01094 apol_bst_get_element(policy->domain_trans_table->domain_table, (void *)&dummy, NULL, (void **)&start_node);
01095 if (start_node) {
01096 tmpl_result->start_type = start_type;
01097 //if needed and present record setexec
01098 if (requires_setexec_or_type_trans(policy) && apol_vector_get_size(start_node->setexec_rules)) {
01099 if (apol_vector_cat(tmpl_result->setexec_rules, start_node->setexec_rules)) {
01100 error = errno;
01101 goto err;
01102 }
01103 }
01104 //check all proc trans to build list of end types
01105 apol_vector_t *proc_trans_rules = apol_bst_get_vector(start_node->process_transition_tree, 0);
01106 apol_vector_t *potential_end_types = apol_vector_create(NULL);
01107 for (size_t i = 0; i < apol_vector_get_size(proc_trans_rules); i++) {
01108 avrule_node_t *ptnode = apol_vector_get_element(proc_trans_rules, i);
01109 apol_vector_append(potential_end_types, (void *)ptnode->type);
01110 }
01111 apol_vector_destroy(&proc_trans_rules);
01112 apol_vector_sort_uniquify(potential_end_types, NULL, NULL);
01113 //for each end check ep
01114 for (size_t i = 0; i < apol_vector_get_size(potential_end_types); i++) {
01115 dummy.type = tmpl_result->end_type = apol_vector_get_element(potential_end_types, i);
01116 dom_node_t *end_node = NULL;
01117 apol_bst_get_element(policy->domain_trans_table->domain_table, (void *)&dummy, NULL, (void **)&end_node);
01118 const qpol_type_t *end_type = dummy.type;
01119 if (end_type == start_type)
01120 continue;
01121 //get all proc trans rules for ths end (may be multiple due to attributes)
01122 apol_vector_t *ptrules =
01123 find_avrules_in_node((void *)start_node, APOL_DOMAIN_TRANS_RULE_PROC_TRANS, end_type);
01124 apol_vector_destroy(&tmpl_result->proc_trans_rules);
01125 tmpl_result->proc_trans_rules = apol_vector_create(NULL);
01126 for (size_t j = 0; j < apol_vector_get_size(ptrules); j++) {
01127 avrule_node_t *pt_ent = apol_vector_get_element(ptrules, j);
01128 pt_ent->used = true;
01129 if (apol_vector_append(tmpl_result->proc_trans_rules, (void *)pt_ent->rule)) {
01130 error = errno;
01131 apol_vector_destroy(&ptrules);
01132 apol_vector_destroy(&potential_end_types);
01133 goto err;
01134 }
01135 }
01136 apol_vector_destroy(&ptrules);
01137 apol_vector_sort_uniquify(tmpl_result->proc_trans_rules, NULL, NULL);
01138 if (end_node) {
01139 //collect potential entrypoint types
01140 apol_vector_t *eprules = apol_bst_get_vector(end_node->entrypoint_tree, 0);
01141 apol_vector_t *potential_ep_types = apol_vector_create(NULL);
01142 if (!eprules || !potential_ep_types) {
01143 error = errno;
01144 apol_vector_destroy(&eprules);
01145 apol_vector_destroy(&potential_end_types);
01146 goto err;
01147 }
01148 for (size_t j = 0; j < apol_vector_get_size(eprules); j++) {
01149 avrule_node_t *epr = apol_vector_get_element(eprules, j);
01150 if (apol_vector_append(potential_ep_types, (void *)epr->type)) {
01151 error = errno;
01152 apol_vector_destroy(&eprules);
01153 apol_vector_destroy(&potential_end_types);
01154 apol_vector_destroy(&potential_ep_types);
01155 goto err;
01156 }
01157 }
01158 apol_vector_destroy(&eprules);
01159 apol_vector_sort_uniquify(potential_ep_types, NULL, NULL);
01160 //for each ep find exec by start
01161 for (size_t j = 0; j < apol_vector_get_size(potential_ep_types); j++) {
01162 tmpl_result->ep_type = apol_vector_get_element(potential_ep_types, j);
01163 ep_node_t edummy =
01164 { (const qpol_type_t *)apol_vector_get_element(potential_ep_types, j), NULL, NULL };
01165 ep_node_t *epnode = NULL;
01166 apol_bst_get_element(policy->domain_trans_table->entrypoint_table, (void *)&edummy, NULL,
01167 (void **)&epnode);
01168 //get all entrypoint rules for ths end (may be multiple due to attributes)
01169 apol_vector_destroy(&tmpl_result->ep_rules);
01170 tmpl_result->ep_rules = apol_vector_create(NULL);
01171 if (!tmpl_result->ep_rules) {
01172 error = errno;
01173 apol_vector_destroy(&potential_end_types);
01174 apol_vector_destroy(&potential_ep_types);
01175 goto err;
01176 }
01177 eprules = find_avrules_in_node((void *)end_node, APOL_DOMAIN_TRANS_RULE_ENTRYPOINT,
01178 tmpl_result->ep_type);
01179 for (size_t k = 0; k < apol_vector_get_size(eprules); k++) {
01180 avrule_node_t *ep_ent = apol_vector_get_element(eprules, k);
01181 ep_ent->used = true;
01182 if (apol_vector_append(tmpl_result->ep_rules, (void *)ep_ent->rule)) {
01183 error = errno;
01184 apol_vector_destroy(&eprules);
01185 apol_vector_destroy(&potential_end_types);
01186 apol_vector_destroy(&potential_ep_types);
01187 goto err;
01188 }
01189 }
01190 apol_vector_destroy(&eprules);
01191 apol_vector_sort_uniquify(tmpl_result->ep_rules, NULL, NULL);
01192 if (epnode) {
01193 //if present find tt
01194 apol_vector_destroy(&tmpl_result->type_trans_rules);
01195 tmpl_result->type_trans_rules = apol_vector_create(NULL);
01196 if (!tmpl_result->type_trans_rules) {
01197 error = errno;
01198 apol_vector_destroy(&potential_end_types);
01199 apol_vector_destroy(&potential_ep_types);
01200 goto err;
01201 }
01202 apol_vector_t *ttrules = find_terules_in_node(epnode, start_type, end_type);
01203 for (size_t l = 0; l < apol_vector_get_size(ttrules); l++) {
01204 terule_node_t *tn = apol_vector_get_element(ttrules, l);
01205 if (apol_vector_append(tmpl_result->type_trans_rules, (void *)tn->rule)) {
01206 error = errno;
01207 apol_vector_destroy(&ttrules);
01208 apol_vector_destroy(&potential_end_types);
01209 apol_vector_destroy(&potential_ep_types);
01210 goto err;
01211 }
01212 }
01213 apol_vector_destroy(&ttrules);
01214 apol_vector_sort_uniquify(tmpl_result->type_trans_rules, NULL, NULL);
01215 //find execute rules
01216 apol_vector_destroy(&tmpl_result->exec_rules);
01217 tmpl_result->exec_rules = apol_vector_create(NULL);
01218 if (!tmpl_result->exec_rules) {
01219 error = errno;
01220 apol_vector_destroy(&potential_end_types);
01221 apol_vector_destroy(&potential_ep_types);
01222 goto err;
01223 }
01224 apol_vector_t *execrules =
01225 find_avrules_in_node(epnode, APOL_DOMAIN_TRANS_RULE_EXEC, start_type);
01226 if (apol_vector_get_size(execrules)) {
01227 for (size_t l = 0; l < apol_vector_get_size(execrules); l++) {
01228 avrule_node_t *xnode = apol_vector_get_element(execrules, l);
01229 //do not mark xnode as used here; it is valid to re-use it.
01230 if (apol_vector_append
01231 (tmpl_result->exec_rules, (void *)xnode->rule)) {
01232 error = errno;
01233 apol_vector_destroy(&execrules);
01234 apol_vector_destroy(&potential_end_types);
01235 apol_vector_destroy(&potential_ep_types);
01236 goto err;
01237 }
01238 }
01239 apol_vector_destroy(&execrules);
01240 apol_vector_sort_uniquify(tmpl_result->exec_rules, NULL, NULL);
01241 //found everything possible add a result
01242 apol_domain_trans_result_t *tmp =
01243 apol_domain_trans_result_create_from_domain_trans_result
01244 (tmpl_result);
01245 if (!tmp || apol_vector_append(local_results, (void *)tmp)) {
01246 error = errno;
01247 apol_domain_trans_result_destroy(&tmp);
01248 apol_vector_destroy(&potential_end_types);
01249 apol_vector_destroy(&potential_ep_types);
01250 goto err;
01251 }
01252 //reset execute rules
01253 apol_vector_destroy(&tmpl_result->exec_rules);
01254 tmpl_result->exec_rules = apol_vector_create(NULL);
01255 if (!tmpl_result->exec_rules) {
01256 error = errno;
01257 apol_vector_destroy(&potential_end_types);
01258 apol_vector_destroy(&potential_ep_types);
01259 goto err;
01260 }
01261 //reset type transition rules
01262 apol_vector_destroy(&tmpl_result->type_trans_rules);
01263 tmpl_result->type_trans_rules = apol_vector_create(NULL);
01264 if (!tmpl_result->type_trans_rules) {
01265 error = errno;
01266 apol_vector_destroy(&potential_end_types);
01267 apol_vector_destroy(&potential_ep_types);
01268 goto err;
01269 }
01270 } else {
01271 //have proc_trans and entrypoint but no execute
01272 apol_domain_trans_result_t *tmp =
01273 apol_domain_trans_result_create_from_domain_trans_result
01274 (tmpl_result);
01275 if (!tmp || apol_vector_append(local_results, (void *)tmp)) {
01276 error = errno;
01277 apol_domain_trans_result_destroy(&tmp);
01278 apol_vector_destroy(&potential_end_types);
01279 apol_vector_destroy(&potential_ep_types);
01280 goto err;
01281 }
01282 }
01283 apol_vector_destroy(&execrules);
01284 } else {
01285 //have proc_trans and entrypoint but no execute
01286 apol_domain_trans_result_t *tmp =
01287 apol_domain_trans_result_create_from_domain_trans_result(tmpl_result);
01288 if (!tmp || apol_vector_append(local_results, (void *)tmp)) {
01289 error = errno;
01290 apol_domain_trans_result_destroy(&tmp);
01291 apol_vector_destroy(&potential_end_types);
01292 apol_vector_destroy(&potential_ep_types);
01293 goto err;
01294 }
01295 }
01296 //reset entrypoint rules
01297 apol_vector_destroy(&tmpl_result->ep_rules);
01298 tmpl_result->ep_rules = apol_vector_create(NULL);
01299 if (!tmpl_result->ep_rules) {
01300 error = errno;
01301 apol_vector_destroy(&potential_end_types);
01302 apol_vector_destroy(&potential_ep_types);
01303 goto err;
01304 }
01305 }
01306 apol_vector_destroy(&potential_ep_types);
01307 } else {
01308 //have proc_trans but end has no ep
01309 apol_domain_trans_result_t *tmp =
01310 apol_domain_trans_result_create_from_domain_trans_result(tmpl_result);
01311 if (!tmp || apol_vector_append(local_results, (void *)tmp)) {
01312 error = errno;
01313 apol_domain_trans_result_destroy(&tmp);
01314 goto err;
01315 }
01316 }
01317 }
01318 apol_vector_destroy(&potential_end_types);
01319 //validate all
01320 for (size_t i = 0; i < apol_vector_get_size(local_results); i++) {
01321 apol_domain_trans_result_t *res = apol_vector_get_element(local_results, i);
01322 if (res->start_type && res->ep_type && res->end_type && apol_vector_get_size(res->proc_trans_rules) &&
01323 apol_vector_get_size(res->ep_rules) && apol_vector_get_size(res->exec_rules) &&
01324 (requires_setexec_or_type_trans(policy)
01325 ? (apol_vector_get_size(res->setexec_rules) || apol_vector_get_size(res->type_trans_rules)) : true)) {
01326 res->valid = true;
01327 }
01328 }
01329 }
01330 //iff looking for invalid find orphan type_transition rules
01331 if (dta->valid & APOL_DOMAIN_TRANS_SEARCH_INVALID) {
01332 if (domain_trans_table_find_orphan_type_transitions(policy, dta, local_results)) {
01333 error = errno;
01334 goto err;
01335 }
01336 }
01337 apol_domain_trans_result_destroy(&tmpl_result);
01338
01339 return 0;
01340 err:
01341 apol_domain_trans_result_destroy(&tmpl_result);
01342 errno = error;
01343 return -1;
01344 }
|
|
||||||||||||||||||||
|
Definition at line 1346 of file domain-trans-analysis.c. References apol_bst_get_element(), apol_bst_get_vector(), apol_domain_trans_analysis_t, apol_domain_trans_result_create_from_domain_trans_result(), apol_domain_trans_result_destroy(), apol_domain_trans_result_t, APOL_DOMAIN_TRANS_RULE_ENTRYPOINT, APOL_DOMAIN_TRANS_RULE_EXEC, APOL_DOMAIN_TRANS_RULE_PROC_TRANS, apol_policy_t, apol_vector_append(), apol_vector_cat(), apol_vector_create(), apol_vector_destroy(), apol_vector_get_element(), apol_vector_get_size(), apol_vector_sort_uniquify(), apol_vector_t, avrule_node_t, dom_node_t, apol_domain_trans_table::domain_table, domain_trans_result_create(), apol_policy::domain_trans_table, domain_trans_table_find_orphan_type_transitions(), apol_domain_trans_result::end_type, apol_domain_trans_table::entrypoint_table, ep_node_t, apol_domain_trans_result::ep_rules, apol_domain_trans_result::ep_type, apol_domain_trans_result::exec_rules, find_avrules_in_node(), find_terules_in_node(), apol_domain_trans_result::proc_trans_rules, requires_setexec_or_type_trans(), terule_node::rule, avrule_node::rule, apol_domain_trans_result::setexec_rules, apol_domain_trans_result::start_type, terule_node_t, avrule_node::type, apol_domain_trans_result::type_trans_rules, terule_node::used, avrule_node::used, apol_domain_trans_analysis::valid, and apol_domain_trans_result::valid. Referenced by apol_domain_trans_analysis_do(). 01348 {
01349 int error = 0;
01350 //create template result this will hold common data for each step and be copied as needed
01351 apol_domain_trans_result_t *tmpl_result = domain_trans_result_create();
01352 if (!tmpl_result) {
01353 error = errno;
01354 goto err;
01355 }
01356 //find end node
01357 dom_node_t dummy = { end_type, NULL, NULL, NULL };
01358 dom_node_t *end_node = NULL;
01359 apol_bst_get_element(policy->domain_trans_table->domain_table, (void *)&dummy, NULL, (void **)&end_node);
01360 if (end_node) {
01361 tmpl_result->end_type = end_type;
01362 //collect potential entrypoint types
01363 apol_vector_t *eprules = apol_bst_get_vector(end_node->entrypoint_tree, 0);
01364 apol_vector_t *potential_ep_types = apol_vector_create(NULL);
01365 if (!eprules || !potential_ep_types) {
01366 error = errno;
01367 apol_vector_destroy(&eprules);
01368 goto err;
01369 }
01370 for (size_t j = 0; j < apol_vector_get_size(eprules); j++) {
01371 avrule_node_t *epr = apol_vector_get_element(eprules, j);
01372 if (apol_vector_append(potential_ep_types, (void *)epr->type)) {
01373 error = errno;
01374 apol_vector_destroy(&eprules);
01375 apol_vector_destroy(&potential_ep_types);
01376 goto err;
01377 }
01378 }
01379 apol_vector_destroy(&eprules);
01380 apol_vector_sort_uniquify(potential_ep_types, NULL, NULL);
01381 for (size_t i = 0; i < apol_vector_get_size(potential_ep_types); i++) {
01382 tmpl_result->ep_type = apol_vector_get_element(potential_ep_types, i);
01383 //get all ep rules for this end (may be multiple due to attributes)
01384 eprules = find_avrules_in_node((void *)end_node, APOL_DOMAIN_TRANS_RULE_ENTRYPOINT, tmpl_result->ep_type);
01385 apol_vector_destroy(&tmpl_result->ep_rules);
01386 tmpl_result->ep_rules = apol_vector_create(NULL);
01387 for (size_t j = 0; j < apol_vector_get_size(eprules); j++) {
01388 avrule_node_t *ep_ent = apol_vector_get_element(eprules, j);
01389 ep_ent->used = true;
01390 if (apol_vector_append(tmpl_result->ep_rules, (void *)ep_ent->rule)) {
01391 error = errno;
01392 apol_vector_destroy(&eprules);
01393 apol_vector_destroy(&potential_ep_types);
01394 goto err;
01395 }
01396 }
01397 apol_vector_destroy(&eprules);
01398 apol_vector_sort_uniquify(tmpl_result->ep_rules, NULL, NULL);
01399 ep_node_t edummy = { tmpl_result->ep_type, NULL, NULL };
01400 ep_node_t *epnode = NULL;
01401 apol_bst_get_element(policy->domain_trans_table->entrypoint_table, (void *)&edummy, NULL, (void **)&epnode);
01402 //for each ep find exec rules to generate list of potential start types
01403 if (epnode) {
01404 apol_vector_t *execrules = apol_bst_get_vector(epnode->execute_tree, 0);
01405 apol_vector_t *potential_start_types = apol_vector_create(NULL);
01406 if (!execrules || !potential_start_types) {
01407 error = errno;
01408 apol_vector_destroy(&execrules);
01409 goto err;
01410 }
01411 for (size_t k = 0; k < apol_vector_get_size(execrules); k++) {
01412 avrule_node_t *n = apol_vector_get_element(execrules, k);
01413 if (apol_vector_append(potential_start_types, (void *)n->type)) {
01414 error = errno;
01415 apol_vector_destroy(&execrules);
01416 apol_vector_destroy(&potential_start_types);
01417 apol_vector_destroy(&potential_ep_types);
01418 goto err;
01419 }
01420 }
01421 apol_vector_destroy(&execrules);
01422 apol_vector_sort_uniquify(potential_start_types, NULL, NULL);
01423 for (size_t k = 0; k < apol_vector_get_size(potential_start_types); k++) {
01424 tmpl_result->start_type = apol_vector_get_element(potential_start_types, k);
01425 //no transition to self
01426 if (tmpl_result->end_type == tmpl_result->start_type)
01427 continue;
01428 //get all execute rule for this start type
01429 apol_vector_t *exec_rules =
01430 find_avrules_in_node((void *)epnode, APOL_DOMAIN_TRANS_RULE_EXEC,
01431 tmpl_result->start_type);
01432 apol_vector_destroy(&tmpl_result->exec_rules);
01433 tmpl_result->exec_rules = apol_vector_create(NULL);
01434 for (size_t l = 0; l < apol_vector_get_size(exec_rules); l++) {
01435 avrule_node_t *n = apol_vector_get_element(exec_rules, l);
01436 n->used = true;
01437 if (apol_vector_append(tmpl_result->exec_rules, (void *)n->rule)) {
01438 error = errno;
01439 apol_vector_destroy(&exec_rules);
01440 apol_vector_destroy(&potential_start_types);
01441 apol_vector_destroy(&potential_ep_types);
01442 goto err;
01443 }
01444 }
01445 apol_vector_destroy(&exec_rules);
01446 apol_vector_sort_uniquify(tmpl_result->exec_rules, NULL, NULL);
01447 //check for type transition rules
01448 apol_vector_t *ttrules =
01449 find_terules_in_node(epnode, tmpl_result->start_type, tmpl_result->end_type);
01450 apol_vector_destroy(&tmpl_result->type_trans_rules);
01451 tmpl_result->type_trans_rules = apol_vector_create(NULL);
01452 if (!tmpl_result->type_trans_rules) {
01453 error = errno;
01454 apol_vector_destroy(&ttrules);
01455 apol_vector_destroy(&potential_start_types);
01456 apol_vector_destroy(&potential_ep_types);
01457 goto err;
01458 }
01459 for (size_t l = 0; l < apol_vector_get_size(ttrules); l++) {
01460 terule_node_t *n = apol_vector_get_element(ttrules, l);
01461 n->used = true;
01462 if (apol_vector_append(tmpl_result->type_trans_rules, (void *)n->rule)) {
01463 error = errno;
01464 apol_vector_destroy(&ttrules);
01465 apol_vector_destroy(&potential_start_types);
01466 apol_vector_destroy(&potential_ep_types);
01467 goto err;
01468 }
01469 }
01470 apol_vector_destroy(&ttrules);
01471 apol_vector_sort_uniquify(tmpl_result->type_trans_rules, NULL, NULL);
01472 dummy.type = tmpl_result->start_type;
01473 dom_node_t *start_node = NULL;
01474 apol_bst_get_element(policy->domain_trans_table->domain_table, (void *)&dummy, NULL,
01475 (void **)&start_node);
01476 if (start_node) {
01477 //for each start check setexec if needed
01478 if (requires_setexec_or_type_trans(policy)) {
01479 apol_vector_destroy(&tmpl_result->setexec_rules);
01480 tmpl_result->setexec_rules = apol_vector_create(NULL);
01481 if (!tmpl_result->setexec_rules ||
01482 apol_vector_cat(tmpl_result->setexec_rules,
01483 start_node->setexec_rules)) {
01484 error = errno;
01485 apol_vector_destroy(&potential_start_types);
01486 apol_vector_destroy(&potential_ep_types);
01487 goto err;
01488 }
01489 }
01490 //for each start find pt
01491 apol_vector_destroy(&tmpl_result->proc_trans_rules);
01492 tmpl_result->proc_trans_rules = apol_vector_create(NULL);
01493 if (!tmpl_result->proc_trans_rules) {
01494 error = errno;
01495 apol_vector_destroy(&potential_start_types);
01496 apol_vector_destroy(&potential_ep_types);
01497 goto err;
01498 }
01499 apol_vector_t *pt_rules = NULL;
01500 pt_rules =
01501 find_avrules_in_node(start_node, APOL_DOMAIN_TRANS_RULE_PROC_TRANS,
01502 tmpl_result->end_type);
01503 if (apol_vector_get_size(pt_rules)) {
01504 for (size_t l = 0; l < apol_vector_get_size(pt_rules); l++) {
01505 avrule_node_t *n = apol_vector_get_element(pt_rules, l);
01506 apol_vector_append(tmpl_result->proc_trans_rules, (void *)n->rule);
01507 }
01508 apol_vector_destroy(&pt_rules);
01509 apol_vector_sort_uniquify(tmpl_result->proc_trans_rules, NULL, NULL);
01510 // have all possible rules add this entry
01511 apol_domain_trans_result_t *tmp =
01512 apol_domain_trans_result_create_from_domain_trans_result
01513 (tmpl_result);
01514 if (!tmp || apol_vector_append(local_results, (void *)tmp)) {
01515 error = errno;
01516 apol_domain_trans_result_destroy(&tmp);
01517 apol_vector_destroy(&potential_start_types);
01518 apol_vector_destroy(&potential_ep_types);
01519 goto err;
01520 }
01521 //reset process transition rules
01522 apol_vector_destroy(&tmpl_result->proc_trans_rules);
01523 tmpl_result->proc_trans_rules = apol_vector_create(NULL);
01524 if (!tmpl_result->proc_trans_rules) {
01525 error = errno;
01526 apol_vector_destroy(&potential_start_types);
01527 apol_vector_destroy(&potential_ep_types);
01528 goto err;
01529 }
01530 //reset setexec rules
01531 apol_vector_destroy(&tmpl_result->setexec_rules);
01532 tmpl_result->setexec_rules = apol_vector_create(NULL);
01533 if (!tmpl_result->setexec_rules) {
01534 error = errno;
01535 apol_vector_destroy(&potential_start_types);
01536 apol_vector_destroy(&potential_ep_types);
01537 goto err;
01538 }
01539 } else {
01540 //have entrypoint and execute rules but no process transition rule
01541 apol_domain_trans_result_t *tmp =
01542 apol_domain_trans_result_create_from_domain_trans_result
01543 (tmpl_result);
01544 if (!tmp || apol_vector_append(local_results, (void *)tmp)) {
01545 error = errno;
01546 apol_domain_trans_result_destroy(&tmp);
01547 apol_vector_destroy(&potential_start_types);
01548 apol_vector_destroy(&potential_ep_types);
01549 apol_vector_destroy(&pt_rules);
01550 goto err;
01551 }
01552 }
01553 apol_vector_destroy(&pt_rules);
01554 } else {
01555 //have entrypoint and execute rules but no process transition rule
01556 apol_domain_trans_result_t *tmp =
01557 apol_domain_trans_result_create_from_domain_trans_result(tmpl_result);
01558 if (!tmp || apol_vector_append(local_results, (void *)tmp)) {
01559 error = errno;
01560 apol_domain_trans_result_destroy(&tmp);
01561 apol_vector_destroy(&potential_start_types);
01562 apol_vector_destroy(&potential_ep_types);
01563 goto err;
01564 }
01565 }
01566 //reset execute rules
01567 apol_vector_destroy(&tmpl_result->exec_rules);
01568 tmpl_result->exec_rules = apol_vector_create(NULL);
01569 if (!tmpl_result->exec_rules) {
01570 error = errno;
01571 apol_vector_destroy(&potential_start_types);
01572 apol_vector_destroy(&potential_ep_types);
01573 goto err;
01574 }
01575 //reset type transition rules
01576 apol_vector_destroy(&tmpl_result->type_trans_rules);
01577 tmpl_result->type_trans_rules = apol_vector_create(NULL);
01578 if (!tmpl_result->type_trans_rules) {
01579 error = errno;
01580 apol_vector_destroy(&potential_start_types);
01581 apol_vector_destroy(&potential_ep_types);
01582 goto err;
01583 }
01584 }
01585 apol_vector_destroy(&potential_start_types);
01586 } else {
01587 //have entrypoint but no exec
01588 apol_domain_trans_result_t *tmp =
01589 apol_domain_trans_result_create_from_domain_trans_result(tmpl_result);
01590 if (!tmp || apol_vector_append(local_results, (void *)tmp)) {
01591 error = errno;
01592 apol_domain_trans_result_destroy(&tmp);
01593 goto err;
01594 }
01595 }
01596 }
01597 apol_vector_destroy(&potential_ep_types);
01598
01599 //validate all
01600 for (size_t i = 0; i < apol_vector_get_size(local_results); i++) {
01601 apol_domain_trans_result_t *res = apol_vector_get_element(local_results, i);
01602 if (res->start_type && res->ep_type && res->end_type && apol_vector_get_size(res->proc_trans_rules) &&
01603 apol_vector_get_size(res->ep_rules) && apol_vector_get_size(res->exec_rules) &&
01604 (requires_setexec_or_type_trans(policy)
01605 ? (apol_vector_get_size(res->setexec_rules) || apol_vector_get_size(res->type_trans_rules)) : true)) {
01606 res->valid = true;
01607 }
01608 }
01609 }
01610 //iff looking for invalid find orphan type_transition rules
01611 if (dta->valid & APOL_DOMAIN_TRANS_SEARCH_INVALID) {
01612 if (domain_trans_table_find_orphan_type_transitions(policy, dta, local_results)) {
01613 error = errno;
01614 goto err;
01615 }
01616 }
01617
01618 apol_domain_trans_result_destroy(&tmpl_result);
01619 return 0;
01620
01621 err:
01622 apol_domain_trans_result_destroy(&tmpl_result);
01623 errno = error;
01624 return -1;
01625 }
|
|
||||||||||||||||
|
Execute a domain transition analysis against a particular policy.
Definition at line 1627 of file domain-trans-analysis.c. References apol_domain_trans_analysis::access_classes, apol_domain_trans_analysis::access_perms, apol_domain_trans_result::access_rules, apol_domain_trans_analysis::access_types, apol_avrule_get_by_query(), apol_avrule_query_append_class(), apol_avrule_query_append_perm(), apol_avrule_query_create(), apol_avrule_query_destroy(), apol_avrule_query_set_rules(), apol_avrule_query_set_source(), apol_avrule_query_set_target(), apol_avrule_query_t, apol_compare_type(), apol_domain_trans_analysis_t, APOL_DOMAIN_TRANS_DIRECTION_FORWARD, apol_domain_trans_result_create_from_domain_trans_result(), apol_domain_trans_result_t, apol_policy_build_domain_trans_table(), apol_policy_get_qpol(), apol_policy_t, APOL_QUERY_REGEX, apol_vector_append(), apol_vector_cat(), apol_vector_create(), apol_vector_destroy(), apol_vector_get_element(), apol_vector_get_size(), apol_vector_remove(), apol_vector_t, apol_domain_trans_analysis::direction, domain_trans_result_free(), apol_policy::domain_trans_table, domain_trans_table_get_all_forward_trans(), domain_trans_table_get_all_reverse_trans(), apol_domain_trans_result::end_type, ERR, apol_policy::p, qpol_policy_get_type_by_name(), QPOL_RULE_ALLOW, qpol_type_get_isattr(), qpol_type_get_name(), qpol_type_t, apol_domain_trans_analysis::result, apol_domain_trans_analysis::result_regex, apol_domain_trans_result::start_type, apol_domain_trans_analysis::start_type, apol_domain_trans_result::valid, and apol_domain_trans_analysis::valid. Referenced by apol_types_relation_domain(), dta_forward(), dta_forward_access(), dta_forward_multi_end(), dta_invalid(), dta_reflexive(), dta_reverse(), dta_reverse_regexp(), inc_dom_trans_run(), and unreachable_doms_run(). 01628 {
01629 apol_vector_t *local_results = NULL;
01630 apol_avrule_query_t *accessq = NULL;
01631 int error = 0;
01632 if (!results)
01633 *results = NULL;
01634 if (!policy || !dta || !results) {
01635 ERR(policy, "%s", strerror(EINVAL));
01636 errno = EINVAL;
01637 return -1;
01638 }
01639
01640 /* build table if not already present */
01641 if (!(policy->domain_trans_table)) {
01642 if (apol_policy_build_domain_trans_table(policy))
01643 return -1; /* errors already reported by build function */
01644 }
01645
01646 /* validate analysis options */
01647 if (dta->direction == 0 || dta->valid & ~(APOL_DOMAIN_TRANS_SEARCH_BOTH) || !(dta->start_type)) {
01648 error = EINVAL;
01649 ERR(policy, "%s", strerror(EINVAL));
01650 goto err;
01651 }
01652 size_t num_atypes = apol_vector_get_size(dta->access_types);
01653 size_t num_aclasses = apol_vector_get_size(dta->access_classes);
01654 size_t num_aprems = apol_vector_get_size(dta->access_perms);
01655 if ((num_atypes == 0 && (num_aclasses != 0 || num_aprems != 0)) ||
01656 (num_aclasses == 0 && (num_atypes != 0 || num_aprems != 0)) ||
01657 (num_aprems == 0 && (num_aclasses != 0 || num_atypes != 0))) {
01658 error = EINVAL;
01659 ERR(policy, "%s", strerror(EINVAL));
01660 goto err;
01661 }
01662
01663 /* get starting type */
01664 const qpol_type_t *start_type = NULL;
01665 if (qpol_policy_get_type_by_name(policy->p, dta->start_type, &start_type)) {
01666 error = errno;
01667 ERR(policy, "Unable to perform analysis: Invalid starting type %s", dta->start_type);
01668 goto err;
01669 }
01670 unsigned char isattr = 0;
01671 qpol_type_get_isattr(policy->p, start_type, &isattr);
01672 if (isattr) {
01673 ERR(policy, "%s", "Attributes are not valid here.");
01674 error = EINVAL;
01675 goto err;
01676 }
01677
01678 local_results = apol_vector_create(domain_trans_result_free);
01679 /* get all transitions for the requested direction */
01680 if (dta->direction == APOL_DOMAIN_TRANS_DIRECTION_REVERSE) {
01681 if (domain_trans_table_get_all_reverse_trans(policy, dta, local_results, start_type)) {
01682 error = errno;
01683 goto err;
01684 }
01685 } else {
01686 if (domain_trans_table_get_all_forward_trans(policy, dta, local_results, start_type)) {
01687 error = errno;
01688 goto err;
01689 }
01690 }
01691
01692 /* if requested, filter by validity */
01693 if (dta->valid != APOL_DOMAIN_TRANS_SEARCH_BOTH) {
01694 for (size_t i = 0; i < apol_vector_get_size(local_results); /* increment later */ ) {
01695 apol_domain_trans_result_t *res = apol_vector_get_element(local_results, i);
01696 if (res->valid != (dta->valid == APOL_DOMAIN_TRANS_SEARCH_VALID)) {
01697 apol_vector_remove(local_results, i);
01698 domain_trans_result_free(res);
01699 } else {
01700 i++;
01701 }
01702 }
01703 }
01704
01705 /* if filtering by result type, do that now */
01706 if (dta->result) {
01707 for (size_t i = 0; i < apol_vector_get_size(local_results); /* increment later */ ) {
01708 apol_domain_trans_result_t *res = apol_vector_get_element(local_results, i);
01709 const qpol_type_t *type = NULL;
01710 if (dta->direction == APOL_DOMAIN_TRANS_DIRECTION_REVERSE) {
01711 type = res->start_type;
01712 } else {
01713 type = res->end_type;
01714 }
01715 int compval = apol_compare_type(policy, type, dta->result, APOL_QUERY_REGEX, &dta->result_regex);
01716 if (compval < 0) {
01717 error = errno;
01718 goto err;
01719 } else if (compval > 0) {
01720 i++;
01721 } else {
01722 apol_vector_remove(local_results, i);
01723 domain_trans_result_free(res);
01724 }
01725 }
01726 }
01727
01728 /* finally do access filtering */
01729 if (dta->direction == APOL_DOMAIN_TRANS_DIRECTION_FORWARD && num_atypes && num_aclasses && num_aprems) {
01730 accessq = apol_avrule_query_create();
01731 apol_avrule_query_set_rules(policy, accessq, QPOL_RULE_ALLOW);
01732 for (size_t i = 0; i < num_aclasses; i++) {
01733 if (apol_avrule_query_append_class
01734 (policy, accessq, (char *)apol_vector_get_element(dta->access_classes, i))) {
01735 error = errno;
01736 goto err;
01737 }
01738 }
01739 for (size_t i = 0; i < num_aprems; i++) {
01740 if (apol_avrule_query_append_perm(policy, accessq, (char *)apol_vector_get_element(dta->access_perms, i))) {
01741 error = errno;
01742 goto err;
01743 }
01744 }
01745 for (size_t i = 0; i < apol_vector_get_size(local_results); /* increment later */ ) {
01746 const char *end_name = NULL;
01747 apol_domain_trans_result_t *res = apol_vector_get_element(local_results, i);
01748 if (qpol_type_get_name(apol_policy_get_qpol(policy), res->end_type, &end_name) ||
01749 apol_avrule_query_set_source(policy, accessq, end_name, 1)) {
01750 error = errno;
01751 goto err;
01752 }
01753 apol_vector_t *tmp_access = apol_vector_create(NULL);
01754 for (size_t j = 0; j < num_atypes; j++) {
01755 if (apol_avrule_query_set_target
01756 (policy, accessq, (char *)apol_vector_get_element(dta->access_types, j), 1)) {
01757 error = errno;
01758 apol_vector_destroy(&tmp_access);
01759 goto err;
01760 }
01761 apol_vector_t *cur_tgt_v = NULL;
01762 apol_avrule_get_by_query(policy, accessq, &cur_tgt_v);
01763 apol_vector_cat(tmp_access, cur_tgt_v);
01764 apol_vector_destroy(&cur_tgt_v);
01765 }
01766 if (apol_vector_get_size(tmp_access)) {
01767 res->access_rules = tmp_access;
01768 tmp_access = NULL;
01769 i++;
01770 } else {
01771 apol_vector_remove(local_results, i);
01772 domain_trans_result_free(res);
01773 }
01774 apol_vector_destroy(&tmp_access);
01775 }
01776 apol_avrule_query_destroy(&accessq);
01777 }
01778
01779 *results = apol_vector_create(domain_trans_result_free);
01780 if (!(*results)) {
01781 error = errno;
01782 goto err;
01783 }
01784 for (size_t i = 0; i < apol_vector_get_size(local_results); i++) {
01785 apol_domain_trans_result_t *res =
01786 apol_domain_trans_result_create_from_domain_trans_result((apol_domain_trans_result_t *)
01787 apol_vector_get_element(local_results, i));
01788 if (!res || apol_vector_append(*results, (void *)res)) {
01789 error = errno;
01790 domain_trans_result_free(res);
01791 goto err;
01792 }
01793 }
01794 apol_vector_destroy(&local_results);
01795
01796 return 0;
01797 err:
01798 apol_vector_destroy(&local_results);
01799 apol_vector_destroy(results);
01800 apol_avrule_query_destroy(&accessq);
01801 errno = error;
01802 return -1;
01803 }
|
|
|
Return the start type of the transition in an apol_domain_trans_result node. The caller should not free the returned pointer. If the transition in the node is not valid there may be no start type in which case NULL is returned.
Definition at line 1807 of file domain-trans-analysis.c. References apol_domain_trans_result_t, qpol_type_t, and apol_domain_trans_result::start_type. Referenced by dta_forward(), dta_forward_access(), dta_forward_multi_end(), dta_invalid(), dta_reflexive(), dta_reverse(), dta_reverse_regexp(), inc_dom_trans_print(), inc_dom_trans_run(), and unreachable_doms_run(). 01808 {
01809 if (dtr) {
01810 return dtr->start_type;
01811 } else {
01812 errno = EINVAL;
01813 return NULL;
01814 }
01815 }
|
|
|
Return the entrypoint type of the transition in an apol_domain_trans_result node. The caller should not free the returned pointer. If the transition in the node is not valid there may be no entrypoint in which case NULL is returned.
Definition at line 1817 of file domain-trans-analysis.c. References apol_domain_trans_result_t, apol_domain_trans_result::ep_type, and qpol_type_t. Referenced by dta_forward(), dta_forward_multi_end(), dta_invalid(), dta_reverse_regexp(), inc_dom_trans_print(), inc_dom_trans_run(), and unreachable_doms_run(). 01818 {
01819 if (dtr) {
01820 return dtr->ep_type;
01821 } else {
01822 errno = EINVAL;
01823 return NULL;
01824 }
01825 }
|
|
|
Return the end type of the transition in an apol_domain_trans_result node. The caller should not free the returned pointer. If the transition in the node is not valid there may be no end type in which case NULL is returned.
Definition at line 1827 of file domain-trans-analysis.c. References apol_domain_trans_result_t, apol_domain_trans_result::end_type, and qpol_type_t. Referenced by apol_types_relation_clone_domaintrans(), dta_forward(), dta_forward_access(), dta_forward_multi_end(), dta_invalid(), dta_reverse(), dta_reverse_regexp(), inc_dom_trans_print(), and inc_dom_trans_run(). 01828 {
01829 if (dtr) {
01830 return dtr->end_type;
01831 } else {
01832 errno = EINVAL;
01833 return NULL;
01834 }
01835 }
|
|
|
Return the vector of process transition rules (qpol_avrule_t pointers) in an apol_domain_trans_result node. The caller should not free the returned pointer. If the transition is invalid then the returned vector will be empty.
Definition at line 1837 of file domain-trans-analysis.c. References apol_domain_trans_result_t, apol_vector_t, and apol_domain_trans_result::proc_trans_rules. Referenced by dta_invalid(). 01838 {
01839 if (dtr) {
01840 return dtr->proc_trans_rules;
01841 } else {
01842 errno = EINVAL;
01843 return NULL;
01844 }
01845 }
|
|
|
Return the vector of file entrypoint rules (qpol_avrule_t pointers) in an apol_domain_trans_result node. The caller should not free the returned pointer. If the transition is invalid then the returned vector will be empty.
Definition at line 1847 of file domain-trans-analysis.c. References apol_domain_trans_result_t, apol_vector_t, and apol_domain_trans_result::ep_rules. Referenced by dta_invalid(). 01848 {
01849 if (dtr) {
01850 return dtr->ep_rules;
01851 } else {
01852 errno = EINVAL;
01853 return NULL;
01854 }
01855 }
|
|
|
Return the vector of file execute rules (qpol_avrule_t pointers) in an apol_domain_trans_result node. The caller should not free the returned pointer. If the transition is invalid then the returned vector will be empty.
Definition at line 1857 of file domain-trans-analysis.c. References apol_domain_trans_result_t, apol_vector_t, and apol_domain_trans_result::exec_rules. Referenced by dta_invalid(). 01858 {
01859 if (dtr) {
01860 return dtr->exec_rules;
01861 } else {
01862 errno = EINVAL;
01863 return NULL;
01864 }
01865 }
|
|
|
Return the vector of process setexec rules (qpol_avrule_t pointers) in an apol_domain_trans_result node. The caller should not free the returned pointer. For all policies of version 15 or later a transition requires either a setexec rule or a type_transition rule to be valid. Valid transitions may have both; if there is no rule, this function returns an empty vector.
Definition at line 1867 of file domain-trans-analysis.c. References apol_domain_trans_result_t, apol_vector_t, and apol_domain_trans_result::setexec_rules. Referenced by dta_invalid(). 01868 {
01869 if (dtr) {
01870 return dtr->setexec_rules;
01871 } else {
01872 errno = EINVAL;
01873 return NULL;
01874 }
01875 }
|
|
|
Return the vector of type_transition rules (qpol_terule_t pointers) in an apol_domain_trans_result node. The caller should not free the returned pointer. For all policies of version 15 or later a transition requires either a setexec rule or a type_transition rule to be valid. Valid transitions may have both; if there is no rule, this function returns an empty vector.
Definition at line 1877 of file domain-trans-analysis.c. References apol_domain_trans_result_t, apol_vector_t, and apol_domain_trans_result::type_trans_rules. Referenced by dta_invalid(). 01878 {
01879 if (dtr) {
01880 return dtr->type_trans_rules;
01881 } else {
01882 errno = EINVAL;
01883 return NULL;
01884 }
01885 }
|
|
|
Determine if the transition in an apol_domain_trans_result node is valid.
Definition at line 1887 of file domain-trans-analysis.c. References apol_domain_trans_result_t, and apol_domain_trans_result::valid. Referenced by dta_invalid(). 01888 {
01889 if (dtr) {
01890 return dtr->valid;
01891 } else {
01892 errno = EINVAL;
01893 return 0;
01894 }
01895 }
|
|
|
Return the vector of access rules which satisfied the access types, classes, and permissions specified in the query. This is a vector of qpol_avrule_t pointers. The caller should not call apol_vector_destroy() upon the returned vector. This vector is only populated if access criteria were specified in the analysis.
Definition at line 1897 of file domain-trans-analysis.c. References apol_domain_trans_result::access_rules, apol_domain_trans_result_t, and apol_vector_t. Referenced by dta_forward_access(). 01898 {
01899 if (dtr) {
01900 return dtr->access_rules;
01901 } else {
01902 errno = EINVAL;
01903 return NULL;
01904 }
01905 }
|
|
||||||||||||||||||||
|
Verify that a transition using the given three types is valid in the given policy. If not valid, return a value indicating the missing rules. If any type is NULL, rules that would contain that type are considered missing. A valid transition requires a process transition, an entrypoint, and an execute rule. If the policy is version 15 or later it also requires either a setexec rule or a type_transition rule. The value APOL_DOMAIN_TRANS_RULE_EXEC_NO_TRANS is not returned by this function.
Definition at line 1907 of file domain-trans-analysis.c. References apol_bst_get_element(), APOL_DOMAIN_TRANS_RULE_ENTRYPOINT, APOL_DOMAIN_TRANS_RULE_EXEC, APOL_DOMAIN_TRANS_RULE_PROC_TRANS, apol_policy_get_qpol(), apol_policy_reset_domain_trans_table(), apol_policy_t, apol_terule_get_by_query(), apol_terule_query_create(), apol_terule_query_destroy(), apol_terule_query_set_default(), apol_terule_query_set_rules(), apol_terule_query_set_source(), apol_terule_query_t, apol_vector_destroy(), apol_vector_get_size(), apol_vector_t, dom_node_t, apol_domain_trans_table::domain_table, apol_policy::domain_trans_table, apol_domain_trans_table::entrypoint_table, ep_node_t, find_avrules_in_node(), find_terules_in_node(), QPOL_RULE_TYPE_TRANS, qpol_type_get_name(), and requires_setexec_or_type_trans(). Referenced by inc_dom_trans_run(), and unreachable_doms_run(). 01909 {
01910 int missing_rules = 0;
01911
01912 if (!policy || !policy->domain_trans_table) {
01913 errno = EINVAL;
01914 return -1;
01915 }
01916 //reset the table
01917 apol_policy_reset_domain_trans_table(policy);
01918 //find nodes for each type
01919 dom_node_t start_dummy = { start_dom, NULL, NULL, NULL };
01920 dom_node_t *start_node = NULL;
01921 if (start_dom)
01922 apol_bst_get_element(policy->domain_trans_table->domain_table, (void *)&start_dummy, NULL, (void **)&start_node);
01923 ep_node_t ep_dummy = { ep_type, NULL, NULL };
01924 ep_node_t *ep_node = NULL;
01925 if (ep_type)
01926 apol_bst_get_element(policy->domain_trans_table->entrypoint_table, (void *)&ep_dummy, NULL, (void **)&ep_node);
01927 dom_node_t end_dummy = { end_dom, NULL, NULL, NULL };
01928 dom_node_t *end_node = NULL;
01929 if (end_dom)
01930 apol_bst_get_element(policy->domain_trans_table->domain_table, (void *)&end_dummy, NULL, (void **)&end_node);
01931
01932 bool tt = false, sx = false, ex = false, pt = false, ep = false;
01933
01934 //find process transition rule
01935 if (start_node && end_dom) {
01936 apol_vector_t *v = find_avrules_in_node(start_node, APOL_DOMAIN_TRANS_RULE_PROC_TRANS, end_dom);
01937 if (apol_vector_get_size(v))
01938 pt = true;
01939 apol_vector_destroy(&v);
01940 }
01941 //find execute rule
01942 if (start_dom && ep_node) {
01943 apol_vector_t *v = find_avrules_in_node(ep_node, APOL_DOMAIN_TRANS_RULE_EXEC, start_dom);
01944 if (apol_vector_get_size(v))
01945 ex = true;
01946 apol_vector_destroy(&v);
01947 }
01948 //find entrypoint rules
01949 if (end_node && ep_type) {
01950 apol_vector_t *v = find_avrules_in_node(end_node, APOL_DOMAIN_TRANS_RULE_ENTRYPOINT, ep_type);
01951 if (apol_vector_get_size(v))
01952 ep = true;
01953 apol_vector_destroy(&v);
01954 }
01955 if (requires_setexec_or_type_trans(policy)) {
01956 //find setexec rule
01957 if (start_node)
01958 if (apol_vector_get_size(start_node->setexec_rules))
01959 sx = true;
01960 //find type_transition rule
01961 if (ep_node && start_dom && end_dom) {
01962 apol_vector_t *v = find_terules_in_node(ep_node, start_dom, end_dom);
01963 if (apol_vector_get_size(v)) {
01964 tt = true;
01965 }
01966 apol_vector_destroy(&v);
01967 }
01968 } else {
01969 //old policy version - pretend these exist
01970 tt = sx = true;
01971 }
01972
01973 if (!(pt && ep && ex && (tt || sx))) {
01974 if (!pt)
01975 missing_rules |= APOL_DOMAIN_TRANS_RULE_PROC_TRANS;
01976 if (!ep)
01977 missing_rules |= APOL_DOMAIN_TRANS_RULE_ENTRYPOINT;
01978 if (!ex)
01979 missing_rules |= APOL_DOMAIN_TRANS_RULE_EXEC;
01980 if (!tt && !sx) {
01981 missing_rules |= APOL_DOMAIN_TRANS_RULE_SETEXEC;
01982 //do not report type_transition as missing if there is one for another entrypoint as this would be invalid
01983 const char *start_name = NULL, *end_name = NULL;
01984 qpol_type_get_name(apol_policy_get_qpol(policy), start_dom, &start_name);
01985 qpol_type_get_name(apol_policy_get_qpol(policy), end_dom, &end_name);
01986 apol_terule_query_t *tq = NULL;
01987 if (!start_name || !end_name || !(tq = apol_terule_query_create())) {
01988 return -1;
01989 }
01990 apol_terule_query_set_rules(policy, tq, QPOL_RULE_TYPE_TRANS);
01991 apol_terule_query_set_source(policy, tq, start_name, 1);
01992 apol_terule_query_set_default(policy, tq, end_name);
01993 apol_vector_t *v = NULL;
01994 if (apol_terule_get_by_query(policy, tq, &v)) {
01995 apol_terule_query_destroy(&tq);
01996 return -1;
01997 }
01998 apol_terule_query_destroy(&tq);
01999 if (!apol_vector_get_size(v))
02000 missing_rules |= APOL_DOMAIN_TRANS_RULE_TYPE_TRANS;
02001 apol_vector_destroy(&v);
02002 }
02003 }
02004
02005 return missing_rules;
02006 }
|
|
|
Do a deep copy (i.e., a clone) of an apol_domain_trans_result_t object. The caller is responsible for calling apol_domain_trans_result_destroy() upon the returned value.
Definition at line 2008 of file domain-trans-analysis.c. References apol_domain_trans_result::access_rules, apol_domain_trans_result_t, apol_vector_create_from_vector(), domain_trans_result_free(), apol_domain_trans_result::end_type, apol_domain_trans_result::ep_rules, apol_domain_trans_result::ep_type, apol_domain_trans_result::exec_rules, apol_domain_trans_result::proc_trans_rules, apol_domain_trans_result::setexec_rules, apol_domain_trans_result::start_type, apol_domain_trans_result::type_trans_rules, and apol_domain_trans_result::valid. Referenced by apol_domain_trans_analysis_do(), apol_types_relation_clone_domaintrans(), domain_trans_table_get_all_forward_trans(), domain_trans_table_get_all_reverse_trans(), and inc_dom_trans_run(). 02009 {
02010 apol_domain_trans_result_t *new_r = NULL;
02011 int retval = -1;
02012 if ((new_r = calloc(1, sizeof(*new_r))) == NULL) {
02013 goto cleanup;
02014 }
02015 if (result->proc_trans_rules != NULL &&
02016 (new_r->proc_trans_rules = apol_vector_create_from_vector(result->proc_trans_rules, NULL, NULL, NULL)) == NULL) {
02017 goto cleanup;
02018 }
02019 if (result->ep_rules != NULL
02020 && (new_r->ep_rules = apol_vector_create_from_vector(result->ep_rules, NULL, NULL, NULL)) == NULL) {
02021 goto cleanup;
02022 }
02023 if (result->exec_rules != NULL
02024 && (new_r->exec_rules = apol_vector_create_from_vector(result->exec_rules, NULL, NULL, NULL)) == NULL) {
02025 goto cleanup;
02026 }
02027 if (result->setexec_rules != NULL
02028 && (new_r->setexec_rules = apol_vector_create_from_vector(result->setexec_rules, NULL, NULL, NULL)) == NULL) {
02029 goto cleanup;
02030 }
02031 if (result->type_trans_rules != NULL &&
02032 (new_r->type_trans_rules = apol_vector_create_from_vector(result->type_trans_rules, NULL, NULL, NULL)) == NULL) {
02033 goto cleanup;
02034 }
02035 if (result->access_rules != NULL
02036 && (new_r->access_rules = apol_vector_create_from_vector(result->access_rules, NULL, NULL, NULL)) == NULL) {
02037 goto cleanup;
02038 }
02039 new_r->start_type = result->start_type;
02040 new_r->ep_type = result->ep_type;
02041 new_r->end_type = result->end_type;
02042 new_r->valid = result->valid;
02043 retval = 0;
02044 cleanup:
02045 if (retval != 0) {
02046 domain_trans_result_free(new_r);
02047 return NULL;
02048 }
02049 return new_r;
02050 }
|
|
|
|
Free all memory used by an apol_domain_trans_result_t object and set it to NULL. This does nothing if the pointer is already NULL. This should only be called for results created by apol_domain_trans_result_create_from_domain_trans_result() and not those returned from within vectors.
Definition at line 2070 of file domain-trans-analysis.c. References apol_domain_trans_result_t, and domain_trans_result_free(). Referenced by domain_trans_result_create(), domain_trans_table_find_orphan_type_transitions(), domain_trans_table_get_all_forward_trans(), domain_trans_table_get_all_reverse_trans(), and dtr_free_wrap(). 02071 {
02072 if (!res || !(*res))
02073 return;
02074 domain_trans_result_free((void *)*res);
02075 *res = NULL;
02076 }
|