2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-08-31 22:35:35 +00:00

[21/38] Add severity support to FileRule

Also add a rank_path() function to severity.py and change rank() to call
rank_path() for paths.
Long-term goal: get rid of the type "guessing" in rank()

Finally add some tests, mostly based on test-severity.py SeverityTest


Acked-by: Steve Beattie <steve@nxnw.org>
This commit is contained in:
Christian Boltz
2016-10-01 20:02:34 +02:00
parent 875f9cf7d9
commit 8dc09bd643
3 changed files with 49 additions and 2 deletions

View File

@@ -306,6 +306,20 @@ class FileRule(BaseRule):
return True
def severity(self, sev_db):
if self.all_paths:
severity = sev_db.rank_path('/**', 'mrwlkix')
else:
severity = -1
sev = sev_db.rank_path(self.path.regex, self._joint_perms())
if isinstance(sev, int): # type check avoids breakage caused by 'unknown'
severity = max(severity, sev)
if severity == -1:
severity = sev # effectively 'unknown'
return severity
def logprof_header_localvars(self):
if self.owner:
owner = _('Yes')

View File

@@ -88,6 +88,15 @@ class Severity(object):
warn("unknown capability: %s" % resource)
return self.severity['DEFAULT_RANK']
def rank_path(self, path, mode=None):
"""Returns the rank for the given path"""
if '@' in path: # path contains variable
return self.handle_variable_rank(path, mode)
elif path[0] == '/': # file resource
return self.handle_file(path, mode)
else:
raise AppArmorException("Unexpected path input: %s" % path)
def check_subtree(self, tree, mode, sev, segments):
"""Returns the max severity from the regex tree"""
if len(segments) == 0:
@@ -136,9 +145,9 @@ class Severity(object):
def rank(self, resource, mode=None):
"""Returns the rank for the resource file/capability"""
if '@' in resource: # path contains variable
return self.handle_variable_rank(resource, mode)
return self.rank_path(resource, mode)
elif resource[0] == '/': # file resource
return self.handle_file(resource, mode)
return self.rank_path(resource, mode)
elif resource[0:4] == 'CAP_': # capability resource
return self.rank_capability(resource[4:])
else:

View File

@@ -19,6 +19,7 @@ from common_test import AATest, setup_all_loops
from apparmor.rule.file import FileRule, FileRuleset
from apparmor.rule import BaseRule
import apparmor.severity as severity
from apparmor.common import AppArmorException, AppArmorBug
from apparmor.logparser import ReadLog
from apparmor.translations import init_translation
@@ -697,6 +698,29 @@ class FileCoveredTest_ManualOrInvalid(AATest):
with self.assertRaises(AppArmorBug):
obj.is_equal(testobj)
class FileSeverityTest(AATest):
tests = [
('/usr/bin/whatis ix,', 5),
('/etc ix,', 'unknown'),
('/dev/doublehit ix,', 0),
('/dev/doublehit rix,', 4),
('/dev/doublehit rwix,', 8),
('/dev/tty10 rwix,', 9),
('/var/adm/foo/** rix,', 3),
('/etc/apparmor/** r,', 6),
('/etc/** r,', 'unknown'),
('/usr/foo@bar r,', 'unknown'), # filename containing @
('/home/foo@bar rw,', 6), # filename containing @
('file,', 'unknown'), # bare file rule XXX should return maximum severity
]
def _run_test(self, params, expected):
sev_db = severity.Severity('severity.db', 'unknown')
obj = FileRule.parse(params)
rank = obj.severity(sev_db)
self.assertEqual(rank, expected)
#class FileLogprofHeaderTest(AATest):
# tests = [
# ('file,', [ _('Access mode'), _('ALL'), _('Bus'), _('ALL'), _('Path'), _('ALL'), _('Name'), _('ALL'), _('Interface'), _('ALL'), _('Member'), _('ALL'), _('Peer exec_perms'), _('ALL'), _('Peer label'), _('ALL')]),