2009-12-09 21:33:50 +00:00
|
|
|
diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/access.py policycoreutils-2.0.78/sepolgen-1.0.19/src/sepolgen/access.py
|
|
|
|
--- nsasepolgen/src/sepolgen/access.py 2009-05-18 13:53:14.000000000 -0400
|
2009-12-16 13:21:49 +00:00
|
|
|
+++ policycoreutils-2.0.78/sepolgen-1.0.19/src/sepolgen/access.py 2009-12-08 17:05:49.000000000 -0500
|
2009-12-09 21:33:50 +00:00
|
|
|
@@ -32,6 +32,7 @@
|
|
|
|
"""
|
|
|
|
|
|
|
|
import refpolicy
|
|
|
|
+from selinux import audit2why
|
|
|
|
|
|
|
|
def is_idparam(id):
|
|
|
|
"""Determine if an id is a paramater in the form $N, where N is
|
|
|
|
@@ -85,6 +86,8 @@
|
|
|
|
self.obj_class = None
|
|
|
|
self.perms = refpolicy.IdSet()
|
|
|
|
self.audit_msgs = []
|
|
|
|
+ self.type = audit2why.TERULE
|
|
|
|
+ self.bools = []
|
|
|
|
|
|
|
|
# The direction of the information flow represented by this
|
|
|
|
# access vector - used for matching
|
|
|
|
@@ -127,7 +130,7 @@
|
|
|
|
return self.to_string()
|
|
|
|
|
|
|
|
def to_string(self):
|
|
|
|
- return "allow %s %s : %s %s;" % (self.src_type, self.tgt_type,
|
|
|
|
+ return "allow %s %s:%s %s;" % (self.src_type, self.tgt_type,
|
|
|
|
self.obj_class, self.perms.to_space_str())
|
|
|
|
|
|
|
|
def __cmp__(self, other):
|
|
|
|
@@ -253,20 +256,22 @@
|
|
|
|
for av in l:
|
|
|
|
self.add_av(AccessVector(av))
|
|
|
|
|
|
|
|
- def add(self, src_type, tgt_type, obj_class, perms, audit_msg=None):
|
|
|
|
+ def add(self, src_type, tgt_type, obj_class, perms, audit_msg=None, avc_type=audit2why.TERULE, bools=[]):
|
|
|
|
"""Add an access vector to the set.
|
|
|
|
"""
|
|
|
|
tgt = self.src.setdefault(src_type, { })
|
|
|
|
cls = tgt.setdefault(tgt_type, { })
|
|
|
|
|
|
|
|
- if cls.has_key(obj_class):
|
|
|
|
- access = cls[obj_class]
|
|
|
|
+ if cls.has_key((obj_class, avc_type)):
|
|
|
|
+ access = cls[obj_class, avc_type]
|
|
|
|
else:
|
|
|
|
access = AccessVector()
|
|
|
|
access.src_type = src_type
|
|
|
|
access.tgt_type = tgt_type
|
|
|
|
access.obj_class = obj_class
|
|
|
|
- cls[obj_class] = access
|
|
|
|
+ access.bools = bools
|
|
|
|
+ access.type = avc_type
|
|
|
|
+ cls[obj_class, avc_type] = access
|
|
|
|
|
|
|
|
access.perms.update(perms)
|
|
|
|
if audit_msg:
|
|
|
|
diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/audit.py policycoreutils-2.0.78/sepolgen-1.0.19/src/sepolgen/audit.py
|
2009-12-01 21:17:45 +00:00
|
|
|
--- nsasepolgen/src/sepolgen/audit.py 2009-12-01 15:46:50.000000000 -0500
|
2010-01-06 20:49:27 +00:00
|
|
|
+++ policycoreutils-2.0.78/sepolgen-1.0.19/src/sepolgen/audit.py 2010-01-06 09:52:35.000000000 -0500
|
2009-08-18 19:25:04 +00:00
|
|
|
@@ -23,6 +23,27 @@
|
2009-04-09 02:05:21 +00:00
|
|
|
|
2009-08-18 19:25:04 +00:00
|
|
|
# Convenience functions
|
2009-04-09 02:05:21 +00:00
|
|
|
|
2009-08-18 19:25:04 +00:00
|
|
|
+def get_audit_boot_msgs():
|
|
|
|
+ """Obtain all of the avc and policy load messages from the audit
|
|
|
|
+ log. This function uses ausearch and requires that the current
|
|
|
|
+ process have sufficient rights to run ausearch.
|
|
|
|
+
|
|
|
|
+ Returns:
|
|
|
|
+ string contain all of the audit messages returned by ausearch.
|
|
|
|
+ """
|
|
|
|
+ import subprocess
|
|
|
|
+ import time
|
|
|
|
+ fd=open("/proc/uptime", "r")
|
|
|
|
+ off=float(fd.read().split()[0])
|
|
|
|
+ fd.close
|
|
|
|
+ s = time.localtime(time.time() - off)
|
|
|
|
+ date = time.strftime("%D/%Y", s).split("/")
|
|
|
|
+ bootdate="%s/%s/%s" % (date[0], date[1], date[3])
|
|
|
|
+ boottime = time.strftime("%X", s)
|
|
|
|
+ output = subprocess.Popen(["/sbin/ausearch", "-m", "AVC,USER_AVC,MAC_POLICY_LOAD,DAEMON_START,SELINUX_ERR", "-ts", bootdate, boottime],
|
|
|
|
+ stdout=subprocess.PIPE).communicate()[0]
|
|
|
|
+ return output
|
|
|
|
+
|
|
|
|
def get_audit_msgs():
|
|
|
|
"""Obtain all of the avc and policy load messages from the audit
|
|
|
|
log. This function uses ausearch and requires that the current
|
|
|
|
@@ -47,6 +68,17 @@
|
2009-05-05 18:51:52 +00:00
|
|
|
stdout=subprocess.PIPE).communicate()[0]
|
|
|
|
return output
|
|
|
|
|
|
|
|
+def get_log_msgs():
|
|
|
|
+ """Obtain all of the avc and policy load messages from /var/log/messages.
|
|
|
|
+
|
|
|
|
+ Returns:
|
|
|
|
+ string contain all of the audit messages returned by /var/log/messages.
|
|
|
|
+ """
|
|
|
|
+ import subprocess
|
|
|
|
+ output = subprocess.Popen(["/bin/grep", "avc", "/var/log/messages"],
|
|
|
|
+ stdout=subprocess.PIPE).communicate()[0]
|
|
|
|
+ return output
|
|
|
|
+
|
|
|
|
# Classes representing audit messages
|
|
|
|
|
|
|
|
class AuditMessage:
|
2010-01-06 20:49:27 +00:00
|
|
|
@@ -106,6 +138,9 @@
|
2009-12-09 21:33:50 +00:00
|
|
|
if fields[0] == "path":
|
|
|
|
self.path = fields[1][1:-1]
|
|
|
|
return
|
|
|
|
+import selinux.audit2why as audit2why
|
2010-01-06 20:49:27 +00:00
|
|
|
+
|
|
|
|
+avcdict = {}
|
2009-12-09 21:33:50 +00:00
|
|
|
|
|
|
|
class AVCMessage(AuditMessage):
|
|
|
|
"""AVC message representing an access denial or granted message.
|
2010-01-06 20:49:27 +00:00
|
|
|
@@ -146,6 +181,8 @@
|
2009-12-09 21:33:50 +00:00
|
|
|
self.path = ""
|
|
|
|
self.accesses = []
|
|
|
|
self.denial = True
|
|
|
|
+ self.type = audit2why.TERULE
|
|
|
|
+ self.bools = []
|
|
|
|
|
|
|
|
def __parse_access(self, recs, start):
|
|
|
|
# This is kind of sucky - the access that is in a space separated
|
2010-01-06 20:49:27 +00:00
|
|
|
@@ -205,7 +242,31 @@
|
2009-12-09 21:33:50 +00:00
|
|
|
|
|
|
|
if not found_src or not found_tgt or not found_class or not found_access:
|
|
|
|
raise ValueError("AVC message in invalid format [%s]\n" % self.message)
|
|
|
|
-
|
|
|
|
+ self.analyze()
|
|
|
|
+
|
|
|
|
+ def analyze(self):
|
|
|
|
+ tcontext = self.tcontext.to_string()
|
|
|
|
+ scontext = self.scontext.to_string()
|
2010-01-06 20:49:27 +00:00
|
|
|
+ access_tuple = tuple( self.accesses)
|
|
|
|
+ if (scontext, tcontext, self.tclass, access_tuple) in avcdict.keys():
|
|
|
|
+ self.type, self.bools = avcdict[(scontext, tcontext, self.tclass, access_tuple)]
|
|
|
|
+ else:
|
|
|
|
+ self.type, self.bools = audit2why.analyze(scontext, tcontext, self.tclass, self.accesses);
|
|
|
|
+ if self.type == audit2why.NOPOLICY:
|
|
|
|
+ raise ValueError("Must call policy_init first")
|
|
|
|
+ if self.type == audit2why.BADTCON:
|
|
|
|
+ raise ValueError("Invalid Target Context %s\n" % tcontext)
|
|
|
|
+ if self.type == audit2why.BADSCON:
|
|
|
|
+ raise ValueError("Invalid Source Context %s\n" % scontext)
|
|
|
|
+ if self.type == audit2why.BADSCON:
|
|
|
|
+ raise ValueError("Invalid Type Class %s\n" % self.tclass)
|
|
|
|
+ if self.type == audit2why.BADPERM:
|
|
|
|
+ raise ValueError("Invalid permission %s\n" % " ".join(self.accesses))
|
|
|
|
+ if self.type == audit2why.BADCOMPUTE:
|
|
|
|
+ raise ValueError("Error during access vector computation")
|
|
|
|
+
|
|
|
|
+ avcdict[(scontext, tcontext, self.tclass, access_tuple)] = (self.type, self.bools)
|
2009-12-09 21:33:50 +00:00
|
|
|
+
|
|
|
|
class PolicyLoadMessage(AuditMessage):
|
|
|
|
"""Audit message indicating that the policy was reloaded."""
|
|
|
|
def __init__(self, message):
|
2010-01-06 20:49:27 +00:00
|
|
|
@@ -285,6 +346,9 @@
|
2009-12-09 21:33:50 +00:00
|
|
|
|
|
|
|
def __initialize(self):
|
|
|
|
self.avc_msgs = []
|
|
|
|
+ self.constraint_msgs = []
|
|
|
|
+ self.dontaudit_msgs = []
|
|
|
|
+ self.rbac_msgs = []
|
|
|
|
self.compute_sid_msgs = []
|
|
|
|
self.invalid_msgs = []
|
|
|
|
self.policy_load_msgs = []
|
2010-01-06 20:49:27 +00:00
|
|
|
@@ -314,7 +378,7 @@
|
2009-12-09 21:33:50 +00:00
|
|
|
elif i == "security_compute_sid:":
|
|
|
|
msg = ComputeSidMessage(line)
|
|
|
|
found = True
|
|
|
|
- elif i == "type=MAC_POLICY_LOAD" or i == "type=1403":
|
|
|
|
+ elif i == "type=MAC_POLICY_LOAD":
|
|
|
|
msg = PolicyLoadMessage(line)
|
|
|
|
found = True
|
|
|
|
elif i == "type=AVC_PATH":
|
2010-01-06 20:49:27 +00:00
|
|
|
@@ -442,16 +506,17 @@
|
2009-12-09 21:33:50 +00:00
|
|
|
audit logs parsed by this object.
|
|
|
|
"""
|
|
|
|
av_set = access.AccessVectorSet()
|
|
|
|
+
|
|
|
|
for avc in self.avc_msgs:
|
|
|
|
if avc.denial != True and only_denials:
|
|
|
|
continue
|
|
|
|
if avc_filter:
|
|
|
|
if avc_filter.filter(avc):
|
|
|
|
av_set.add(avc.scontext.type, avc.tcontext.type, avc.tclass,
|
|
|
|
- avc.accesses, avc)
|
|
|
|
+ avc.accesses, avc, avc_type=avc.type, bools=avc.bools)
|
|
|
|
else:
|
|
|
|
av_set.add(avc.scontext.type, avc.tcontext.type, avc.tclass,
|
|
|
|
- avc.accesses, avc)
|
|
|
|
+ avc.accesses, avc, avc_type=avc.type, bools=avc.bools)
|
|
|
|
return av_set
|
|
|
|
|
|
|
|
class AVCTypeFilter:
|
2010-01-06 20:49:27 +00:00
|
|
|
@@ -477,5 +542,3 @@
|
2009-12-09 21:33:50 +00:00
|
|
|
if self.regex.match(avc.tcontext.type):
|
|
|
|
return True
|
|
|
|
return False
|
|
|
|
-
|
|
|
|
-
|
|
|
|
diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/policygen.py policycoreutils-2.0.78/sepolgen-1.0.19/src/sepolgen/policygen.py
|
|
|
|
--- nsasepolgen/src/sepolgen/policygen.py 2008-09-12 11:48:15.000000000 -0400
|
2010-01-08 14:37:32 +00:00
|
|
|
+++ policycoreutils-2.0.78/sepolgen-1.0.19/src/sepolgen/policygen.py 2010-01-08 09:33:54.000000000 -0500
|
2009-12-09 21:33:50 +00:00
|
|
|
@@ -29,6 +29,8 @@
|
|
|
|
import access
|
|
|
|
import interfaces
|
|
|
|
import matching
|
|
|
|
+import selinux.audit2why as audit2why
|
|
|
|
+from setools import *
|
|
|
|
|
|
|
|
# Constants for the level of explanation from the generation
|
|
|
|
# routines
|
|
|
|
@@ -74,7 +76,7 @@
|
|
|
|
self.moduel = module
|
|
|
|
else:
|
|
|
|
self.module = refpolicy.Module()
|
|
|
|
-
|
|
|
|
+ self.domains = None
|
|
|
|
def set_gen_refpol(self, if_set=None, perm_maps=None):
|
|
|
|
"""Set whether reference policy interfaces are generated.
|
|
|
|
|
2010-01-08 14:37:32 +00:00
|
|
|
@@ -141,15 +143,42 @@
|
|
|
|
"""Return the generated module"""
|
|
|
|
return self.module
|
|
|
|
|
|
|
|
- def __add_allow_rules(self, avs):
|
|
|
|
+ def __add_allow_rules(self, avs, dontaudit):
|
2009-12-09 21:33:50 +00:00
|
|
|
for av in avs:
|
2010-01-08 14:37:32 +00:00
|
|
|
- rule = refpolicy.AVRule(av)
|
|
|
|
+ rule = refpolicy.AVRule(av, dontaudit=dontaudit)
|
2009-12-09 21:33:50 +00:00
|
|
|
+ rule.comment = ""
|
|
|
|
if self.explain:
|
|
|
|
rule.comment = refpolicy.Comment(explain_access(av, verbosity=self.explain))
|
2009-12-16 13:21:49 +00:00
|
|
|
+ if av.type == audit2why.ALLOW:
|
|
|
|
+ rule.comment += "#!!!! This avc is allowed in the current policy\n"
|
2009-12-09 21:33:50 +00:00
|
|
|
+ if av.type == audit2why.DONTAUDIT:
|
|
|
|
+ rule.comment += "#!!!! This avc has a dontaudit rule in the current policy\n"
|
|
|
|
+ if av.type == audit2why.BOOLEAN:
|
|
|
|
+ if len(av.bools) > 1:
|
|
|
|
+ rule.comment += "#!!!! This avc can be allowed using one of the these booleans:\n# %s\n" % ", ".join(map(lambda x: av.bools[0][0], av.bools))
|
|
|
|
+ else:
|
|
|
|
+ rule.comment += "#!!!! This avc can be allowed using the boolean '%s'\n" % av.bools[0][0]
|
|
|
|
+
|
|
|
|
+ if av.type == audit2why.CONSTRAINT:
|
|
|
|
+ rule.comment += "#!!!! This avc is a constraint violation. You will need to add an attribute to either the source or target type to make it work.\n"
|
|
|
|
+ if av.type == audit2why.TERULE:
|
2009-12-16 13:21:49 +00:00
|
|
|
+ if "write" in av.perms:
|
|
|
|
+ if "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 map(lambda x: x[TCONTEXT], sesearch([ALLOW], {SCONTEXT: av.src_type, CLASS: av.obj_class, PERMS: av.perms})):
|
|
|
|
+ if i not in self.domains:
|
|
|
|
+ types.append(i)
|
|
|
|
+ if len(types) == 1:
|
|
|
|
+ rule.comment += "#!!!! The source type '%s' can write to a '%s' of the following type:\n# %s\n" % ( av.src_type, av.obj_class, ", ".join(types))
|
|
|
|
+ elif len(types) >= 1:
|
|
|
|
+ rule.comment += "#!!!! The source type '%s' can write to a '%s' of the following types:\n# %s\n" % ( av.src_type, av.obj_class, ", ".join(types))
|
2009-12-09 21:33:50 +00:00
|
|
|
+
|
|
|
|
self.module.children.append(rule)
|
|
|
|
|
|
|
|
|
2010-01-08 14:37:32 +00:00
|
|
|
- def add_access(self, av_set):
|
|
|
|
+ def add_access(self, av_set, dontaudit=False):
|
|
|
|
"""Add the access from the access vector set to this
|
|
|
|
module.
|
|
|
|
"""
|
|
|
|
@@ -165,7 +194,7 @@
|
|
|
|
raw_allow = av_set
|
|
|
|
|
|
|
|
# Generate the raw allow rules from the filtered list
|
|
|
|
- self.__add_allow_rules(raw_allow)
|
|
|
|
+ self.__add_allow_rules(raw_allow, dontaudit)
|
|
|
|
|
|
|
|
def add_role_types(self, role_type_set):
|
|
|
|
for role_type in role_type_set:
|
2009-12-09 21:33:50 +00:00
|
|
|
diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/refparser.py policycoreutils-2.0.78/sepolgen-1.0.19/src/sepolgen/refparser.py
|
2009-12-01 21:17:45 +00:00
|
|
|
--- nsasepolgen/src/sepolgen/refparser.py 2009-10-29 15:21:39.000000000 -0400
|
2009-12-16 13:21:49 +00:00
|
|
|
+++ policycoreutils-2.0.78/sepolgen-1.0.19/src/sepolgen/refparser.py 2009-12-08 17:05:49.000000000 -0500
|
2009-12-09 21:33:50 +00:00
|
|
|
@@ -973,7 +973,7 @@
|
2007-12-19 10:40:23 +00:00
|
|
|
def list_headers(root):
|
|
|
|
modules = []
|
|
|
|
support_macros = None
|
|
|
|
- blacklist = ["init.if", "inetd.if", "uml.if", "thunderbird.if"]
|
2009-08-19 19:02:29 +00:00
|
|
|
+ blacklist = ["uml.if", "thunderbird.if", "unconfined.if"]
|
2007-12-19 10:40:23 +00:00
|
|
|
|
|
|
|
for dirpath, dirnames, filenames in os.walk(root):
|
|
|
|
for name in filenames:
|
2009-12-09 21:33:50 +00:00
|
|
|
diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/refpolicy.py policycoreutils-2.0.78/sepolgen-1.0.19/src/sepolgen/refpolicy.py
|
|
|
|
--- nsasepolgen/src/sepolgen/refpolicy.py 2009-10-29 15:21:39.000000000 -0400
|
2010-01-08 14:37:32 +00:00
|
|
|
+++ policycoreutils-2.0.78/sepolgen-1.0.19/src/sepolgen/refpolicy.py 2010-01-08 09:33:37.000000000 -0500
|
2009-12-09 21:33:50 +00:00
|
|
|
@@ -398,6 +398,7 @@
|
|
|
|
return "attribute %s;" % self.name
|
|
|
|
|
|
|
|
# Classes representing rules
|
|
|
|
+import selinux.audit2why as audit2why
|
|
|
|
|
|
|
|
class AVRule(Leaf):
|
|
|
|
"""SELinux access vector (AV) rule.
|
2010-01-08 14:37:32 +00:00
|
|
|
@@ -420,21 +421,26 @@
|
|
|
|
AUDITALLOW = 2
|
|
|
|
NEVERALLOW = 3
|
|
|
|
|
|
|
|
- def __init__(self, av=None, parent=None):
|
|
|
|
+ def __init__(self, av=None, parent=None, dontaudit=False):
|
|
|
|
Leaf.__init__(self, parent)
|
|
|
|
self.src_types = IdSet()
|
2009-12-09 21:33:50 +00:00
|
|
|
self.tgt_types = IdSet()
|
|
|
|
self.obj_classes = IdSet()
|
|
|
|
self.perms = IdSet()
|
|
|
|
- self.rule_type = self.ALLOW
|
2010-01-08 14:37:32 +00:00
|
|
|
+ if dontaudit:
|
|
|
|
+ self.rule_type = audit2why.DONTAUDIT
|
|
|
|
+ else:
|
|
|
|
+ self.rule_type = audit2why.TERULE
|
2009-12-09 21:33:50 +00:00
|
|
|
if av:
|
|
|
|
self.from_av(av)
|
|
|
|
|
|
|
|
def __rule_type_str(self):
|
|
|
|
- if self.rule_type == self.ALLOW:
|
|
|
|
+ if self.rule_type == audit2why.TERULE:
|
|
|
|
return "allow"
|
|
|
|
- elif self.rule_type == self.DONTAUDIT:
|
|
|
|
+ elif self.rule_type == audit2why.DONTAUDIT:
|
|
|
|
return "dontaudit"
|
|
|
|
+ elif self.rule_type == audit2why.CONSTRAINT:
|
|
|
|
+ return "#constraint allow"
|
|
|
|
else:
|
|
|
|
return "auditallow"
|
|
|
|
|