Common/ObjClass: Refactor to load attributes on construction.

This commit is contained in:
Chris PeBenito 2018-08-06 15:48:52 -04:00
parent 55a1ff884e
commit 55f4e666ee

View File

@ -30,29 +30,33 @@ cdef class Common(PolicySymbol):
"""A common permission set.""" """A common permission set."""
cdef: cdef:
sepol.common_datum_t *handle uintptr_t key
str name
readonly dict _perm_table readonly dict _perm_table
@staticmethod @staticmethod
cdef factory(SELinuxPolicy policy, sepol.common_datum_t *symbol): cdef inline Common factory(SELinuxPolicy policy, sepol.common_datum_t *symbol):
"""Factory function for creating Common objects.""" """Factory function for creating Common objects."""
cdef: cdef:
Common c
sepol.hashtab_node_t *node sepol.hashtab_node_t *node
uint32_t bucket = 0 uint32_t bucket = 0
str key str key
uint32_t value uint32_t value
dict perm_table
try: try:
return _common_cache[<uintptr_t>symbol] return _common_cache[<uintptr_t>symbol]
except KeyError: except KeyError:
c = Common() c = Common.__new__(Common)
c.policy = policy c.policy = policy
c.handle = symbol c.key = <uintptr_t>symbol
c._perm_table = {} c.name = policy.common_value_to_name(symbol.s.value - 1)
# #
# Create value:name permission table (reverse of what is in the policydb) # Create value:name permission table (reverse of what is in the policydb)
# #
c._perm_table = {}
while bucket < symbol.permissions.table[0].size: while bucket < symbol.permissions.table[0].size:
node = symbol.permissions.table[0].htable[bucket] node = symbol.permissions.table[0].htable[bucket]
while node != NULL: while node != NULL:
@ -67,11 +71,11 @@ cdef class Common(PolicySymbol):
return c return c
def __str__(self): def __str__(self):
return self.policy.common_value_to_name(self.handle.s.value - 1) return self.name
def _eq(self, Common other): def _eq(self, Common other):
"""Low-level equality check (C pointers).""" """Low-level equality check (C pointers)."""
return self.handle == other.handle return self.key == other.key
def __contains__(self, other): def __contains__(self, other):
return other in self.perms return other in self.perms
@ -90,24 +94,49 @@ cdef class ObjClass(PolicySymbol):
"""An object class.""" """An object class."""
cdef: cdef:
sepol.class_datum_t *handle uintptr_t key
str name
Common _common
readonly dict _perm_table readonly dict _perm_table
list _defaults
list _constraints
list _validatetrans
# class_datum_t->permissions.nprim
# is needed for the permission iterator
uint32_t nprim
@staticmethod @staticmethod
cdef factory(SELinuxPolicy policy, sepol.class_datum_t *symbol): cdef inline ObjClass factory(SELinuxPolicy policy, sepol.class_datum_t *symbol):
"""Factory function for creating ObjClass objects.""" """Factory function for creating ObjClass objects."""
cdef: cdef:
sepol.hashtab_node_t *node sepol.hashtab_node_t *node
uint32_t bucket = 0 uint32_t bucket = 0
str key str key
uint32_t value uint32_t value
dict perm_table
object com
ObjClass c
try: try:
return _objclass_cache[<uintptr_t>symbol] return _objclass_cache[<uintptr_t>symbol]
except KeyError: except KeyError:
c = ObjClass() #
# Instantiate object class
#
c = ObjClass.__new__(ObjClass)
c.policy = policy c.policy = policy
c.handle = symbol c.key = <uintptr_t>symbol
c.nprim = symbol.permissions.nprim
c.name = policy.class_value_to_name(symbol.s.value - 1)
c._validatetrans = list(ValidatetransIterator.factory(policy, c, symbol.validatetrans))
c._constraints = list(ConstraintIterator.factory(policy, c, symbol.constraints))
#
# Load common
#
if symbol.comdatum:
c._common = Common.factory(policy, symbol.comdatum)
c._perm_table = {} c._perm_table = {}
# #
@ -116,18 +145,34 @@ cdef class ObjClass(PolicySymbol):
while bucket < symbol.permissions.table[0].size: while bucket < symbol.permissions.table[0].size:
node = symbol.permissions.table[0].htable[bucket] node = symbol.permissions.table[0].htable[bucket]
while node != NULL: while node != NULL:
key = intern(node.key) key = intern(<char *>node.key)
value = (<sepol.perm_datum_t *>node.datum).s.value value = (<sepol.perm_datum_t *>node.datum).s.value
c._perm_table[value] = key c._perm_table[value] = key
node = node.next node = node.next
bucket += 1 bucket += 1
#
# Load defaults
#
c._defaults = []
if symbol.default_user:
c._defaults.append(Default.factory(policy, c, symbol.default_user, None, None, None))
if symbol.default_role:
c._defaults.append(Default.factory(policy, c, None, symbol.default_role, None, None))
if symbol.default_type:
c._defaults.append(Default.factory(policy, c, None, None, symbol.default_type, None))
if symbol.default_range:
c._defaults.append(Default.factory(policy, c, None, None, None, symbol.default_range))
_objclass_cache[<uintptr_t>symbol] = c _objclass_cache[<uintptr_t>symbol] = c
return c return c
def __str__(self): def __str__(self):
return self.policy.class_value_to_name(self.handle.s.value - 1) return self.name
def __contains__(self, other): def __contains__(self, other):
try: try:
@ -140,7 +185,7 @@ cdef class ObjClass(PolicySymbol):
def _eq(self, ObjClass other): def _eq(self, ObjClass other):
"""Low-level equality check (C pointers).""" """Low-level equality check (C pointers)."""
return self.handle == other.handle return self.key == other.key
@property @property
def common(self): def common(self):
@ -150,28 +195,18 @@ cdef class ObjClass(PolicySymbol):
Exceptions: Exceptions:
NoCommon The object class does not inherit a common. NoCommon The object class does not inherit a common.
""" """
if self.handle.comdatum: if self._common:
return Common.factory(self.policy, self.handle.comdatum) return self._common
else: else:
raise NoCommon("{0} does not inherit a common.".format(self)) raise NoCommon("{0} does not inherit a common.".format(self.name))
def constraints(self): def constraints(self):
"""Iterator for the constraints that apply to this class.""" """Iterator for the constraints that apply to this class."""
return ConstraintIterator.factory(self.policy, self, self.handle.constraints) return iter(self._constraints)
def defaults(self): def defaults(self):
"""Iterator for the defaults for this object class.""" """Iterator for the defaults for this object class."""
if self.handle.default_user: return iter(self._defaults)
yield Default.factory(self.policy, self, self.handle.default_user, None, None, None)
if self.handle.default_role:
yield Default.factory(self.policy, self, None, self.handle.default_role, None, None)
if self.handle.default_type:
yield Default.factory(self.policy, self, None, None, self.handle.default_type, None)
if self.handle.default_range:
yield Default.factory(self.policy, self, None, None, None, self.handle.default_range)
@property @property
def perms(self): def perms(self):
@ -179,7 +214,7 @@ cdef class ObjClass(PolicySymbol):
return set(self._perm_table.values()) return set(self._perm_table.values())
def statement(self): def statement(self):
stmt = "class {0}\n".format(self) stmt = "class {0}\n".format(self.name)
try: try:
stmt += "inherits {0}\n".format(self.common) stmt += "inherits {0}\n".format(self.common)
@ -195,7 +230,7 @@ cdef class ObjClass(PolicySymbol):
def validatetrans(self): def validatetrans(self):
"""Iterator for validatetrans that apply to this class.""" """Iterator for validatetrans that apply to this class."""
return ValidatetransIterator.factory(self.policy, self, self.handle.validatetrans) return iter(self._validatetrans)
# #
@ -253,7 +288,7 @@ cdef class PermissionVectorIterator(PolicyIterator):
i = PermissionVectorIterator() i = PermissionVectorIterator()
i.policy = policy i.policy = policy
i.vector = vector i.vector = vector
i.perm_max = tclass.handle.permissions.nprim i.perm_max = tclass.nprim
i.perm_table = tclass._perm_table i.perm_table = tclass._perm_table
try: try: