policy_extend.h File Reference


Detailed Description

Public interface for loading and using an extended policy image.

Author:
Kevin Carr kcarr@tresys.com

Jeremy A. Mowery jmowery@tresys.com

Jason Tang jtang@tresys.com

Copyright (C) 2006-2007 Tresys Technology, LLC

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 policy_extend.h.

#include <qpol/policy.h>
#include <qpol/iterator.h>

Go to the source code of this file.


Functions

int qpol_policy_build_syn_rule_table (qpol_policy_t *policy)
 Build the table of syntactic rules for a policy.
int qpol_avrule_get_syn_avrule_iter (const qpol_policy_t *policy, const struct qpol_avrule *rule, qpol_iterator_t **iter)
 Get an iterator over the syntactic rules contributing to an av rule.
int qpol_terule_get_syn_terule_iter (const qpol_policy_t *policy, const struct qpol_terule *rule, qpol_iterator_t **iter)
 Get an iterator over the syntactic rules contributing to a type rule.

Function Documentation

int qpol_policy_build_syn_rule_table qpol_policy_t policy  ) 
 

Build the table of syntactic rules for a policy.

Subsequent calls to this function have no effect.

Parameters:
policy The policy for which to build the table. This policy will be modified by this call.
Returns:
0 on success and < 0 on error; if the call fails, errno will be set.

Definition at line 855 of file policy_extend.c.

References qpol_syn_rule_table::buckets, ERR, qpol_policy::ext, INFO, qpol_extended_image::master_list_sz, qpol_syn_rule_node::next, qpol_policy::p, qpol_extended_image_t, qpol_policy_t, qpol_syn_rule_node_t, QPOL_SYN_RULE_TABLE_BITS, qpol_syn_rule_table_destroy(), qpol_syn_rule_table_insert_sepol_avrule(), QPOL_SYN_RULE_TABLE_SIZE, qpol_syn_rule_table_t, qpol_extended_image::syn_rule_master_list, and qpol_extended_image::syn_rule_table.

Referenced by avrule_init(), main(), poldiff_enable_line_numbers(), policy_view_find_terules_runner(), and terule_init().

