From 23d42f162fc6ddaf70c89738caa27b09309d2207 Mon Sep 17 00:00:00 2001 From: Chris PeBenito <pebenito@ieee.org> Date: Tue, 13 Feb 2018 19:28:43 -0500 Subject: [PATCH] MLSRule: Convert to direct sepol structure access. Add iterator. --- libqpol/mlsrule_query.c | 276 ---------------------------- setools/policyrep/libpolicyrep.pyx | 29 --- setools/policyrep/mlsrule.pxi | 84 ++++----- setools/policyrep/selinuxpolicy.pxi | 6 +- setup.py | 1 - 5 files changed, 43 insertions(+), 353 deletions(-) delete mode 100644 libqpol/mlsrule_query.c diff --git a/libqpol/mlsrule_query.c b/libqpol/mlsrule_query.c deleted file mode 100644 index 19e93bc..0000000 --- a/libqpol/mlsrule_query.c +++ /dev/null @@ -1,276 +0,0 @@ -/** - * @file - * Implementation for the public interface for searching and iterating over - * range transition rules. - * - * @author Kevin Carr kcarr@tresys.com - * @author Jeremy A. Mowery jmowery@tresys.com - * @author 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 - */ - -#include "iterator_internal.h" -#include <qpol/iterator.h> -#include <qpol/policy.h> -#include <qpol/mlsrule_query.h> -#include <sepol/policydb/policydb.h> -#include <sepol/policydb/avtab.h> -#include <sepol/policydb/util.h> -#include <stdlib.h> -#include "qpol_internal.h" - -typedef struct range_trans_state -{ - unsigned int bucket; - hashtab_ptr_t cur_item; - range_trans_t *cur; -} range_trans_state_t; - -static int range_trans_state_end(const qpol_iterator_t * iter) -{ - range_trans_state_t *rs = NULL; - - if (!iter || !(rs = qpol_iterator_state(iter))) { - errno = EINVAL; - return STATUS_ERR; - } - - return rs->cur ? 0 : 1; -} - -static void *range_trans_state_get_cur(const qpol_iterator_t * iter) -{ - range_trans_state_t *rs = NULL; - const policydb_t *db = NULL; - - if (!iter || !(rs = qpol_iterator_state(iter)) || !(db = qpol_iterator_policy(iter))) { - errno = EINVAL; - return NULL; - } - - return rs->cur; -} - -static int range_trans_state_next(qpol_iterator_t * iter) -{ - range_trans_state_t *rs = NULL; - const policydb_t *db = NULL; - - if (!iter || !(rs = qpol_iterator_state(iter)) || !(db = qpol_iterator_policy(iter))) { - errno = EINVAL; - return STATUS_ERR; - } - - if (range_trans_state_end(iter)) { - errno = EINVAL; - return STATUS_ERR; - } - - rs->cur_item = rs->cur_item->next; - while (rs->cur_item == NULL) { - rs->bucket++; - if (rs->bucket >= db->range_tr->size) { - break; - } - - rs->cur_item = db->range_tr->htable[rs->bucket]; - } - - if (rs->cur_item == NULL) { - rs->cur = NULL; - } else { - rs->cur = (range_trans_t*)rs->cur_item->key; - } - - return STATUS_SUCCESS; -} - -static size_t range_trans_state_size(const qpol_iterator_t * iter) -{ - range_trans_state_t *rs = NULL; - const policydb_t *db = NULL; - size_t count = 0; - unsigned int i = 0; - - if (!iter || !(rs = qpol_iterator_state(iter)) || !(db = qpol_iterator_policy(iter))) { - errno = EINVAL; - return 0; - } - - hashtab_ptr_t cur = NULL; - for (i = 0; i < db->range_tr->size; i++) { - cur = db->range_tr->htable[i]; - while (cur != NULL) { - count++; - cur = cur->next; - } - } - - return count; -} - -int qpol_policy_get_range_trans_iter(const qpol_policy_t * policy, qpol_iterator_t ** iter) -{ - policydb_t *db = NULL; - range_trans_state_t *rs = NULL; - int error = 0; - - if (iter) - *iter = NULL; - - if (!policy || !iter) { - ERR(policy, "%s", strerror(EINVAL)); - errno = EINVAL; - return STATUS_ERR; - } - - db = &policy->p->p; - - rs = calloc(1, sizeof(range_trans_state_t)); - if (!rs) { - error = errno; - ERR(policy, "%s", strerror(error)); - errno = error; - return STATUS_ERR; - } - - if (qpol_iterator_create(policy, (void *)rs, range_trans_state_get_cur, - range_trans_state_next, range_trans_state_end, range_trans_state_size, free, iter)) { - error = errno; - free(rs); - errno = error; - return STATUS_ERR; - } - - rs->bucket = 0; - rs->cur_item = db->range_tr->htable[0]; - rs->cur = NULL; - - rs->cur_item = db->range_tr->htable[rs->bucket]; - while (rs->cur_item == NULL) { - rs->bucket++; - if (rs->bucket >= db->range_tr->size) { - break; - } - - rs->cur_item = db->range_tr->htable[rs->bucket]; - } - - if (rs->cur_item != NULL) { - rs->cur = (range_trans_t*)rs->cur_item->key; - } - - return STATUS_SUCCESS; -} - -int qpol_range_trans_get_source_type(const qpol_policy_t * policy, const qpol_range_trans_t * rule, const qpol_type_t ** source) -{ - policydb_t *db = NULL; - range_trans_t *rt = NULL; - - if (source) { - *source = NULL; - } - - if (!policy || !rule || !source) { - errno = EINVAL; - ERR(policy, "%s", strerror(EINVAL)); - return STATUS_ERR; - } - - db = &policy->p->p; - rt = (range_trans_t *) rule; - - *source = (qpol_type_t *) db->type_val_to_struct[rt->source_type - 1]; - - return STATUS_SUCCESS; -} - -int qpol_range_trans_get_target_type(const qpol_policy_t * policy, const qpol_range_trans_t * rule, const qpol_type_t ** target) -{ - policydb_t *db = NULL; - range_trans_t *rt = NULL; - - if (target) { - *target = NULL; - } - - if (!policy || !rule || !target) { - ERR(policy, "%s", strerror(EINVAL)); - errno = EINVAL; - return STATUS_ERR; - } - - db = &policy->p->p; - rt = (range_trans_t *) rule; - - *target = (qpol_type_t *) db->type_val_to_struct[rt->target_type - 1]; - - return STATUS_SUCCESS; -} - -int qpol_range_trans_get_target_class(const qpol_policy_t * policy, const qpol_range_trans_t * rule, const qpol_class_t ** target) -{ - policydb_t *db = NULL; - range_trans_t *rt = NULL; - - if (target) { - *target = NULL; - } - - if (!policy || !rule || !target) { - ERR(policy, "%s", strerror(EINVAL)); - errno = EINVAL; - return STATUS_ERR; - } - - db = &policy->p->p; - rt = (range_trans_t *) rule; - - *target = (qpol_class_t *) db->class_val_to_struct[rt->target_class - 1]; - - return STATUS_SUCCESS; -} - -int qpol_range_trans_get_range(const qpol_policy_t * policy, const qpol_range_trans_t * rule, const qpol_mls_range_t ** range) -{ - range_trans_t *rt = NULL; - - if (range) { - *range = NULL; - } - - if (!policy || !rule || !range) { - ERR(policy, "%s", strerror(EINVAL)); - errno = EINVAL; - return STATUS_ERR; - } - - policydb_t *db = &policy->p->p; - rt = (range_trans_t *) rule; - mls_range_t *target_range = NULL; - - target_range = hashtab_search(db->range_tr, (hashtab_key_t)rt); - if (target_range == NULL) { - return STATUS_ERR; - } - - *range = (qpol_mls_range_t *)target_range; - - return STATUS_SUCCESS; -} diff --git a/setools/policyrep/libpolicyrep.pyx b/setools/policyrep/libpolicyrep.pyx index c03f88f..a21a677 100644 --- a/setools/policyrep/libpolicyrep.pyx +++ b/setools/policyrep/libpolicyrep.pyx @@ -176,14 +176,6 @@ cdef extern from "include/qpol/constraint_query.h": int qpol_class_get_constraint_iter(const qpol_policy_t * policy, const qpol_class_t * obj_class, qpol_iterator_t ** constr) int qpol_class_get_validatetrans_iter(const qpol_policy_t * policy, const qpol_class_t * obj_class, qpol_iterator_t ** vtrans) -cdef extern from "include/qpol/context_query.h": - ctypedef struct qpol_context_t: - pass - int qpol_context_get_user(const qpol_policy_t * policy, const qpol_context_t * context, const qpol_user_t ** user) - int qpol_context_get_role(const qpol_policy_t * policy, const qpol_context_t * context, const qpol_role_t ** role) - int qpol_context_get_type(const qpol_policy_t * policy, const qpol_context_t * context, const qpol_type_t ** type) - int qpol_context_get_range(const qpol_policy_t * policy, const qpol_context_t * context, const qpol_mls_range_t ** range) - cdef extern from "include/qpol/ftrule_query.h": ctypedef struct qpol_filename_trans_t: pass @@ -203,27 +195,6 @@ cdef extern from "include/qpol/iterator.h": int qpol_iterator_end(const qpol_iterator_t * iter) int qpol_iterator_get_size(const qpol_iterator_t * iter, size_t * size) -cdef extern from "include/qpol/mls_query.h": - ctypedef struct qpol_level_t: - pass - ctypedef struct qpol_cat_t: - pass - ctypedef struct qpol_mls_range_t: - pass - ctypedef struct qpol_mls_level_t: - pass - ctypedef struct qpol_semantic_level_t: - pass - -cdef extern from "include/qpol/mlsrule_query.h": - ctypedef struct qpol_range_trans_t: - pass - int qpol_policy_get_range_trans_iter(const qpol_policy_t * policy, qpol_iterator_t ** iter) - int qpol_range_trans_get_source_type(const qpol_policy_t * policy, const qpol_range_trans_t * rule, const qpol_type_t ** source) - int qpol_range_trans_get_target_type(const qpol_policy_t * policy, const qpol_range_trans_t * rule, const qpol_type_t ** target) - int qpol_range_trans_get_target_class(const qpol_policy_t * policy, const qpol_range_trans_t * rule, const qpol_class_t ** target) - int qpol_range_trans_get_range(const qpol_policy_t * policy, const qpol_range_trans_t * rule, const qpol_mls_range_t ** range) - cdef extern from "qpol_internal.h": ctypedef struct qpol_policy_t: sepol.sepol_policydb *p diff --git a/setools/policyrep/mlsrule.pxi b/setools/policyrep/mlsrule.pxi index cc9e889..139d6ed 100644 --- a/setools/policyrep/mlsrule.pxi +++ b/setools/policyrep/mlsrule.pxi @@ -1,5 +1,5 @@ # Copyright 2014, 2016, Tresys Technology, LLC -# Copyright 2016-2017, Chris PeBenito <pebenito@ieee.org> +# Copyright 2016-2018, Chris PeBenito <pebenito@ieee.org> # # This file is part of SETools. # @@ -19,41 +19,6 @@ # import itertools -# -# MLS rule factory functions -# -cdef inline MLSRule mls_rule_factory_iter(SELinuxPolicy policy, QpolIteratorItem symbol): - """Factory function variant for iterating over MLSRule objects.""" - return mls_rule_factory(policy, <const qpol_range_trans_t *> symbol.obj) - - -cdef inline MLSRule mls_rule_factory(SELinuxPolicy policy, const qpol_range_trans_t *symbol): - """Factory function for creating MLSRule objects.""" - r = MLSRule() - r.policy = policy - r.handle = symbol - return r - - -# -# Expanded MLS rule factory function -# -cdef inline ExpandedMLSRule expanded_mls_rule_factory(MLSRule original, source, target): - """ - Factory function for creating expanded MLS rules. - - original The MLS rule the expanded rule originates from. - source The source type of the expanded rule. - target The target type of the expanded rule. - """ - r = ExpandedMLSRule() - r.policy = original.policy - r.handle = original.handle - r.source = source - r.target = target - r.origin = original - return r - class MLSRuletype(PolicyEnum): @@ -68,10 +33,20 @@ cdef class MLSRule(PolicyRule): cdef: sepol.range_trans_t *handle + object rng readonly object ruletype - def __init__(self): + @staticmethod + cdef factory(SELinuxPolicy policy, sepol.range_trans_t *symbol, sepol.mls_range_t *rng): + """Factory function for creating MLSRule objects.""" + r = MLSRule(Range.factory(policy, rng)) + r.policy = policy + r.handle = symbol + return r + + def __init__(self, rng): self.ruletype = MLSRuletype.range_transition + self.rng = rng def __str__(self): return "{0.ruletype} {0.source} {0.target}:{0.tclass} {0.default};".format(self) @@ -98,15 +73,18 @@ cdef class MLSRule(PolicyRule): @property def default(self): """The rule's default range.""" - cdef sepol.mls_range_t *default_range - default_range = <sepol.mls_range_t *> hashtab_search(self.policy.handle.p.p.range_tr, - <sepol.hashtab_key_t> self.handle) - return Range.factory(self.policy, default_range) + return self.rng def expand(self): """Expand the rule into an equivalent set of rules without attributes.""" for s, t in itertools.product(self.source.expand(), self.target.expand()): - yield expanded_mls_rule_factory(self, s, t) + r = ExpandedMLSRule(self.rng) + r.policy = self.policy + r.handle = self.handle + r.source = s + r.target = t + r.origin = self + yield r cdef class ExpandedMLSRule(MLSRule): @@ -131,3 +109,25 @@ cdef class ExpandedMLSRule(MLSRule): def __lt__(self, other): return str(self) < str(other) + + +# +# Iterators +# +cdef class MLSRuleIterator(HashtabIterator): + + """Iterate over MLS rules in the policy.""" + + @staticmethod + cdef factory(SELinuxPolicy policy, sepol.hashtab_t *table): + """Factory function for creating MLS rule iterators.""" + i = MLSRuleIterator() + i.policy = policy + i.table = table + i.reset() + return i + + def __next__(self): + super().__next__() + return MLSRule.factory(self.policy, <sepol.range_trans_t *>self.curr.key, + <sepol.mls_range_t *>self.curr.datum) diff --git a/setools/policyrep/selinuxpolicy.pxi b/setools/policyrep/selinuxpolicy.pxi index 64c22a2..d72dead 100644 --- a/setools/policyrep/selinuxpolicy.pxi +++ b/setools/policyrep/selinuxpolicy.pxi @@ -608,11 +608,7 @@ cdef class SELinuxPolicy: def mlsrules(self): """Iterator over all MLS rules.""" - cdef qpol_iterator_t *iter - if qpol_policy_get_range_trans_iter(self.handle, &iter): - raise MemoryError - - return qpol_iterator_factory(self, iter, mls_rule_factory_iter) + return MLSRuleIterator.factory(self, &self.handle.p.p.range_tr) def rbacrules(self): """Iterator over all RBAC rules.""" diff --git a/setup.py b/setup.py index 5ef474c..de2ece9 100644 --- a/setup.py +++ b/setup.py @@ -73,7 +73,6 @@ ext_py_mods = [Extension('setools.policyrep.libpolicyrep', 'libqpol/constraint_query.c', 'libqpol/ftrule_query.c', 'libqpol/iterator.c', - 'libqpol/mlsrule_query.c', 'libqpol/policy.c', 'libqpol/policy_extend.c', 'libqpol/rbacrule_query.c',