From 8260b9b166f345de9a550f5e3e1f071684beb7fd Mon Sep 17 00:00:00 2001 From: Chris PeBenito Date: Sun, 11 Feb 2018 10:48:18 -0500 Subject: [PATCH] Boolean: Convert to direct sepol structure access. Add iterator. --- libqpol/bool_query.c | 156 ---------------------------- setools/policyrep/boolcond.pxi | 75 ++++++------- setools/policyrep/libpolicyrep.pyx | 7 -- setools/policyrep/selinuxpolicy.pxi | 12 +-- setup.py | 1 - 5 files changed, 39 insertions(+), 212 deletions(-) delete mode 100644 libqpol/bool_query.c diff --git a/libqpol/bool_query.c b/libqpol/bool_query.c deleted file mode 100644 index 71ca659..0000000 --- a/libqpol/bool_query.c +++ /dev/null @@ -1,156 +0,0 @@ -/** - * @file - * Implementation of the interface for searching and iterating over booleans. - * - * @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 -#include -#include -#include -#include -#include -#include -#include "iterator_internal.h" -#include -#include "qpol_internal.h" - -int qpol_policy_get_bool_by_name(const qpol_policy_t * policy, const char *name, qpol_bool_t ** datum) -{ - hashtab_datum_t internal_datum; - policydb_t *db; - - if (policy == NULL || name == NULL || datum == NULL) { - if (datum != NULL) - *datum = NULL; - ERR(policy, "%s", strerror(EINVAL)); - errno = EINVAL; - return STATUS_ERR; - } - - db = &policy->p->p; - internal_datum = hashtab_search(db->p_bools.table, (hashtab_key_t)name); - if (internal_datum == NULL) { - ERR(policy, "could not find datum for bool %s", name); - *datum = NULL; - errno = ENOENT; - return STATUS_ERR; - } - *datum = (qpol_bool_t *) internal_datum; - - return STATUS_SUCCESS; -} - -int qpol_policy_get_bool_iter(const qpol_policy_t * policy, qpol_iterator_t ** iter) -{ - policydb_t *db; - hash_state_t *hs = NULL; - int error = 0; - - if (policy == NULL || iter == NULL) { - if (iter != NULL) - *iter = NULL; - ERR(policy, "%s", strerror(EINVAL)); - errno = EINVAL; - return STATUS_ERR; - } - - db = &policy->p->p; - - hs = calloc(1, sizeof(hash_state_t)); - if (hs == NULL) { - error = errno; - ERR(policy, "%s", strerror(ENOMEM)); - errno = error; - return STATUS_ERR; - } - hs->table = &db->p_bools.table; - hs->node = (*(hs->table))->htable[0]; - - if (qpol_iterator_create(policy, (void *)hs, hash_state_get_cur, - hash_state_next, hash_state_end, hash_state_size, free, iter)) { - free(hs); - return STATUS_ERR; - } - - if (hs->node == NULL) - hash_state_next(*iter); - - return STATUS_SUCCESS; -} - -int qpol_bool_get_value(const qpol_policy_t * policy, const qpol_bool_t * datum, uint32_t * value) -{ - cond_bool_datum_t *internal_datum; - - if (policy == NULL || datum == NULL || value == NULL) { - if (value != NULL) - *value = 0; - ERR(policy, "%s", strerror(EINVAL)); - errno = EINVAL; - return STATUS_ERR; - } - - internal_datum = (cond_bool_datum_t *) datum; - *value = internal_datum->s.value; - - return STATUS_SUCCESS; -} - -int qpol_bool_get_state(const qpol_policy_t * policy, const qpol_bool_t * datum, int *state) -{ - cond_bool_datum_t *internal_datum; - - if (policy == NULL || datum == NULL || state == NULL) { - if (state != NULL) - *state = 0; - ERR(policy, "%s", strerror(EINVAL)); - errno = EINVAL; - return STATUS_ERR; - } - - internal_datum = (cond_bool_datum_t *) datum; - *state = internal_datum->state; - - return STATUS_SUCCESS; -} - -int qpol_bool_get_name(const qpol_policy_t * policy, const qpol_bool_t * datum, const char **name) -{ - cond_bool_datum_t *internal_datum = NULL; - policydb_t *db = NULL; - - if (policy == NULL || datum == NULL || name == NULL) { - if (name != NULL) - *name = NULL; - ERR(policy, "%s", strerror(EINVAL)); - errno = EINVAL; - return STATUS_ERR; - } - - db = &policy->p->p; - internal_datum = (cond_bool_datum_t *) datum; - - *name = db->p_bool_val_to_name[internal_datum->s.value - 1]; - - return STATUS_SUCCESS; -} diff --git a/setools/policyrep/boolcond.pxi b/setools/policyrep/boolcond.pxi index 57d7450..ec58baf 100644 --- a/setools/policyrep/boolcond.pxi +++ b/setools/policyrep/boolcond.pxi @@ -24,31 +24,6 @@ from collections import namedtuple truth_table_row = namedtuple("truth_table_row", ["values", "result"]) -# -# Boolean factory functions -# -cdef inline Boolean boolean_factory_lookup(SELinuxPolicy policy, str name): - """Factory function variant for constructing Boolean objects by name.""" - - cdef qpol_bool_t *symbol; - if qpol_policy_get_bool_by_name(policy.handle, name.encode(), &symbol): - raise InvalidBoolean("{0} is not a valid Boolean".format(name)) - - return boolean_factory(policy, symbol) - - -cdef inline Boolean boolean_factory_iter(SELinuxPolicy policy, QpolIteratorItem symbol): - """Factory function variant for iterating over Boolean objects.""" - return boolean_factory(policy, symbol.obj) - - -cdef inline Boolean boolean_factory(SELinuxPolicy policy, const qpol_bool_t *symbol): - """Factory function for creating Boolean objects.""" - r = Boolean() - r.policy = policy - r.handle = symbol - return r - # # Conditional expression factory functions # @@ -93,7 +68,7 @@ cdef inline object conditional_node_factory_iter(SELinuxPolicy policy, QpolItera ex.errno = errno raise ex - return boolean_factory(policy, b) + return Boolean.factory(policy, b) else: return conditional_op_factory(policy, symbol) @@ -114,17 +89,18 @@ cdef class Boolean(PolicySymbol): """A Boolean.""" - cdef const qpol_bool_t *handle + cdef sepol.cond_bool_datum_t *handle + + @staticmethod + cdef factory(SELinuxPolicy policy, sepol.cond_bool_datum_t *symbol): + """Factory function for creating Boolean objects.""" + r = Boolean() + r.policy = policy + r.handle = symbol + return r def __str__(self): - cdef const char *name - - if qpol_bool_get_name(self.policy.handle, self.handle, &name): - ex = LowLevelPolicyError("Error reading Boolean name: {}".format(strerror(errno))) - ex.errno = errno - raise ex - - return intern(name) + return intern(self.policy.handle.p.p.sym_val_to_name[sepol.SYM_BOOLS][self.handle.s.value - 1]) def _eq(self, Boolean other): """Low-level equality check (C pointers).""" @@ -133,13 +109,7 @@ cdef class Boolean(PolicySymbol): @property def state(self): """The default state of the Boolean.""" - cdef int s - if qpol_bool_get_state(self.policy.handle, self.handle, &s): - ex = LowLevelPolicyError("Error reading boolean state: {}".format(strerror(errno))) - ex.errno = errno - raise ex - - return bool(s) + return self.handle.state def statement(self): """The policy statement.""" @@ -403,3 +373,24 @@ cdef class ConditionalOperator(PolicySymbol): def unary(self): """T/F the operator is unary""" return self._type == QPOL_COND_EXPR_NOT + + +# +# Iterators +# +cdef class BooleanHashtabIterator(HashtabIterator): + + """Iterate over Booleans in the policy.""" + + @staticmethod + cdef factory(SELinuxPolicy policy, sepol.hashtab_t *table): + """Factory function for creating Boolean iterators.""" + i = BooleanHashtabIterator() + i.policy = policy + i.table = table + i.reset() + return i + + def __next__(self): + super().__next__() + return Boolean.factory(self.policy, self.curr.datum) diff --git a/setools/policyrep/libpolicyrep.pyx b/setools/policyrep/libpolicyrep.pyx index 4ac4a14..0271e35 100644 --- a/setools/policyrep/libpolicyrep.pyx +++ b/setools/policyrep/libpolicyrep.pyx @@ -80,13 +80,6 @@ cdef extern from "include/qpol/avrule_query.h": cdef extern from "include/qpol/bool_query.h": ctypedef struct qpol_bool_t: pass - int qpol_policy_get_bool_by_name(const qpol_policy_t * policy, const char *name, qpol_bool_t ** datum) - int qpol_policy_get_bool_iter(const qpol_policy_t * policy, qpol_iterator_t ** iter) - int qpol_bool_get_value(const qpol_policy_t * policy, const qpol_bool_t * datum, uint32_t * value) - int qpol_bool_get_state(const qpol_policy_t * policy, const qpol_bool_t * datum, int *state) - int qpol_bool_set_state(qpol_policy_t * policy, qpol_bool_t * datum, int state) - int qpol_bool_set_state_no_eval(qpol_policy_t * policy, qpol_bool_t * datum, int state) - int qpol_bool_get_name(const qpol_policy_t * policy, const qpol_bool_t * datum, const char **name) cdef extern from "include/qpol/bounds_query.h": ctypedef struct qpol_typebounds_t: diff --git a/setools/policyrep/selinuxpolicy.pxi b/setools/policyrep/selinuxpolicy.pxi index 03bb265..b337992 100644 --- a/setools/policyrep/selinuxpolicy.pxi +++ b/setools/policyrep/selinuxpolicy.pxi @@ -429,7 +429,11 @@ cdef class SELinuxPolicy: # def lookup_boolean(self, name): """Look up a Boolean.""" - return boolean_factory_lookup(self, name) + for b in self.bools(): + if b == name: + return b + + raise InvalidBoolean("{0} is not a valid Boolean".format(name)) def lookup_class(self, name): """Look up an object class.""" @@ -484,11 +488,7 @@ cdef class SELinuxPolicy: # def bools(self): """Iterator which yields all Booleans.""" - cdef qpol_iterator_t *iter - if qpol_policy_get_bool_iter(self.handle, &iter): - raise MemoryError - - return qpol_iterator_factory(self, iter, boolean_factory_iter) + return BooleanHashtabIterator.factory(self, &self.handle.p.p.symtab[sepol.SYM_BOOLS].table) def bounds(self): """Iterator which yields all *bounds statements (typebounds, etc.)""" diff --git a/setup.py b/setup.py index 4bcf5e2..209acc1 100644 --- a/setup.py +++ b/setup.py @@ -67,7 +67,6 @@ else: ext_py_mods = [Extension('setools.policyrep.libpolicyrep', ['setools/policyrep/libpolicyrep.pyx', 'libqpol/avrule_query.c', - 'libqpol/bool_query.c', 'libqpol/bounds_query.c', 'libqpol/class_perm_query.c', 'libqpol/cond_query.c',