00856 {
00857         int error = 0, created = 0;
00858         avrule_block_t *cur_block = NULL;
00859         avrule_decl_t *decl = NULL;
00860         avrule_t *cur_rule = NULL;
00861         cond_node_t *cur_cond = NULL, *remapped_cond;
00862 
00863         if (!policy) {
00864                 ERR(policy, "%s", strerror(EINVAL));
00865                 errno = EINVAL;
00866                 return -1;
00867         }
00868 
00869         if (!policy->ext) {
00870                 policy->ext = calloc(1, sizeof(qpol_extended_image_t));
00871                 if (!policy->ext) {
00872                         error = errno;
00873                         ERR(policy, "%s", strerror(error));
00874                         goto err;
00875                 }
00876         }
00877 
00878         if (policy->ext->syn_rule_table)
00879                 return 0;              /* already built */
00880 
00881         policy->ext->syn_rule_table = calloc(1, sizeof(qpol_syn_rule_table_t));
00882         if (!policy->ext->syn_rule_table) {
00883                 error = errno;
00884                 ERR(policy, "%s", strerror(error));
00885                 goto err;
00886         }
00887         policy->ext->syn_rule_table->buckets = calloc(QPOL_SYN_RULE_TABLE_SIZE, sizeof(qpol_syn_rule_node_t *));
00888         if (!policy->ext->syn_rule_table->buckets) {
00889                 error = errno;
00890                 ERR(policy, "%s", strerror(error));
00891                 goto err;
00892         }
00893 
00894         policy->ext->master_list_sz = 0;
00895         for (cur_block = policy->p->p.global; cur_block; cur_block = cur_block->next) {
00896                 decl = cur_block->enabled;
00897                 if (!decl)
00898                         continue;
00899 
00900                 for (cur_rule = decl->avrules; cur_rule; cur_rule = cur_rule->next) {
00901                         policy->ext->master_list_sz++;
00902                 }
00903                 for (cur_cond = decl->cond_list; cur_cond; cur_cond = cur_cond->next) {
00904                         for (cur_rule = cur_cond->avtrue_list; cur_rule; cur_rule = cur_rule->next) {
00905                                 policy->ext->master_list_sz++;
00906                         }
00907                         for (cur_rule = cur_cond->avfalse_list; cur_rule; cur_rule = cur_rule->next) {
00908                                 policy->ext->master_list_sz++;
00909                         }
00910                 }
00911         }
00912 
00913         if (policy->ext->master_list_sz == 0) {
00914                 policy->ext->syn_rule_master_list = NULL;
00915                 return 0;              /* policy is not a source policy */
00916         }
00917 
00918         INFO(policy, "%s", "Building syntactic rules tables.");
00919 
00920         policy->ext->syn_rule_master_list = calloc(policy->ext->master_list_sz, sizeof(struct qpol_syn_rule *));
00921         if (!policy->ext->syn_rule_master_list) {
00922                 error = errno;
00923                 ERR(policy, "%s", strerror(error));
00924                 goto err;
00925         }
00926 
00927         /* reset size as it will represent the current number of elements inserted */
00928         policy->ext->master_list_sz = 0;
00929 
00930         for (cur_block = policy->p->p.global; cur_block; cur_block = cur_block->next) {
00931                 decl = cur_block->enabled;
00932                 if (!decl)
00933                         continue;
00934 
00935                 for (cur_rule = decl->avrules; cur_rule; cur_rule = cur_rule->next) {
00936                         if (qpol_syn_rule_table_insert_sepol_avrule(policy, policy->ext->syn_rule_table, cur_rule, NULL, 0)) {
00937                                 error = errno;
00938                                 goto err;
00939                         }
00940                 }
00941                 for (cur_cond = decl->cond_list; cur_cond; cur_cond = cur_cond->next) {
00942                         /* convert the cond within an avrule_decl to
00943                          * the expanded cond */
00944                         remapped_cond = cond_node_find(&policy->p->p, cur_cond, policy->p->p.cond_list, &created);
00945                         if (created || !remapped_cond) {
00946                                 cond_node_destroy(remapped_cond);
00947                                 error = EIO;
00948                                 ERR(policy, "%s", "Inconsistent conditional records");
00949                                 assert(0);
00950                                 goto err;
00951                         }
00952                         for (cur_rule = cur_cond->avtrue_list; cur_rule; cur_rule = cur_rule->next) {
00953                                 if (qpol_syn_rule_table_insert_sepol_avrule
00954                                     (policy, policy->ext->syn_rule_table, cur_rule, remapped_cond, 0)) {
00955                                         error = errno;
00956                                         goto err;
00957                                 }
00958                         }
00959                         for (cur_rule = cur_cond->avfalse_list; cur_rule; cur_rule = cur_rule->next) {
00960                                 if (qpol_syn_rule_table_insert_sepol_avrule
00961                                     (policy, policy->ext->syn_rule_table, cur_rule, remapped_cond, 1)) {
00962                                         error = errno;
00963                                         goto err;
00964                                 }
00965                         }
00966                 }
00967         }
00968 
00969 #ifdef SETOOLS_DEBUG
00970         /*
00971          * Debugging code to measure the how well the syntactic rules
00972          * are being hashed.  Calculate the min, max, and std
00973          * deviation.
00974          */
00975         size_t bucket;
00976         float o2 = 0.0f;
00977         long total_entries = 0;
00978         for (bucket = 0; bucket < QPOL_SYN_RULE_TABLE_SIZE; bucket++) {
00979                 qpol_syn_rule_node_t *n = policy->ext->syn_rule_table->buckets[bucket];
00980                 while (n != NULL) {
00981                         total_entries++;
00982                         n = n->next;
00983                 }
00984         }
00985         float expected_value = total_entries * 1.0f / QPOL_SYN_RULE_TABLE_SIZE;
00986         size_t min_items = total_entries;
00987         size_t max_items = 0;
00988         for (bucket = 0; bucket < QPOL_SYN_RULE_TABLE_SIZE; bucket++) {
00989                 size_t num_items = 0;
00990                 qpol_syn_rule_node_t *n = policy->ext->syn_rule_table->buckets[bucket];
00991                 while (n != NULL) {
00992                         num_items++;
00993                         n = n->next;
00994                 }
00995                 if (num_items > max_items) {
00996                         max_items = num_items;
00997                 }
00998                 if (num_items < min_items) {
00999                         min_items = num_items;
01000                 }
01001                 o2 += (num_items - expected_value) * (num_items - expected_value);
01002         }
01003         float stddev = sqrtf(o2 / (QPOL_SYN_RULE_TABLE_SIZE - 1));
01004         fprintf(stderr, "libqpol synrule table %d bits:  total entries %lu, expected %g\n", QPOL_SYN_RULE_TABLE_BITS, total_entries,
01005                 expected_value);
01006         fprintf(stderr, "                        min %zd, max %zd, stddev %g\n", min_items, max_items, stddev);
01007 #endif
01008 
01009         return 0;
01010 
01011       err:
01012         if (policy->ext)
01013                 qpol_syn_rule_table_destroy(&policy->ext->syn_rule_table);
01014         errno = error;
01015         return -1;
01016 }

