[PATCH 1/1] python/sepolicy: fix compatibility with setools 4.2.0

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When testing sepolicy gui with setools 4.2.0-beta, the following error
happened:

      File "python/sepolicy/sepolicy/__init__.py", line 277, in _setools_rule_to_dict
        if isinstance(rule, setools.policyrep.terule.AVRule):
    AttributeError: module 'setools.policyrep' has no attribute 'terule'

This is due to a reorganization of files in setools 4.2. After reporting
the issue on https://github.com/SELinuxProject/setools/issues/8 , it
appears that sepolicy has not been using setools API properly. Fix this
by:
* replacing exception types internal to setools with AttributeError, as
  they all inherit from it ;
* using rule.conditional.evaluate(...) in order to find out whether a
  conditional rule is enabled, instead of relying on
  rule.qpol_symbol.is_enabled() (which disappeared).

This last point required knowing the states of the booleans in the
policy. As sepolicy already retrieves all boolean states in
get_all_bools(), put them in a dict which can be used by
rule.conditional.evaluate().

This code has been tested with setools 4.1.1 and setools 4.2.0-beta.

Signed-off-by: Nicolas Iooss <nicolas.iooss@xxxxxxx>
---
 python/sepolicy/sepolicy/__init__.py | 30 +++++++++++++++++++---------
 1 file changed, 21 insertions(+), 9 deletions(-)

diff --git a/python/sepolicy/sepolicy/__init__.py b/python/sepolicy/sepolicy/__init__.py
index 89346aba0b15..ed6dfea9718a 100644
--- a/python/sepolicy/sepolicy/__init__.py
+++ b/python/sepolicy/sepolicy/__init__.py
@@ -112,6 +112,7 @@ login_mappings = None
 file_types = None
 port_types = None
 bools = None
+bools_dict = None
 all_attributes = None
 booleans = None
 booleans_dict = None
@@ -134,6 +135,7 @@ def policy(policy_file):
     global all_domains
     global all_attributes
     global bools
+    global bools_dict
     global all_types
     global role_allows
     global users
@@ -143,6 +145,7 @@ def policy(policy_file):
     all_domains = None
     all_attributes = None
     bools = None
+    bools_dict = None
     all_types = None
     role_allows = None
     users = None
@@ -272,34 +275,35 @@ def _setools_rule_to_dict(rule):
         'class': str(rule.tclass),
     }
 
+    # Evaluate the boolean condition if it is a conditional rule.
+    # In order to do this, extract the booleans which are used in the condition first.
     try:
-        enabled = bool(rule.qpol_symbol.is_enabled(rule.policy))
+        all_bools = get_all_bools_as_dict()
+        used_bools = dict((str(name), all_bools[name]) for name in rule.conditional.booleans)
+        enabled = rule.conditional.evaluate(**used_bools) == rule.conditional_block
     except AttributeError:
         enabled = True
 
-    if isinstance(rule, setools.policyrep.terule.AVRule):
-        d['enabled'] = enabled
+    d['enabled'] = enabled
 
     try:
         d['permlist'] = list(map(str, rule.perms))
-    except setools.policyrep.exception.RuleUseError:
+    except AttributeError:
         pass
 
     try:
         d['transtype'] = str(rule.default)
-    except setools.policyrep.exception.RuleUseError:
+    except AttributeError:
         pass
 
     try:
         d['boolean'] = [(str(rule.conditional), enabled)]
-    except (AttributeError, setools.policyrep.exception.RuleNotConditional):
+    except AttributeError:
         pass
 
     try:
         d['filename'] = rule.filename
-    except (AttributeError,
-            setools.policyrep.exception.RuleNotConditional,
-            setools.policyrep.exception.TERuleNoFilename):
+    except AttributeError:
         pass
 
     return d
@@ -930,6 +934,14 @@ def get_all_bools():
     return bools
 
 
+def get_all_bools_as_dict():
+    """Return a name->state dict of the booleans defined in the policy"""
+    global bools_dict
+    if not bools_dict:
+        bools_dict = dict((b['name'], b['state']) for b in get_all_bools())
+    return bools_dict
+
+
 def prettyprint(f, trim):
     return " ".join(f[:-len(trim)].split("_"))
 
-- 
2.19.0

_______________________________________________
Selinux mailing list
Selinux@xxxxxxxxxxxxx
To unsubscribe, send email to Selinux-leave@xxxxxxxxxxxxx.
To get help, send an email containing "help" to Selinux-request@xxxxxxxxxxxxx.



[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux