2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-09-03 15:55:46 +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 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): def logprof_header_localvars(self):
if self.owner: if self.owner:
owner = _('Yes') owner = _('Yes')

View File

@@ -88,6 +88,15 @@ class Severity(object):
warn("unknown capability: %s" % resource) warn("unknown capability: %s" % resource)
return self.severity['DEFAULT_RANK'] 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): def check_subtree(self, tree, mode, sev, segments):
"""Returns the max severity from the regex tree""" """Returns the max severity from the regex tree"""
if len(segments) == 0: if len(segments) == 0:
@@ -136,9 +145,9 @@ class Severity(object):
def rank(self, resource, mode=None): def rank(self, resource, mode=None):
"""Returns the rank for the resource file/capability""" """Returns the rank for the resource file/capability"""
if '@' in resource: # path contains variable if '@' in resource: # path contains variable
return self.handle_variable_rank(resource, mode) return self.rank_path(resource, mode)
elif resource[0] == '/': # file resource elif resource[0] == '/': # file resource
return self.handle_file(resource, mode) return self.rank_path(resource, mode)
elif resource[0:4] == 'CAP_': # capability resource elif resource[0:4] == 'CAP_': # capability resource
return self.rank_capability(resource[4:]) return self.rank_capability(resource[4:])
else: 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.file import FileRule, FileRuleset
from apparmor.rule import BaseRule from apparmor.rule import BaseRule
import apparmor.severity as severity
from apparmor.common import AppArmorException, AppArmorBug from apparmor.common import AppArmorException, AppArmorBug
from apparmor.logparser import ReadLog from apparmor.logparser import ReadLog
from apparmor.translations import init_translation from apparmor.translations import init_translation
@@ -697,6 +698,29 @@ class FileCoveredTest_ManualOrInvalid(AATest):
with self.assertRaises(AppArmorBug): with self.assertRaises(AppArmorBug):
obj.is_equal(testobj) 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): #class FileLogprofHeaderTest(AATest):
# tests = [ # tests = [
# ('file,', [ _('Access mode'), _('ALL'), _('Bus'), _('ALL'), _('Path'), _('ALL'), _('Name'), _('ALL'), _('Interface'), _('ALL'), _('Member'), _('ALL'), _('Peer exec_perms'), _('ALL'), _('Peer label'), _('ALL')]), # ('file,', [ _('Access mode'), _('ALL'), _('Bus'), _('ALL'), _('Path'), _('ALL'), _('Name'), _('ALL'), _('Interface'), _('ALL'), _('Member'), _('ALL'), _('Peer exec_perms'), _('ALL'), _('Peer label'), _('ALL')]),