int qpol_avrule_get_syn_avrule_iter const qpol_policy_t policy,
const struct qpol_avrule *  rule,
qpol_iterator_t **  iter
 

Get an iterator over the syntactic rules contributing to an av rule.

Parameters:
policy Policy associated with the rule.
rule Rule from which to get the syntactic rules.
iter Iterator over items of type qpol_syn_avrule_t returned. The caller is responsible for calling qpol_iterator_destroy() to free memory used by this iterator. It is important to note that this iterator is only valid as long as the policy is unmodified.
Returns:
0 on success and < 0 on failure; if the call fails, errno will be set and *iter will be NULL.

Definition at line 1171 of file policy_extend.c.

References qpol_syn_rule_key::class_val, qpol_syn_rule_key::cond, syn_rule_state::cur, ERR, qpol_policy::ext, syn_rule_state::node, qpol_avrule_get_cond(), qpol_avrule_get_object_class(), qpol_avrule_get_rule_type(), qpol_avrule_get_source_type(), qpol_avrule_get_target_type(), qpol_class_get_value(), qpol_class_t, qpol_cond_t, qpol_iterator_create(), qpol_iterator_t, qpol_policy_t, QPOL_RULE_DONTAUDIT, qpol_syn_rule_key_t, qpol_syn_rule_table_find_node_by_key(), qpol_type_get_value(), qpol_type_t, qpol_syn_rule_key::rule_type, qpol_syn_rule_node::rules, qpol_syn_rule_key::source_val, syn_rule_state_end(), syn_rule_state_get_cur(), syn_rule_state_next(), syn_rule_state_size(), syn_rule_state_t, qpol_extended_image::syn_rule_table, and qpol_syn_rule_key::target_val.

Referenced by apol_avrule_list_to_syn_avrules(), apol_avrule_to_syn_avrules(), avrule_enable_line_numbers(), and avrule_get_line_numbers_for_perm().

