diff --git a/utils/apparmor/rule/capability.py b/utils/apparmor/rule/capability.py index 85f1de048..19d4be4a0 100644 --- a/utils/apparmor/rule/capability.py +++ b/utils/apparmor/rule/capability.py @@ -126,6 +126,20 @@ class CapabilityRule(BaseRule): return True + def severity(self, sev_db): + if self.all_caps: + severity = sev_db.rank_capability('__ALL__') + else: + severity = -1 + for cap in self.capability: + sev = sev_db.rank_capability(cap) + if isinstance(sev, int): # type check avoids breakage caused by 'unknown' + severity = max(severity, sev) + + if severity == -1: + severity = sev # effectively 'unknown' + + return severity class CapabilityRuleset(BaseRuleset): '''Class to handle and store a collection of capability rules''' diff --git a/utils/apparmor/severity.py b/utils/apparmor/severity.py index 3244cd4e3..cc7ca7b97 100644 --- a/utils/apparmor/severity.py +++ b/utils/apparmor/severity.py @@ -79,6 +79,8 @@ class Severity(object): def rank_capability(self, resource): """Returns the severity of for the capability resource, default value if no match""" cap = 'CAP_%s' % resource.upper() + if resource == '__ALL__': + return max(self.severity['CAPABILITIES'].values()) if cap in self.severity['CAPABILITIES'].keys(): return self.severity['CAPABILITIES'][cap] # raise ValueError("unexpected capability rank input: %s"%resource) diff --git a/utils/test/test-capability.py b/utils/test/test-capability.py index 7240f2afb..396378b7c 100644 --- a/utils/test/test-capability.py +++ b/utils/test/test-capability.py @@ -18,6 +18,7 @@ from common_test import AATest, setup_all_loops from apparmor.rule.capability import CapabilityRule, CapabilityRuleset from apparmor.rule import BaseRule +import apparmor.severity as severity from apparmor.common import AppArmorException, AppArmorBug, hasher from apparmor.logparser import ReadLog @@ -419,6 +420,20 @@ class CapabilityCoveredTest(AATest): self.assertFalse(self._is_covered(obj2, 'capability sys_admin,')) self.assertTrue(self._is_covered(obj2, 'capability ptrace,')) +class CapabiliySeverityTest(AATest): + tests = [ + ('fsetid', 9), + ('dac_read_search', 7), + (['fsetid', 'dac_read_search'], 9), + (CapabilityRule.ALL, 10), + ('foo', 'unknown'), + ] + def _run_test(self, params, expected): + sev_db = severity.Severity('severity.db', 'unknown') + obj = CapabilityRule(params) + rank = obj.severity(sev_db) + self.assertEqual(rank, expected) + # --- tests for CapabilityRuleset --- # class CapabilityRulesTest(AATest): diff --git a/utils/test/test-severity.py b/utils/test/test-severity.py index b8aedcb0a..1686f31a2 100755 --- a/utils/test/test-severity.py +++ b/utils/test/test-severity.py @@ -64,6 +64,7 @@ class SeverityTestCap(SeverityBaseTest): ('setpcap', 9), ('UNKNOWN', 'unknown'), ('K*', 'unknown'), + ('__ALL__', 10), ] def _run_test(self, params, expected):