]>
Commit | Line | Data |
---|---|---|
db3649f6 SS |
1 | diff --git a/src/sepolgen/audit.py b/src/sepolgen/audit.py |
2 | index 898fbc3..9fdfafa 100644 | |
3 | --- a/src/sepolgen/audit.py | |
4 | +++ b/src/sepolgen/audit.py | |
5 | @@ -127,6 +127,9 @@ class PathMessage(AuditMessage): | |
6 | if fields[0] == "path": | |
7 | self.path = fields[1][1:-1] | |
8 | return | |
9 | +import selinux.audit2why as audit2why | |
10 | + | |
11 | +avcdict = {} | |
12 | ||
13 | class AVCMessage(AuditMessage): | |
14 | """AVC message representing an access denial or granted message. | |
15 | @@ -168,6 +171,8 @@ class AVCMessage(AuditMessage): | |
16 | self.name = "" | |
17 | self.accesses = [] | |
18 | self.denial = True | |
19 | + self.type = audit2why.TERULE | |
20 | + self.bools = [] | |
21 | ||
22 | def __parse_access(self, recs, start): | |
23 | # This is kind of sucky - the access that is in a space separated | |
24 | @@ -229,7 +234,31 @@ class AVCMessage(AuditMessage): | |
25 | ||
26 | if not found_src or not found_tgt or not found_class or not found_access: | |
27 | raise ValueError("AVC message in invalid format [%s]\n" % self.message) | |
28 | - | |
29 | + self.analyze() | |
30 | + | |
31 | + def analyze(self): | |
32 | + tcontext = self.tcontext.to_string() | |
33 | + scontext = self.scontext.to_string() | |
34 | + access_tuple = tuple( self.accesses) | |
35 | + if (scontext, tcontext, self.tclass, access_tuple) in avcdict.keys(): | |
36 | + self.type, self.bools = avcdict[(scontext, tcontext, self.tclass, access_tuple)] | |
37 | + else: | |
38 | + self.type, self.bools = audit2why.analyze(scontext, tcontext, self.tclass, self.accesses); | |
39 | + if self.type == audit2why.NOPOLICY: | |
40 | + self.type = audit2why.TERULE | |
41 | + if self.type == audit2why.BADTCON: | |
42 | + raise ValueError("Invalid Target Context %s\n" % tcontext) | |
43 | + if self.type == audit2why.BADSCON: | |
44 | + raise ValueError("Invalid Source Context %s\n" % scontext) | |
45 | + if self.type == audit2why.BADSCON: | |
46 | + raise ValueError("Invalid Type Class %s\n" % self.tclass) | |
47 | + if self.type == audit2why.BADPERM: | |
48 | + raise ValueError("Invalid permission %s\n" % " ".join(self.accesses)) | |
49 | + if self.type == audit2why.BADCOMPUTE: | |
50 | + raise ValueError("Error during access vector computation") | |
51 | + | |
52 | + avcdict[(scontext, tcontext, self.tclass, access_tuple)] = (self.type, self.bools) | |
53 | + | |
54 | class PolicyLoadMessage(AuditMessage): | |
55 | """Audit message indicating that the policy was reloaded.""" | |
56 | def __init__(self, message): | |
57 | @@ -472,10 +501,10 @@ class AuditParser: | |
58 | if avc_filter: | |
59 | if avc_filter.filter(avc): | |
60 | av_set.add(avc.scontext.type, avc.tcontext.type, avc.tclass, | |
61 | - avc.accesses, avc) | |
62 | + avc.accesses, avc, avc_type=avc.type, bools=avc.bools) | |
63 | else: | |
64 | av_set.add(avc.scontext.type, avc.tcontext.type, avc.tclass, | |
65 | - avc.accesses, avc) | |
66 | + avc.accesses, avc, avc_type=avc.type, bools=avc.bools) | |
67 | return av_set | |
68 | ||
69 | class AVCTypeFilter: | |
70 | diff --git a/src/sepolgen/matching.py b/src/sepolgen/matching.py | |
71 | index 1a9a3e5..d56dd92 100644 | |
72 | --- a/src/sepolgen/matching.py | |
73 | +++ b/src/sepolgen/matching.py | |
74 | @@ -50,7 +50,7 @@ class Match: | |
75 | return 1 | |
76 | ||
77 | class MatchList: | |
78 | - DEFAULT_THRESHOLD = 120 | |
79 | + DEFAULT_THRESHOLD = 150 | |
80 | def __init__(self): | |
81 | # Match objects that pass the threshold | |
82 | self.children = [] | |
83 | @@ -63,14 +63,15 @@ class MatchList: | |
84 | def best(self): | |
85 | if len(self.children): | |
86 | return self.children[0] | |
87 | - else: | |
88 | - return None | |
89 | + if len(self.bastards): | |
90 | + return self.bastards[0] | |
91 | + return None | |
92 | ||
93 | def __len__(self): | |
94 | # Only return the length of the matches so | |
95 | # that this can be used to test if there is | |
96 | # a match. | |
97 | - return len(self.children) | |
98 | + return len(self.children) + len(self.bastards) | |
99 | ||
100 | def __iter__(self): | |
101 | return iter(self.children) | |
102 | diff --git a/src/sepolgen/policygen.py b/src/sepolgen/policygen.py | |
103 | index 0e6b502..4882999 100644 | |
104 | --- a/src/sepolgen/policygen.py | |
105 | +++ b/src/sepolgen/policygen.py | |
106 | @@ -29,6 +29,8 @@ import objectmodel | |
107 | import access | |
108 | import interfaces | |
109 | import matching | |
110 | +import selinux.audit2why as audit2why | |
111 | +from setools import * | |
112 | ||
113 | # Constants for the level of explanation from the generation | |
114 | # routines | |
115 | @@ -77,6 +79,7 @@ class PolicyGenerator: | |
116 | ||
117 | self.dontaudit = False | |
118 | ||
119 | + self.domains = None | |
120 | def set_gen_refpol(self, if_set=None, perm_maps=None): | |
121 | """Set whether reference policy interfaces are generated. | |
122 | ||
123 | @@ -151,8 +154,41 @@ class PolicyGenerator: | |
124 | rule = refpolicy.AVRule(av) | |
125 | if self.dontaudit: | |
126 | rule.rule_type = rule.DONTAUDIT | |
127 | + rule.comment = "" | |
128 | if self.explain: | |
129 | - rule.comment = refpolicy.Comment(explain_access(av, verbosity=self.explain)) | |
130 | + rule.comment = str(refpolicy.Comment(explain_access(av, verbosity=self.explain))) | |
131 | + if av.type == audit2why.ALLOW: | |
132 | + rule.comment += "#!!!! This avc is allowed in the current policy\n" | |
133 | + if av.type == audit2why.DONTAUDIT: | |
134 | + rule.comment += "#!!!! This avc has a dontaudit rule in the current policy\n" | |
135 | + | |
136 | + if av.type == audit2why.BOOLEAN: | |
137 | + if len(av.bools) > 1: | |
138 | + rule.comment += "#!!!! This avc can be allowed using one of the these booleans:\n# %s\n" % ", ".join(map(lambda x: x[0], av.bools)) | |
139 | + else: | |
140 | + rule.comment += "#!!!! This avc can be allowed using the boolean '%s'\n" % av.bools[0][0] | |
141 | + | |
142 | + if av.type == audit2why.CONSTRAINT: | |
143 | + 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" | |
144 | + rule.comment += "#Constraint rule: " | |
145 | + | |
146 | + if av.type == audit2why.TERULE: | |
147 | + if "write" in av.perms: | |
148 | + if "dir" in av.obj_class or "open" in av.perms: | |
149 | + if not self.domains: | |
150 | + self.domains = seinfo(ATTRIBUTE, name="domain")[0]["types"] | |
151 | + types=[] | |
152 | + | |
153 | + try: | |
154 | + for i in map(lambda x: x[TCONTEXT], sesearch([ALLOW], {SCONTEXT: av.src_type, CLASS: av.obj_class, PERMS: av.perms})): | |
155 | + if i not in self.domains: | |
156 | + types.append(i) | |
157 | + if len(types) == 1: | |
158 | + 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)) | |
159 | + elif len(types) >= 1: | |
160 | + 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)) | |
161 | + except: | |
162 | + pass | |
163 | self.module.children.append(rule) | |
164 | ||
165 | ||
166 | diff --git a/src/sepolgen/refparser.py b/src/sepolgen/refparser.py | |
167 | index 955784d..9a79340 100644 | |
168 | --- a/src/sepolgen/refparser.py | |
169 | +++ b/src/sepolgen/refparser.py | |
170 | @@ -245,7 +245,7 @@ def t_refpolicywarn(t): | |
171 | t.lexer.lineno += 1 | |
172 | ||
173 | def t_IDENTIFIER(t): | |
174 | - r'[a-zA-Z_\$\"][a-zA-Z0-9_\-\.\$\*\"]*' | |
175 | + r'[a-zA-Z_\$\"][a-zA-Z0-9_\-\.\$\*\"~]*' | |
176 | # Handle any keywords | |
177 | t.type = reserved.get(t.value,'IDENTIFIER') | |
178 | return t | |
179 | diff --git a/src/sepolgen/yacc.py b/src/sepolgen/yacc.py | |
180 | index 58332de..2f3c09d 100644 | |
181 | --- a/src/sepolgen/yacc.py | |
182 | +++ b/src/sepolgen/yacc.py | |
183 | @@ -594,7 +594,7 @@ class MiniProduction: | |
184 | pass | |
185 | ||
186 | # regex matching identifiers | |
187 | -_is_identifier = re.compile(r'^[a-zA-Z0-9_-]+$') | |
188 | +_is_identifier = re.compile(r'^[a-zA-Z0-9_-~]+$') | |
189 | ||
190 | # ----------------------------------------------------------------------------- | |
191 | # add_production() |