01172 {
01173         qpol_syn_rule_key_t *key = NULL;
01174         const qpol_type_t *tmp_type;
01175         const qpol_class_t *tmp_class;
01176         const qpol_cond_t *tmp_cond;
01177         syn_rule_state_t *srs = NULL;
01178         uint32_t tmp_val;
01179         int error = 0;
01180 
01181         if (iter)
01182                 *iter = NULL;
01183 
01184         if (!policy || !policy->ext || !rule || !iter) {
01185                 ERR(policy, "%s", strerror(EINVAL));
01186                 errno = EINVAL;
01187                 return -1;
01188         }
01189 
01190         /* build key */
01191         if (!(key = calloc(1, sizeof(qpol_syn_rule_key_t)))) {
01192                 error = errno;
01193                 ERR(policy, "%S", strerror(error));
01194                 goto err;
01195         }
01196 
01197         if (qpol_avrule_get_rule_type(policy, rule, &tmp_val)) {
01198                 error = errno;
01199                 goto err;
01200         }
01201         key->rule_type = (tmp_val == QPOL_RULE_DONTAUDIT ? (AVRULE_AUDITDENY | AVRULE_DONTAUDIT) : tmp_val);
01202 
01203         if (qpol_avrule_get_source_type(policy, rule, &tmp_type)) {
01204                 error = errno;
01205                 goto err;
01206         }
01207         if (qpol_type_get_value(policy, tmp_type, &tmp_val)) {
01208                 error = errno;
01209                 goto err;
01210         }
01211         key->source_val = tmp_val;
01212 
01213         if (qpol_avrule_get_target_type(policy, rule, &tmp_type)) {
01214                 error = errno;
01215                 goto err;
01216         }
01217         if (qpol_type_get_value(policy, tmp_type, &tmp_val)) {
01218                 error = errno;
01219                 goto err;
01220         }
01221         key->target_val = tmp_val;
01222 
01223         if (qpol_avrule_get_object_class(policy, rule, &tmp_class)) {
01224                 error = errno;
01225                 goto err;
01226         }
01227         if (qpol_class_get_value(policy, tmp_class, &tmp_val)) {
01228                 error = errno;
01229                 goto err;
01230         }
01231         key->class_val = tmp_val;
01232 
01233         if (qpol_avrule_get_cond(policy, rule, &tmp_cond)) {
01234                 error = errno;
01235                 goto err;
01236         }
01237         key->cond = (cond_node_t *) tmp_cond;
01238 
01239         /* build state object */
01240         if (!(srs = calloc(1, sizeof(syn_rule_state_t)))) {
01241                 error = errno;
01242                 ERR(policy, "%s", strerror(error));
01243                 goto err;
01244         }
01245 
01246         srs->node = qpol_syn_rule_table_find_node_by_key(policy->ext->syn_rule_table, key);
01247         if (!srs->node) {
01248                 ERR(policy, "%s", "Unable to locate syntactic rules for semantic av rule");
01249                 errno = ENOENT;
01250                 goto err;
01251         }
01252         srs->cur = srs->node->rules;
01253 
01254         if (qpol_iterator_create(policy, (void *)srs,
01255                                  syn_rule_state_get_cur, syn_rule_state_next, syn_rule_state_end, syn_rule_state_size, free, iter))
01256         {
01257                 error = errno;
01258                 goto err;
01259         }
01260 
01261         free(key);
01262 
01263         return 0;
01264 
01265       err:
01266         free(key);
01267         free(srs);
01268         errno = error;
01269         return -1;
01270 }

int qpol_terule_get_syn_terule_iter const qpol_policy_t policy,
const struct qpol_terule *  rule,
qpol_iterator_t **  iter
 

Get an iterator over the syntactic rules contributing to a type rule.

Parameters:
policy Policy associated with the rule.
rule Rule from which to get the syntactic rules.
iter Iterator over items of type qpol_syn_terule_t returned. The caller is responsible for calling qpol_iterator_destroy() to free memory used by this iterator. It is important to note that this iterator is only valid as long as the policy is unmodified.
Returns:
0 on success and < 0 on failure; if the call fails, errno will be set and *iter will be NULL.

Definition at line 1272 of file policy_extend.c.

References qpol_syn_rule_key::class_val, qpol_syn_rule_key::cond, syn_rule_state::cur, ERR, qpol_policy::ext, syn_rule_state::node, qpol_class_get_value(), qpol_class_t, qpol_cond_t, qpol_iterator_create(), qpol_iterator_t, qpol_policy_t, qpol_syn_rule_key_t, qpol_syn_rule_table_find_node_by_key(), qpol_terule_get_cond(), qpol_terule_get_object_class(), qpol_terule_get_rule_type(), qpol_terule_get_source_type(), qpol_terule_get_target_type(), qpol_type_get_value(), qpol_type_t, qpol_syn_rule_key::rule_type, qpol_syn_rule_node::rules, qpol_syn_rule_key::source_val, syn_rule_state_end(), syn_rule_state_get_cur(), syn_rule_state_next(), syn_rule_state_size(), syn_rule_state_t, qpol_extended_image::syn_rule_table, and qpol_syn_rule_key::target_val.

