diff --git a/setools/policyrep.pyi b/setools/policyrep.pyi index 752a22c4..28266b2b 100644 --- a/setools/policyrep.pyi +++ b/setools/policyrep.pyi @@ -462,6 +462,7 @@ class FSUseRuletype(PolicyEnum): class FileNameTERule(BaseTERule): default: Type = ... filename: str = ... + match_type: FileNameTERuleMatchType = ... perms: NoReturn = ... ruletype: TERuletype = ... source: TypeOrAttr = ... @@ -490,6 +491,11 @@ class FileNameTERuleIterator(HashtabIterator): def __reduce__(self) -> Any: ... def __setstate__(self, state) -> Any: ... +class FileNameTERuleMatchType(PolicyEnum): + exact: int = ... + prefix: int = ... + suffix: int = ... + class GenfsFiletype(int): _filetype_to_text: Any = ... @classmethod diff --git a/setools/policyrep/selinuxpolicy.pxi b/setools/policyrep/selinuxpolicy.pxi index cff3b5ed..f072402d 100644 --- a/setools/policyrep/selinuxpolicy.pxi +++ b/setools/policyrep/selinuxpolicy.pxi @@ -510,7 +510,9 @@ cdef class SELinuxPolicy: def terules(self): """Iterator over all type enforcement rules.""" yield from TERuleIterator.factory(self, &self.handle.p.te_avtab) - yield from FileNameTERuleIterator.factory(self, &self.handle.p.filename_trans) + yield from FileNameTERuleIterator.factory(self, &self.handle.p.filename_trans[sepol.FILENAME_TRANS_MATCH_EXACT], sepol.FILENAME_TRANS_MATCH_EXACT) + yield from FileNameTERuleIterator.factory(self, &self.handle.p.filename_trans[sepol.FILENAME_TRANS_MATCH_PREFIX], sepol.FILENAME_TRANS_MATCH_PREFIX) + yield from FileNameTERuleIterator.factory(self, &self.handle.p.filename_trans[sepol.FILENAME_TRANS_MATCH_SUFFIX], sepol.FILENAME_TRANS_MATCH_SUFFIX) for c in self.conditionals(): yield from c.true_rules() @@ -1064,7 +1066,9 @@ cdef class SELinuxPolicy: if not self.terule_counts: self.terule_counts = TERuleIterator.factory(self, &self.handle.p.te_avtab).ruletype_count() self.terule_counts[TERuletype.type_transition.value] += \ - len(FileNameTERuleIterator.factory(self, &self.handle.p.filename_trans)) + len(FileNameTERuleIterator.factory(self, &self.handle.p.filename_trans[sepol.FILENAME_TRANS_MATCH_EXACT], sepol.FILENAME_TRANS_MATCH_EXACT)) + \ + len(FileNameTERuleIterator.factory(self, &self.handle.p.filename_trans[sepol.FILENAME_TRANS_MATCH_PREFIX], sepol.FILENAME_TRANS_MATCH_PREFIX)) + \ + len(FileNameTERuleIterator.factory(self, &self.handle.p.filename_trans[sepol.FILENAME_TRANS_MATCH_SUFFIX], sepol.FILENAME_TRANS_MATCH_SUFFIX)) for c in self.conditionals(): self.terule_counts.update(c.true_rules().ruletype_count()) diff --git a/setools/policyrep/sepol.pxd b/setools/policyrep/sepol.pxd index 922065e4..331844ca 100644 --- a/setools/policyrep/sepol.pxd +++ b/setools/policyrep/sepol.pxd @@ -793,6 +793,10 @@ cdef extern from "": cdef int SYM_CATS cdef int SYM_NUM + cdef int FILENAME_TRANS_MATCH_EXACT + cdef int FILENAME_TRANS_MATCH_PREFIX + cdef int FILENAME_TRANS_MATCH_SUFFIX + cdef struct policydb: uint32_t policy_type char *name @@ -819,7 +823,7 @@ cdef extern from "": ocontext_t *ocontexts[9] # TODO: OCON_NUM=9 genfs_t *genfs hashtab_t range_tr - hashtab_t filename_trans + hashtab_t filename_trans[3] ebitmap_t *type_attr_map ebitmap_t *attr_type_map # not saved in the binary policy ebitmap_t policycaps diff --git a/setools/policyrep/terule.pxi b/setools/policyrep/terule.pxi index 4f4a95f5..08501384 100644 --- a/setools/policyrep/terule.pxi +++ b/setools/policyrep/terule.pxi @@ -469,6 +469,15 @@ cdef class TERule(BaseTERule): return self.rule_string +class FileNameTERuleMatchType(PolicyEnum): + + """Enumeration of name match type of FileName TE rules.""" + + exact = sepol.FILENAME_TRANS_MATCH_EXACT + prefix = sepol.FILENAME_TRANS_MATCH_PREFIX + suffix = sepol.FILENAME_TRANS_MATCH_SUFFIX + + cdef class FileNameTERule(BaseTERule): """A type_transition type enforcement rule with filename.""" @@ -476,11 +485,13 @@ cdef class FileNameTERule(BaseTERule): cdef: Type dft readonly str filename + readonly object match_type @staticmethod cdef inline FileNameTERule factory(SELinuxPolicy policy, sepol.filename_trans_key_t *key, - Type stype, size_t otype): + Type stype, uint32_t match_type, + size_t otype): """Factory function for creating FileNameTERule objects.""" cdef FileNameTERule r = FileNameTERule.__new__(FileNameTERule) r.policy = policy @@ -491,11 +502,12 @@ cdef class FileNameTERule(BaseTERule): r.tclass = ObjClass.factory(policy, policy.class_value_to_datum(key.tclass - 1)) r.dft = Type.factory(policy, policy.type_value_to_datum(otype - 1)) r.filename = intern(key.name) + r.match_type = FileNameTERuleMatchType(match_type) r.origin = None return r def __hash__(self): - return hash("{0.ruletype}|{0.source}|{0.target}|{0.tclass}|{0.filename}|{1}|{2}".format( + return hash("{0.ruletype}|{0.source}|{0.target}|{0.tclass}|{0.filename}|{0.match_type}|{1}|{2}".format( self, None, None)) def __lt__(self, other): @@ -525,6 +537,7 @@ cdef class FileNameTERule(BaseTERule): r.tclass = self.tclass r.dft = self.dft r.filename = self.filename + r.match_type = self.match_type r.origin = None r._conditional = self._conditional r._conditional_block = self._conditional_block @@ -536,8 +549,16 @@ cdef class FileNameTERule(BaseTERule): yield self def statement(self): - return "{0.ruletype} {0.source} {0.target}:{0.tclass} {0.default} {0.filename};". \ - format(self) + if self.match_type == FileNameTERuleMatchType.exact: + match_type_str = "" + elif self.match_type == FileNameTERuleMatchType.prefix: + match_type_str = " prefix" + elif self.match_type == FileNameTERuleMatchType.suffix: + match_type_str = " suffix" + else: + raise ValueError("Invalid filename trans match type") + return "{0.ruletype} {0.source} {0.target}:{0.tclass} {0.default} {0.filename}{1};". \ + format(self, match_type_str) # @@ -720,13 +741,15 @@ cdef class FileNameTERuleIterator(HashtabIterator): cdef: sepol.filename_trans_datum_t *datum TypeEbitmapIterator stypei + uint32_t match_type @staticmethod - cdef factory(SELinuxPolicy policy, sepol.hashtab_t *table): + cdef factory(SELinuxPolicy policy, sepol.hashtab_t *table, uint32_t match_type): """Factory function for creating FileNameTERule iterators.""" i = FileNameTERuleIterator() i.policy = policy i.table = table + i.match_type = match_type i.reset() return i @@ -748,10 +771,10 @@ cdef class FileNameTERuleIterator(HashtabIterator): stype = self._next_stype() return FileNameTERule.factory(self.policy, self.curr.key, - stype, self.datum.otype) + stype, self.match_type, self.datum.otype) def __len__(self): - return sum(1 for r in FileNameTERuleIterator.factory(self.policy, self.table)) + return sum(1 for r in FileNameTERuleIterator.factory(self.policy, self.table, self.match_type)) def reset(self): super().reset()