mirror of
https://github.com/SELinuxProject/setools
synced 2025-03-11 07:18:15 +00:00
policyrep: Change caches to be per-policy, with weak references.
Make SELinuxPolicy weak-referenceable. Implement a WeakKeyDefaultDict class which has the behaviors of a combination of both WeakKeyDictionary and defaultdict.
This commit is contained in:
parent
58bda1a40a
commit
76c64b6374
@ -32,6 +32,7 @@ import itertools
|
||||
import ipaddress
|
||||
import collections
|
||||
import enum
|
||||
import weakref
|
||||
|
||||
cimport sepol
|
||||
cimport selinux
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
truth_table_row = collections.namedtuple("truth_table_row", ["values", "result"])
|
||||
|
||||
cdef dict _cond_cache = {}
|
||||
cdef object _cond_cache = WeakKeyDefaultDict(dict)
|
||||
|
||||
#
|
||||
# Classes
|
||||
@ -62,10 +62,10 @@ cdef class Conditional(PolicyObject):
|
||||
list booleans
|
||||
|
||||
try:
|
||||
return _cond_cache[<uintptr_t>symbol]
|
||||
return _cond_cache[policy][<uintptr_t>symbol]
|
||||
except KeyError:
|
||||
c = Conditional.__new__(Conditional)
|
||||
_cond_cache[<uintptr_t>symbol] = c
|
||||
_cond_cache[policy][<uintptr_t>symbol] = c
|
||||
c.policy = policy
|
||||
c.key = <uintptr_t>symbol
|
||||
c._postfix_expression = []
|
||||
|
@ -19,9 +19,9 @@
|
||||
#
|
||||
# pylint: disable=protected-access
|
||||
|
||||
cdef dict _cat_cache = {}
|
||||
cdef dict _sens_cache = {}
|
||||
cdef dict _leveldecl_cache = {}
|
||||
cdef object _cat_cache = WeakKeyDefaultDict(dict)
|
||||
cdef object _sens_cache = WeakKeyDefaultDict(dict)
|
||||
cdef object _leveldecl_cache = WeakKeyDefaultDict(dict)
|
||||
|
||||
|
||||
#
|
||||
@ -58,14 +58,14 @@ cdef class Category(PolicySymbol):
|
||||
raise MLSDisabled
|
||||
|
||||
try:
|
||||
return _cat_cache[<uintptr_t>symbol]
|
||||
return _cat_cache[policy][<uintptr_t>symbol]
|
||||
except KeyError:
|
||||
c = Category.__new__(Category)
|
||||
c.policy = policy
|
||||
c.key = <uintptr_t>symbol
|
||||
c.name = policy.category_value_to_name(symbol.s.value - 1)
|
||||
c._value = symbol.s.value
|
||||
_cat_cache[<uintptr_t>symbol] = c
|
||||
_cat_cache[policy][<uintptr_t>symbol] = c
|
||||
return c
|
||||
|
||||
def __hash__(self):
|
||||
@ -119,10 +119,10 @@ cdef class Sensitivity(PolicySymbol):
|
||||
raise MLSDisabled
|
||||
|
||||
try:
|
||||
return _sens_cache[<uintptr_t>symbol]
|
||||
return _sens_cache[policy][<uintptr_t>symbol]
|
||||
except KeyError:
|
||||
s = Sensitivity.__new__(Sensitivity)
|
||||
_sens_cache[<uintptr_t>symbol] = s
|
||||
_sens_cache[policy][<uintptr_t>symbol] = s
|
||||
s.policy = policy
|
||||
s.key = <uintptr_t>symbol
|
||||
s.name = policy.level_value_to_name(symbol.level.sens - 1)
|
||||
@ -233,10 +233,10 @@ cdef class LevelDecl(BaseMLSLevel):
|
||||
raise MLSDisabled
|
||||
|
||||
try:
|
||||
return _leveldecl_cache[<uintptr_t>symbol]
|
||||
return _leveldecl_cache[policy][<uintptr_t>symbol]
|
||||
except KeyError:
|
||||
l = LevelDecl.__new__(LevelDecl)
|
||||
_leveldecl_cache[<uintptr_t>symbol] = l
|
||||
_leveldecl_cache[policy][<uintptr_t>symbol] = l
|
||||
l.policy = policy
|
||||
l._categories = set(CategoryEbitmapIterator.factory(policy, &symbol.level.cat))
|
||||
# the datum for levels is also used for Sensitivity objects
|
||||
|
@ -18,8 +18,8 @@
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
cdef dict _common_cache = {}
|
||||
cdef dict _objclass_cache = {}
|
||||
cdef object _common_cache = WeakKeyDefaultDict(dict)
|
||||
cdef object _objclass_cache = WeakKeyDefaultDict(dict)
|
||||
|
||||
|
||||
#
|
||||
@ -45,7 +45,7 @@ cdef class Common(PolicySymbol):
|
||||
dict perm_table
|
||||
|
||||
try:
|
||||
return _common_cache[<uintptr_t>symbol]
|
||||
return _common_cache[policy][<uintptr_t>symbol]
|
||||
except KeyError:
|
||||
c = Common.__new__(Common)
|
||||
c.policy = policy
|
||||
@ -68,7 +68,7 @@ cdef class Common(PolicySymbol):
|
||||
|
||||
c.perms = frozenset(c._perm_table.values())
|
||||
|
||||
_common_cache[<uintptr_t>symbol] = c
|
||||
_common_cache[policy][<uintptr_t>symbol] = c
|
||||
return c
|
||||
|
||||
def __contains__(self, other):
|
||||
@ -106,13 +106,13 @@ cdef class ObjClass(PolicySymbol):
|
||||
ObjClass c
|
||||
|
||||
try:
|
||||
return _objclass_cache[<uintptr_t>symbol]
|
||||
return _objclass_cache[policy][<uintptr_t>symbol]
|
||||
except KeyError:
|
||||
#
|
||||
# Instantiate object class
|
||||
#
|
||||
c = ObjClass.__new__(ObjClass)
|
||||
_objclass_cache[<uintptr_t>symbol] = c
|
||||
_objclass_cache[policy][<uintptr_t>symbol] = c
|
||||
c.policy = policy
|
||||
c.key = <uintptr_t>symbol
|
||||
c.nprim = symbol.permissions.nprim
|
||||
|
@ -46,6 +46,7 @@ cdef class SELinuxPolicy:
|
||||
object log
|
||||
object constraint_counts
|
||||
object terule_counts
|
||||
object __weakref__
|
||||
|
||||
# Public attributes:
|
||||
readonly str path
|
||||
|
@ -21,8 +21,8 @@
|
||||
#
|
||||
# Cache objects
|
||||
#
|
||||
cdef dict _type_cache = {}
|
||||
cdef dict _typeattr_cache = {}
|
||||
cdef object _type_cache = WeakKeyDefaultDict(dict)
|
||||
cdef object _typeattr_cache = WeakKeyDefaultDict(dict)
|
||||
|
||||
|
||||
#
|
||||
@ -77,10 +77,10 @@ cdef class Type(BaseType):
|
||||
policy.type_value_to_name(symbol.s.value - 1)))
|
||||
|
||||
try:
|
||||
return _type_cache[<uintptr_t>symbol]
|
||||
return _type_cache[policy][<uintptr_t>symbol]
|
||||
except KeyError:
|
||||
t = Type.__new__(Type)
|
||||
_type_cache[<uintptr_t>symbol] = t
|
||||
_type_cache[policy][<uintptr_t>symbol] = t
|
||||
t.policy = policy
|
||||
t.key = <uintptr_t>symbol
|
||||
t.value = symbol.s.value
|
||||
@ -148,10 +148,10 @@ cdef class TypeAttribute(BaseType):
|
||||
policy.type_value_to_name(symbol.s.value - 1)))
|
||||
|
||||
try:
|
||||
return _typeattr_cache[<uintptr_t>symbol]
|
||||
return _typeattr_cache[policy][<uintptr_t>symbol]
|
||||
except KeyError:
|
||||
a = TypeAttribute.__new__(TypeAttribute)
|
||||
_typeattr_cache[<uintptr_t>symbol] = a
|
||||
_typeattr_cache[policy][<uintptr_t>symbol] = a
|
||||
a.policy = policy
|
||||
a.key = <uintptr_t>symbol
|
||||
a.name = policy.type_value_to_name(symbol.s.value - 1)
|
||||
|
@ -18,7 +18,7 @@
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
cdef dict _user_cache = {}
|
||||
cdef object _user_cache = WeakKeyDefaultDict(dict)
|
||||
|
||||
|
||||
cdef class User(PolicySymbol):
|
||||
@ -35,10 +35,10 @@ cdef class User(PolicySymbol):
|
||||
"""Factory function for constructing User objects."""
|
||||
cdef User u
|
||||
try:
|
||||
return _user_cache[<uintptr_t>symbol]
|
||||
return _user_cache[policy][<uintptr_t>symbol]
|
||||
except KeyError:
|
||||
u = User.__new__(User)
|
||||
_user_cache[<uintptr_t>symbol] = u
|
||||
_user_cache[policy][<uintptr_t>symbol] = u
|
||||
u.policy = policy
|
||||
u.key = <uintptr_t>symbol
|
||||
u.name = policy.user_value_to_name(symbol.s.value - 1)
|
||||
|
@ -60,6 +60,38 @@ class PolicyEnum(enum.Enum):
|
||||
except ValueError:
|
||||
return cls[value]
|
||||
|
||||
|
||||
class WeakKeyDefaultDict(weakref.WeakKeyDictionary):
|
||||
|
||||
"""
|
||||
A dictionary with a weak-referenced key and a default value.
|
||||
|
||||
This is a combination of WeakKeyDictionary and defaultdict
|
||||
classes and has the interfaces of both, with the exception
|
||||
of the constructor.
|
||||
|
||||
WeakKeyDefaultDict(default_factory, [dict])
|
||||
"""
|
||||
|
||||
def __init__(self, default_factory, *args):
|
||||
self.default_factory = default_factory
|
||||
super().__init__(args)
|
||||
|
||||
def __getitem__(self, key):
|
||||
try:
|
||||
return super().__getitem__(key)
|
||||
except KeyError:
|
||||
return self.__missing__(key)
|
||||
|
||||
def __missing__(self, key):
|
||||
if self.default_factory is None:
|
||||
raise KeyError(key)
|
||||
|
||||
defaultvalue = self.default_factory()
|
||||
self.__setitem__(key, defaultvalue)
|
||||
return defaultvalue
|
||||
|
||||
|
||||
#
|
||||
# Functions
|
||||
#
|
||||
|
Loading…
Reference in New Issue
Block a user