mirror of
https://github.com/SELinuxProject/setools
synced 2025-04-10 03:21:22 +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 ipaddress
|
||||||
import collections
|
import collections
|
||||||
import enum
|
import enum
|
||||||
|
import weakref
|
||||||
|
|
||||||
cimport sepol
|
cimport sepol
|
||||||
cimport selinux
|
cimport selinux
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
truth_table_row = collections.namedtuple("truth_table_row", ["values", "result"])
|
truth_table_row = collections.namedtuple("truth_table_row", ["values", "result"])
|
||||||
|
|
||||||
cdef dict _cond_cache = {}
|
cdef object _cond_cache = WeakKeyDefaultDict(dict)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Classes
|
# Classes
|
||||||
@ -62,10 +62,10 @@ cdef class Conditional(PolicyObject):
|
|||||||
list booleans
|
list booleans
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return _cond_cache[<uintptr_t>symbol]
|
return _cond_cache[policy][<uintptr_t>symbol]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
c = Conditional.__new__(Conditional)
|
c = Conditional.__new__(Conditional)
|
||||||
_cond_cache[<uintptr_t>symbol] = c
|
_cond_cache[policy][<uintptr_t>symbol] = c
|
||||||
c.policy = policy
|
c.policy = policy
|
||||||
c.key = <uintptr_t>symbol
|
c.key = <uintptr_t>symbol
|
||||||
c._postfix_expression = []
|
c._postfix_expression = []
|
||||||
|
@ -19,9 +19,9 @@
|
|||||||
#
|
#
|
||||||
# pylint: disable=protected-access
|
# pylint: disable=protected-access
|
||||||
|
|
||||||
cdef dict _cat_cache = {}
|
cdef object _cat_cache = WeakKeyDefaultDict(dict)
|
||||||
cdef dict _sens_cache = {}
|
cdef object _sens_cache = WeakKeyDefaultDict(dict)
|
||||||
cdef dict _leveldecl_cache = {}
|
cdef object _leveldecl_cache = WeakKeyDefaultDict(dict)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -58,14 +58,14 @@ cdef class Category(PolicySymbol):
|
|||||||
raise MLSDisabled
|
raise MLSDisabled
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return _cat_cache[<uintptr_t>symbol]
|
return _cat_cache[policy][<uintptr_t>symbol]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
c = Category.__new__(Category)
|
c = Category.__new__(Category)
|
||||||
c.policy = policy
|
c.policy = policy
|
||||||
c.key = <uintptr_t>symbol
|
c.key = <uintptr_t>symbol
|
||||||
c.name = policy.category_value_to_name(symbol.s.value - 1)
|
c.name = policy.category_value_to_name(symbol.s.value - 1)
|
||||||
c._value = symbol.s.value
|
c._value = symbol.s.value
|
||||||
_cat_cache[<uintptr_t>symbol] = c
|
_cat_cache[policy][<uintptr_t>symbol] = c
|
||||||
return c
|
return c
|
||||||
|
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
@ -119,10 +119,10 @@ cdef class Sensitivity(PolicySymbol):
|
|||||||
raise MLSDisabled
|
raise MLSDisabled
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return _sens_cache[<uintptr_t>symbol]
|
return _sens_cache[policy][<uintptr_t>symbol]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
s = Sensitivity.__new__(Sensitivity)
|
s = Sensitivity.__new__(Sensitivity)
|
||||||
_sens_cache[<uintptr_t>symbol] = s
|
_sens_cache[policy][<uintptr_t>symbol] = s
|
||||||
s.policy = policy
|
s.policy = policy
|
||||||
s.key = <uintptr_t>symbol
|
s.key = <uintptr_t>symbol
|
||||||
s.name = policy.level_value_to_name(symbol.level.sens - 1)
|
s.name = policy.level_value_to_name(symbol.level.sens - 1)
|
||||||
@ -233,10 +233,10 @@ cdef class LevelDecl(BaseMLSLevel):
|
|||||||
raise MLSDisabled
|
raise MLSDisabled
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return _leveldecl_cache[<uintptr_t>symbol]
|
return _leveldecl_cache[policy][<uintptr_t>symbol]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
l = LevelDecl.__new__(LevelDecl)
|
l = LevelDecl.__new__(LevelDecl)
|
||||||
_leveldecl_cache[<uintptr_t>symbol] = l
|
_leveldecl_cache[policy][<uintptr_t>symbol] = l
|
||||||
l.policy = policy
|
l.policy = policy
|
||||||
l._categories = set(CategoryEbitmapIterator.factory(policy, &symbol.level.cat))
|
l._categories = set(CategoryEbitmapIterator.factory(policy, &symbol.level.cat))
|
||||||
# the datum for levels is also used for Sensitivity objects
|
# the datum for levels is also used for Sensitivity objects
|
||||||
|
@ -18,8 +18,8 @@
|
|||||||
# <http://www.gnu.org/licenses/>.
|
# <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
|
|
||||||
cdef dict _common_cache = {}
|
cdef object _common_cache = WeakKeyDefaultDict(dict)
|
||||||
cdef dict _objclass_cache = {}
|
cdef object _objclass_cache = WeakKeyDefaultDict(dict)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -45,7 +45,7 @@ cdef class Common(PolicySymbol):
|
|||||||
dict perm_table
|
dict perm_table
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return _common_cache[<uintptr_t>symbol]
|
return _common_cache[policy][<uintptr_t>symbol]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
c = Common.__new__(Common)
|
c = Common.__new__(Common)
|
||||||
c.policy = policy
|
c.policy = policy
|
||||||
@ -68,7 +68,7 @@ cdef class Common(PolicySymbol):
|
|||||||
|
|
||||||
c.perms = frozenset(c._perm_table.values())
|
c.perms = frozenset(c._perm_table.values())
|
||||||
|
|
||||||
_common_cache[<uintptr_t>symbol] = c
|
_common_cache[policy][<uintptr_t>symbol] = c
|
||||||
return c
|
return c
|
||||||
|
|
||||||
def __contains__(self, other):
|
def __contains__(self, other):
|
||||||
@ -106,13 +106,13 @@ cdef class ObjClass(PolicySymbol):
|
|||||||
ObjClass c
|
ObjClass c
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return _objclass_cache[<uintptr_t>symbol]
|
return _objclass_cache[policy][<uintptr_t>symbol]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
#
|
#
|
||||||
# Instantiate object class
|
# Instantiate object class
|
||||||
#
|
#
|
||||||
c = ObjClass.__new__(ObjClass)
|
c = ObjClass.__new__(ObjClass)
|
||||||
_objclass_cache[<uintptr_t>symbol] = c
|
_objclass_cache[policy][<uintptr_t>symbol] = c
|
||||||
c.policy = policy
|
c.policy = policy
|
||||||
c.key = <uintptr_t>symbol
|
c.key = <uintptr_t>symbol
|
||||||
c.nprim = symbol.permissions.nprim
|
c.nprim = symbol.permissions.nprim
|
||||||
|
@ -46,6 +46,7 @@ cdef class SELinuxPolicy:
|
|||||||
object log
|
object log
|
||||||
object constraint_counts
|
object constraint_counts
|
||||||
object terule_counts
|
object terule_counts
|
||||||
|
object __weakref__
|
||||||
|
|
||||||
# Public attributes:
|
# Public attributes:
|
||||||
readonly str path
|
readonly str path
|
||||||
|
@ -21,8 +21,8 @@
|
|||||||
#
|
#
|
||||||
# Cache objects
|
# Cache objects
|
||||||
#
|
#
|
||||||
cdef dict _type_cache = {}
|
cdef object _type_cache = WeakKeyDefaultDict(dict)
|
||||||
cdef dict _typeattr_cache = {}
|
cdef object _typeattr_cache = WeakKeyDefaultDict(dict)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -77,10 +77,10 @@ cdef class Type(BaseType):
|
|||||||
policy.type_value_to_name(symbol.s.value - 1)))
|
policy.type_value_to_name(symbol.s.value - 1)))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return _type_cache[<uintptr_t>symbol]
|
return _type_cache[policy][<uintptr_t>symbol]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
t = Type.__new__(Type)
|
t = Type.__new__(Type)
|
||||||
_type_cache[<uintptr_t>symbol] = t
|
_type_cache[policy][<uintptr_t>symbol] = t
|
||||||
t.policy = policy
|
t.policy = policy
|
||||||
t.key = <uintptr_t>symbol
|
t.key = <uintptr_t>symbol
|
||||||
t.value = symbol.s.value
|
t.value = symbol.s.value
|
||||||
@ -148,10 +148,10 @@ cdef class TypeAttribute(BaseType):
|
|||||||
policy.type_value_to_name(symbol.s.value - 1)))
|
policy.type_value_to_name(symbol.s.value - 1)))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return _typeattr_cache[<uintptr_t>symbol]
|
return _typeattr_cache[policy][<uintptr_t>symbol]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
a = TypeAttribute.__new__(TypeAttribute)
|
a = TypeAttribute.__new__(TypeAttribute)
|
||||||
_typeattr_cache[<uintptr_t>symbol] = a
|
_typeattr_cache[policy][<uintptr_t>symbol] = a
|
||||||
a.policy = policy
|
a.policy = policy
|
||||||
a.key = <uintptr_t>symbol
|
a.key = <uintptr_t>symbol
|
||||||
a.name = policy.type_value_to_name(symbol.s.value - 1)
|
a.name = policy.type_value_to_name(symbol.s.value - 1)
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
# <http://www.gnu.org/licenses/>.
|
# <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
|
|
||||||
cdef dict _user_cache = {}
|
cdef object _user_cache = WeakKeyDefaultDict(dict)
|
||||||
|
|
||||||
|
|
||||||
cdef class User(PolicySymbol):
|
cdef class User(PolicySymbol):
|
||||||
@ -35,10 +35,10 @@ cdef class User(PolicySymbol):
|
|||||||
"""Factory function for constructing User objects."""
|
"""Factory function for constructing User objects."""
|
||||||
cdef User u
|
cdef User u
|
||||||
try:
|
try:
|
||||||
return _user_cache[<uintptr_t>symbol]
|
return _user_cache[policy][<uintptr_t>symbol]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
u = User.__new__(User)
|
u = User.__new__(User)
|
||||||
_user_cache[<uintptr_t>symbol] = u
|
_user_cache[policy][<uintptr_t>symbol] = u
|
||||||
u.policy = policy
|
u.policy = policy
|
||||||
u.key = <uintptr_t>symbol
|
u.key = <uintptr_t>symbol
|
||||||
u.name = policy.user_value_to_name(symbol.s.value - 1)
|
u.name = policy.user_value_to_name(symbol.s.value - 1)
|
||||||
|
@ -60,6 +60,38 @@ class PolicyEnum(enum.Enum):
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
return cls[value]
|
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
|
# Functions
|
||||||
#
|
#
|
||||||
|
Loading…
Reference in New Issue
Block a user