93a347a42a
Fix sepolgen to handle filename transitions
520 lines
21 KiB
Diff
520 lines
21 KiB
Diff
diff -up policycoreutils-2.0.86/sepolgen-1.0.23/src/sepolgen/access.py.sepolgen policycoreutils-2.0.86/sepolgen-1.0.23/src/sepolgen/access.py
|
|
--- policycoreutils-2.0.86/sepolgen-1.0.23/src/sepolgen/access.py.sepolgen 2010-03-24 15:57:20.000000000 -0400
|
|
+++ policycoreutils-2.0.86/sepolgen-1.0.23/src/sepolgen/access.py 2011-05-25 16:11:58.150628048 -0400
|
|
@@ -32,6 +32,7 @@ in a variety of ways, but they are the f
|
|
"""
|
|
|
|
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 @@ class AccessVector:
|
|
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
|
|
@@ -253,20 +256,22 @@ class AccessVectorSet:
|
|
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 -up policycoreutils-2.0.86/sepolgen-1.0.23/src/sepolgen/audit.py.sepolgen policycoreutils-2.0.86/sepolgen-1.0.23/src/sepolgen/audit.py
|
|
--- policycoreutils-2.0.86/sepolgen-1.0.23/src/sepolgen/audit.py.sepolgen 2010-03-24 15:57:20.000000000 -0400
|
|
+++ policycoreutils-2.0.86/sepolgen-1.0.23/src/sepolgen/audit.py 2011-05-25 16:11:58.150628048 -0400
|
|
@@ -68,6 +68,17 @@ def get_dmesg_msgs():
|
|
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:
|
|
@@ -127,6 +138,9 @@ class PathMessage(AuditMessage):
|
|
if fields[0] == "path":
|
|
self.path = fields[1][1:-1]
|
|
return
|
|
+import selinux.audit2why as audit2why
|
|
+
|
|
+avcdict = {}
|
|
|
|
class AVCMessage(AuditMessage):
|
|
"""AVC message representing an access denial or granted message.
|
|
@@ -167,6 +181,8 @@ class AVCMessage(AuditMessage):
|
|
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
|
|
@@ -226,7 +242,31 @@ class AVCMessage(AuditMessage):
|
|
|
|
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()
|
|
+ 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:
|
|
+ self.type = audit2why.TERULE
|
|
+ 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)
|
|
+
|
|
class PolicyLoadMessage(AuditMessage):
|
|
"""Audit message indicating that the policy was reloaded."""
|
|
def __init__(self, message):
|
|
@@ -469,10 +509,10 @@ class AuditParser:
|
|
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:
|
|
diff -up policycoreutils-2.0.86/sepolgen-1.0.23/src/sepolgen/defaults.py.sepolgen policycoreutils-2.0.86/sepolgen-1.0.23/src/sepolgen/defaults.py
|
|
--- policycoreutils-2.0.86/sepolgen-1.0.23/src/sepolgen/defaults.py.sepolgen 2010-03-24 15:57:20.000000000 -0400
|
|
+++ policycoreutils-2.0.86/sepolgen-1.0.23/src/sepolgen/defaults.py 2011-05-25 16:11:58.150628048 -0400
|
|
@@ -30,6 +30,9 @@ def perm_map():
|
|
def interface_info():
|
|
return data_dir() + "/interface_info"
|
|
|
|
+def attribute_info():
|
|
+ return data_dir() + "/attribute_info"
|
|
+
|
|
def refpolicy_devel():
|
|
return "/usr/share/selinux/devel"
|
|
|
|
diff -up policycoreutils-2.0.86/sepolgen-1.0.23/src/sepolgen/interfaces.py.sepolgen policycoreutils-2.0.86/sepolgen-1.0.23/src/sepolgen/interfaces.py
|
|
--- policycoreutils-2.0.86/sepolgen-1.0.23/src/sepolgen/interfaces.py.sepolgen 2010-03-24 15:57:20.000000000 -0400
|
|
+++ policycoreutils-2.0.86/sepolgen-1.0.23/src/sepolgen/interfaces.py 2011-05-25 16:11:58.151628058 -0400
|
|
@@ -29,6 +29,8 @@ import matching
|
|
|
|
from sepolgeni18n import _
|
|
|
|
+import copy
|
|
+
|
|
class Param:
|
|
"""
|
|
Object representing a paramater for an interface.
|
|
@@ -197,10 +199,48 @@ def ifcall_extract_params(ifcall, params
|
|
ret = 1
|
|
|
|
return ret
|
|
-
|
|
+
|
|
+class AttributeVector:
|
|
+ def __init__(self):
|
|
+ self.name = ""
|
|
+ self.access = access.AccessVectorSet()
|
|
+
|
|
+ def add_av(self, av):
|
|
+ self.access.add_av(av)
|
|
+
|
|
+class AttributeSet:
|
|
+ def __init__(self):
|
|
+ self.attributes = { }
|
|
+
|
|
+ def add_attr(self, attr):
|
|
+ self.attributes[attr.name] = attr
|
|
+
|
|
+ def from_file(self, fd):
|
|
+ def parse_attr(line):
|
|
+ fields = line[1:-1].split()
|
|
+ if len(fields) != 2 or fields[0] != "Attribute":
|
|
+ raise SyntaxError("Syntax error Attribute statement %s" % line)
|
|
+ a = AttributeVector()
|
|
+ a.name = fields[1]
|
|
+
|
|
+ return a
|
|
+
|
|
+ a = None
|
|
+ for line in fd:
|
|
+ line = line[:-1]
|
|
+ if line[0] == "[":
|
|
+ if a:
|
|
+ self.add_attr(a)
|
|
+ a = parse_attr(line)
|
|
+ elif a:
|
|
+ l = line.split(",")
|
|
+ av = access.AccessVector(l)
|
|
+ a.add_av(av)
|
|
+ if a:
|
|
+ self.add_attr(a)
|
|
|
|
class InterfaceVector:
|
|
- def __init__(self, interface=None):
|
|
+ def __init__(self, interface=None, attributes={}):
|
|
# Enabled is a loose concept currently - we are essentially
|
|
# not enabling interfaces that we can't handle currently.
|
|
# See InterfaceVector.add_ifv for more information.
|
|
@@ -214,10 +254,10 @@ class InterfaceVector:
|
|
# value: Param object).
|
|
self.params = { }
|
|
if interface:
|
|
- self.from_interface(interface)
|
|
+ self.from_interface(interface, attributes)
|
|
self.expanded = False
|
|
|
|
- def from_interface(self, interface):
|
|
+ def from_interface(self, interface, attributes={}):
|
|
self.name = interface.name
|
|
|
|
# Add allow rules
|
|
@@ -232,6 +272,23 @@ class InterfaceVector:
|
|
for av in avs:
|
|
self.add_av(av)
|
|
|
|
+ # Add typeattribute access
|
|
+ if attributes != None:
|
|
+ for typeattribute in interface.typeattributes():
|
|
+ for attr in typeattribute.attributes:
|
|
+ if not attributes.attributes.has_key(attr):
|
|
+ # print "missing attribute " + attr
|
|
+ continue
|
|
+ attr_vec = attributes.attributes[attr]
|
|
+ for a in attr_vec.access:
|
|
+ av = copy.copy(a)
|
|
+ if av.src_type == attr_vec.name:
|
|
+ av.src_type = typeattribute.type
|
|
+ if av.tgt_type == attr_vec.name:
|
|
+ av.tgt_type = typeattribute.type
|
|
+ self.add_av(av)
|
|
+
|
|
+
|
|
# Extract paramaters from roles
|
|
for role in interface.roles():
|
|
if role_extract_params(role, self.params):
|
|
@@ -346,13 +403,13 @@ class InterfaceSet:
|
|
l = self.tgt_type_map.setdefault(type, [])
|
|
l.append(ifv)
|
|
|
|
- def add(self, interface):
|
|
- ifv = InterfaceVector(interface)
|
|
+ def add(self, interface, attributes={}):
|
|
+ ifv = InterfaceVector(interface, attributes)
|
|
self.add_ifv(ifv)
|
|
|
|
- def add_headers(self, headers, output=None):
|
|
+ def add_headers(self, headers, output=None, attributes={}):
|
|
for i in itertools.chain(headers.interfaces(), headers.templates()):
|
|
- self.add(i)
|
|
+ self.add(i, attributes)
|
|
|
|
self.expand_ifcalls(headers)
|
|
self.index()
|
|
diff -up policycoreutils-2.0.86/sepolgen-1.0.23/src/sepolgen/matching.py.sepolgen policycoreutils-2.0.86/sepolgen-1.0.23/src/sepolgen/matching.py
|
|
--- policycoreutils-2.0.86/sepolgen-1.0.23/src/sepolgen/matching.py.sepolgen 2010-03-24 15:57:20.000000000 -0400
|
|
+++ policycoreutils-2.0.86/sepolgen-1.0.23/src/sepolgen/matching.py 2011-05-25 16:11:58.151628058 -0400
|
|
@@ -50,7 +50,7 @@ class Match:
|
|
return 1
|
|
|
|
class MatchList:
|
|
- DEFAULT_THRESHOLD = 120
|
|
+ DEFAULT_THRESHOLD = 150
|
|
def __init__(self):
|
|
# Match objects that pass the threshold
|
|
self.children = []
|
|
@@ -63,14 +63,15 @@ class MatchList:
|
|
def best(self):
|
|
if len(self.children):
|
|
return self.children[0]
|
|
- else:
|
|
- return None
|
|
+ if len(self.bastards):
|
|
+ return self.bastards[0]
|
|
+ return None
|
|
|
|
def __len__(self):
|
|
# Only return the length of the matches so
|
|
# that this can be used to test if there is
|
|
# a match.
|
|
- return len(self.children)
|
|
+ return len(self.children) + len(self.bastards)
|
|
|
|
def __iter__(self):
|
|
return iter(self.children)
|
|
diff -up policycoreutils-2.0.86/sepolgen-1.0.23/src/sepolgen/policygen.py.sepolgen policycoreutils-2.0.86/sepolgen-1.0.23/src/sepolgen/policygen.py
|
|
--- policycoreutils-2.0.86/sepolgen-1.0.23/src/sepolgen/policygen.py.sepolgen 2010-03-24 15:57:20.000000000 -0400
|
|
+++ policycoreutils-2.0.86/sepolgen-1.0.23/src/sepolgen/policygen.py 2011-05-25 16:11:58.151628058 -0400
|
|
@@ -29,6 +29,8 @@ import objectmodel
|
|
import access
|
|
import interfaces
|
|
import matching
|
|
+import selinux.audit2why as audit2why
|
|
+from setools import *
|
|
|
|
# Constants for the level of explanation from the generation
|
|
# routines
|
|
@@ -77,6 +79,7 @@ class PolicyGenerator:
|
|
|
|
self.dontaudit = False
|
|
|
|
+ self.domains = None
|
|
def set_gen_refpol(self, if_set=None, perm_maps=None):
|
|
"""Set whether reference policy interfaces are generated.
|
|
|
|
@@ -151,8 +154,41 @@ class PolicyGenerator:
|
|
rule = refpolicy.AVRule(av)
|
|
if self.dontaudit:
|
|
rule.rule_type = rule.DONTAUDIT
|
|
+ rule.comment = ""
|
|
if self.explain:
|
|
- rule.comment = refpolicy.Comment(explain_access(av, verbosity=self.explain))
|
|
+ rule.comment = str(refpolicy.Comment(explain_access(av, verbosity=self.explain)))
|
|
+ if av.type == audit2why.ALLOW:
|
|
+ rule.comment += "#!!!! This avc is allowed in the current policy\n"
|
|
+ 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: x[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"
|
|
+ rule.comment += "#Contraint rule: "
|
|
+
|
|
+ if av.type == audit2why.TERULE:
|
|
+ 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=[]
|
|
+
|
|
+ try:
|
|
+ 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))
|
|
+ except:
|
|
+ pass
|
|
self.module.children.append(rule)
|
|
|
|
|
|
diff -up policycoreutils-2.0.86/sepolgen-1.0.23/src/sepolgen/refparser.py.sepolgen policycoreutils-2.0.86/sepolgen-1.0.23/src/sepolgen/refparser.py
|
|
--- policycoreutils-2.0.86/sepolgen-1.0.23/src/sepolgen/refparser.py.sepolgen 2010-03-24 15:57:20.000000000 -0400
|
|
+++ policycoreutils-2.0.86/sepolgen-1.0.23/src/sepolgen/refparser.py 2011-05-25 16:18:20.911964611 -0400
|
|
@@ -243,7 +243,7 @@ def t_refpolicywarn(t):
|
|
t.lexer.lineno += 1
|
|
|
|
def t_IDENTIFIER(t):
|
|
- r'[a-zA-Z_\$][a-zA-Z0-9_\-\.\$\*]*'
|
|
+ r'[a-zA-Z_\$\"][a-zA-Z0-9_\-\.\$\*\"]*'
|
|
# Handle any keywords
|
|
t.type = reserved.get(t.value,'IDENTIFIER')
|
|
return t
|
|
@@ -768,6 +768,7 @@ def p_avrule_def(p):
|
|
|
|
def p_typerule_def(p):
|
|
'''typerule_def : TYPE_TRANSITION names names COLON names IDENTIFIER SEMI
|
|
+ | TYPE_TRANSITION names names COLON names IDENTIFIER IDENTIFIER SEMI
|
|
| TYPE_CHANGE names names COLON names IDENTIFIER SEMI
|
|
| TYPE_MEMBER names names COLON names IDENTIFIER SEMI
|
|
'''
|
|
@@ -1044,7 +1045,7 @@ def parse_headers(root, output=None, exp
|
|
# of misc_macros. We are just going to pretend that this is an interface
|
|
# to make the expansion work correctly.
|
|
can_exec = refpolicy.Interface("can_exec")
|
|
- av = access.AccessVector(["$1","$2","file","execute_no_trans","read",
|
|
+ av = access.AccessVector(["$1","$2","file","execute_no_trans","open", "read",
|
|
"getattr","lock","execute","ioctl"])
|
|
|
|
can_exec.children.append(refpolicy.AVRule(av))
|
|
diff -up policycoreutils-2.0.86/sepolgen-1.0.23/src/share/perm_map.sepolgen policycoreutils-2.0.86/sepolgen-1.0.23/src/share/perm_map
|
|
--- policycoreutils-2.0.86/sepolgen-1.0.23/src/share/perm_map.sepolgen 2010-03-24 15:57:20.000000000 -0400
|
|
+++ policycoreutils-2.0.86/sepolgen-1.0.23/src/share/perm_map 2011-05-25 16:11:58.152628068 -0400
|
|
@@ -124,7 +124,7 @@ class filesystem 10
|
|
quotamod w 1
|
|
quotaget r 1
|
|
|
|
-class file 20
|
|
+class file 21
|
|
execute_no_trans r 1
|
|
entrypoint r 1
|
|
execmod n 1
|
|
@@ -141,48 +141,50 @@ class file 20
|
|
unlink w 1
|
|
link w 1
|
|
rename w 5
|
|
- execute r 100
|
|
+ execute r 10
|
|
swapon b 1
|
|
quotaon b 1
|
|
mounton b 1
|
|
+ open r 1
|
|
|
|
-class dir 22
|
|
- add_name w 5
|
|
+class dir 23
|
|
+ add_name w 1
|
|
remove_name w 1
|
|
reparent w 1
|
|
search r 1
|
|
rmdir b 1
|
|
ioctl n 1
|
|
- read r 10
|
|
- write w 10
|
|
+ read r 1
|
|
+ write w 1
|
|
create w 1
|
|
- getattr r 7
|
|
- setattr w 7
|
|
+ getattr r 1
|
|
+ setattr w 1
|
|
lock n 1
|
|
- relabelfrom r 10
|
|
- relabelto w 10
|
|
+ relabelfrom r 1
|
|
+ relabelto w 1
|
|
append w 1
|
|
unlink w 1
|
|
link w 1
|
|
- rename w 5
|
|
+ rename w 1
|
|
execute r 1
|
|
swapon b 1
|
|
quotaon b 1
|
|
mounton b 1
|
|
+ open r 1
|
|
|
|
class fd 1
|
|
use b 1
|
|
|
|
-class lnk_file 17
|
|
+class lnk_file 18
|
|
ioctl n 1
|
|
- read r 10
|
|
- write w 10
|
|
+ read r 1
|
|
+ write w 1
|
|
create w 1
|
|
- getattr r 7
|
|
- setattr w 7
|
|
+ getattr r 1
|
|
+ setattr w 1
|
|
lock n 1
|
|
- relabelfrom r 10
|
|
- relabelto w 10
|
|
+ relabelfrom r 1
|
|
+ relabelto w 1
|
|
append w 1
|
|
unlink w 1
|
|
link w 1
|
|
@@ -191,8 +193,9 @@ class lnk_file 17
|
|
swapon b 1
|
|
quotaon b 1
|
|
mounton b 1
|
|
+ open r 1
|
|
|
|
-class chr_file 20
|
|
+class chr_file 21
|
|
execute_no_trans r 1
|
|
entrypoint r 1
|
|
execmod n 1
|
|
@@ -213,8 +216,9 @@ class chr_file 20
|
|
swapon b 1
|
|
quotaon b 1
|
|
mounton b 1
|
|
+ open r 1
|
|
|
|
-class blk_file 17
|
|
+class blk_file 18
|
|
ioctl n 1
|
|
read r 10
|
|
write w 10
|
|
@@ -232,8 +236,9 @@ class blk_file 17
|
|
swapon b 1
|
|
quotaon b 1
|
|
mounton b 1
|
|
+ open r 1
|
|
|
|
-class sock_file 17
|
|
+class sock_file 18
|
|
ioctl n 1
|
|
read r 10
|
|
write w 10
|
|
@@ -251,8 +256,9 @@ class sock_file 17
|
|
swapon b 1
|
|
quotaon b 1
|
|
mounton b 1
|
|
+ open r 1
|
|
|
|
-class fifo_file 17
|
|
+class fifo_file 18
|
|
ioctl n 1
|
|
read r 10
|
|
write w 10
|
|
@@ -270,6 +276,7 @@ class fifo_file 17
|
|
swapon b 1
|
|
quotaon b 1
|
|
mounton b 1
|
|
+ open r 1
|
|
|
|
class socket 22
|
|
ioctl n 1
|