Referenced by apol_terule_list_to_syn_terules(), apol_terule_to_syn_terules(), and terule_enable_line_numbers().

01273 {
01274         qpol_syn_rule_key_t *key = NULL;
01275         const qpol_type_t *tmp_type;
01276         const qpol_class_t *tmp_class;
01277         const qpol_cond_t *tmp_cond;
01278         syn_rule_state_t *srs = NULL;
01279         uint32_t tmp_val;
01280         int error = 0;
01281 
01282         if (iter)
01283                 *iter = NULL;
01284 
01285         if (!policy || !policy->ext || !rule || !iter) {
01286                 ERR(policy, "%s", strerror(EINVAL));
01287                 errno = EINVAL;
01288                 return -1;
01289         }
01290 
01291         /* build key */
01292         if (!(key = calloc(1, sizeof(qpol_syn_rule_key_t)))) {
01293                 error = errno;
01294                 ERR(policy, "%S", strerror(error));
01295                 goto err;
01296         }
01297 
01298         if (qpol_terule_get_rule_type(policy, rule, &tmp_val)) {
01299                 error = errno;
01300                 goto err;
01301         }
01302         key->rule_type = tmp_val;
01303 
01304         if (qpol_terule_get_source_type(policy, rule, &tmp_type)) {
01305                 error = errno;
01306                 goto err;
01307         }
01308         if (qpol_type_get_value(policy, tmp_type, &tmp_val)) {
01309                 error = errno;
01310                 goto err;
01311         }
01312         key->source_val = tmp_val;
01313 
01314         if (qpol_terule_get_target_type(policy, rule, &tmp_type)) {
01315                 error = errno;
01316                 goto err;
01317         }
01318         if (qpol_type_get_value(policy, tmp_type, &tmp_val)) {
01319                 error = errno;
01320                 goto err;
01321         }
01322         key->target_val = tmp_val;
01323 
01324         if (qpol_terule_get_object_class(policy, rule, &tmp_class)) {
01325                 error = errno;
01326                 goto err;
01327         }
01328         if (qpol_class_get_value(policy, tmp_class, &tmp_val)) {
01329                 error = errno;
01330                 goto err;
01331         }
01332         key->class_val = tmp_val;
01333 
01334         if (qpol_terule_get_cond(policy, rule, &tmp_cond)) {
01335                 error = errno;
01336                 goto err;
01337         }
01338         key->cond = (cond_node_t *) tmp_cond;
01339 
01340         /* build state object */
01341         if (!(srs = calloc(1, sizeof(syn_rule_state_t)))) {
01342                 error = errno;
01343                 ERR(policy, "%s", strerror(error));
01344                 goto err;
01345         }
01346 
01347         srs->node = qpol_syn_rule_table_find_node_by_key(policy->ext->syn_rule_table, key);
01348         if (!srs->node) {
01349                 ERR(policy, "%s", "Unable to locate syntactic rules for semantic te rule");
01350                 error = ENOENT;
01351                 goto err;
01352         }
01353         srs->cur = srs->node->rules;
01354 
01355         if (qpol_iterator_create(policy, (void *)srs,
01356                                  syn_rule_state_get_cur, syn_rule_state_next, syn_rule_state_end, syn_rule_state_size, free, iter))
01357         {
01358                 error = errno;
01359                 goto err;
01360         }
01361 
01362         free(key);
01363 
01364         return 0;
01365 
01366       err:
01367         free(key);
01368         free(srs);
01369         errno = error;
01370         return -1;
01371 }