Re: [PATCH v2] python/sepolgen: port policygen.py to setools 4 API
Stephen Smalley <[email protected]> Fri, 24 Jul 2026 10:19:21 -0400
| Newsgroups | org.kernel.vger.selinux |
|---|---|
| Message-ID | <CAEjxPJ6RJQAymiPCF5OTr2cT86PeNbwzs9ZA=+OnEb3AWD=UrQ@mail.gmail.com> |
On Mon, Jul 20, 2026 at 3:53 PM Stephen Smalley <[email protected]> wrote: > > policygen.py still called seinfo() and sesearch(), the setools 3 > python bindings that were removed years ago. The calls only survived > because they sat inside a bare "try/except: pass", so the "source type > can write to..." hint in audit2allow output has been silently dead. > > Replace them with the setools 4 equivalents: > - SELinuxPolicy().lookup_typeattr("domain").expand() for the > domain attribute member set. > - TERuleQuery(ruletype=[allow], source=..., tclass=[...], perms=..., > perms_subset=True) for the allow rule search, expanding rule.target > so attribute targets are resolved to concrete types > > While here, cache the loaded policy on the PolicyGenerator instance so > it is not reparsed for every access vector, drop the wildcard import, > narrow the bare except to setools exceptions, and dedupe/sort the > resulting type list for stable output. > > Fixes: https://github.com/SELinuxProject/selinux/issues/332 > Signed-off-by: Stephen Smalley <[email protected]> Merged. > --- > python/sepolgen/src/sepolgen/policygen.py | 41 ++++++++++++++--------- > 1 file changed, 25 insertions(+), 16 deletions(-) > > diff --git a/python/sepolgen/src/sepolgen/policygen.py b/python/sepolgen/src/sepolgen/policygen.py > index 7715bed5..a5af521a 100644 > --- a/python/sepolgen/src/sepolgen/policygen.py > +++ b/python/sepolgen/src/sepolgen/policygen.py > @@ -26,9 +26,9 @@ import textwrap > > import selinux.audit2why as audit2why > try: > - from setools import * > -except: > - pass > + import setools > +except ImportError: > + setools = None > > from . import refpolicy > from . import objectmodel > @@ -85,6 +85,7 @@ class PolicyGenerator: > self.dontaudit = False > self.xperms = False > > + self.policy = None > self.domains = None > self.gen_cil = False > self.comment_start = '#' > @@ -206,23 +207,31 @@ class PolicyGenerator: > rule.comment += "\n%s" % self.comment_start > rule.comment += "\tPossible cause is the source %s and target %s are different." % reason > > - try: > - if ( av.type == audit2why.TERULE and > - "write" in av.perms and > - ( "dir" in av.obj_class or "open" in av.perms )): > - if not self.domains: > - self.domains = seinfo(ATTRIBUTE, name="domain")[0]["types"] > - types=[] > - > - for i in [x[TCONTEXT] for x in sesearch([ALLOW], {SCONTEXT: av.src_type, CLASS: av.obj_class, PERMS: av.perms})]: > - if i not in self.domains: > - types.append(i) > + if ( setools and > + av.type == audit2why.TERULE and > + "write" in av.perms and > + ( "dir" in av.obj_class or "open" in av.perms )): > + try: > + if not self.policy: > + self.policy = setools.SELinuxPolicy() > + self.domains = set(str(t) for t in > + self.policy.lookup_typeattr("domain").expand()) > + q = setools.TERuleQuery(self.policy, > + ruletype=[setools.TERuletype.allow], > + source=av.src_type, > + tclass=[av.obj_class], > + perms=av.perms, perms_subset=True) > + types = set() > + for r in q.results(): > + types.update(str(t) for t in r.target.expand()) > + types -= self.domains > + types = sorted(types) > if len(types) == 1: > rule.comment += "\n%s!!!! The source type '%s' can write to a '%s' of the following type:\n%s %s\n" % (self.comment_start, av.src_type, av.obj_class, self.comment_start, ", ".join(types)) > elif len(types) >= 1: > rule.comment += "\n%s!!!! The source type '%s' can write to a '%s' of the following types:\n%s %s\n" % (self.comment_start, av.src_type, av.obj_class, self.comment_start, ", ".join(types)) > - except: > - pass > + except setools.exception.SEToolsException: > + pass > > self.module.children.append(rule) > > -- > 2.55.0 >