Boolean: Convert to direct sepol structure access. Add iterator.

This commit is contained in:
Chris PeBenito 2018-02-11 10:48:18 -05:00
parent 680664ba66
commit 8260b9b166
5 changed files with 39 additions and 212 deletions

View File

@ -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 <stddef.h>
#include <stdlib.h>
#include <stdint.h>
#include <qpol/iterator.h>
#include <sepol/policydb.h>
#include <sepol/policydb/policydb.h>
#include <sepol/policydb/expand.h>
#include "iterator_internal.h"
#include <qpol/bool_query.h>
#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;
}

View File

@ -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, <const qpol_bool_t *> 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, <sepol.cond_bool_datum_t *>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 <bint> 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, <sepol.cond_bool_datum_t *>self.curr.datum)

View File

@ -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:

View File

@ -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.)"""

View File

@ -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',