mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-09-05 08:45:22 +00:00
Convert test-severity.py to use the AATest class
This simplifies test-severity.py a lot: - lots of test functions are replaced with tests[] arrays - tempdir handling and cleanup is now done automagically Even if test-severity.py shrunk by 65 lines, all tests are still there. There's even an addition - SeverityTestCap now additionally verifies the result of rank_capability(). Acked-by: Steve Beattie <steve@nxnw.org>
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (C) 2013 Kshitij Gupta <kgupta8592@gmail.com>
|
||||
# Copyright (C) 2014 Canonical, Ltd.
|
||||
# Copyright (C) 2015 Christian Boltz <apparmor@cboltz.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
@@ -13,23 +14,17 @@
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# ----------------------------------------------------------------------
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
import unittest
|
||||
from common_test import AATest, setup_all_loops
|
||||
|
||||
import apparmor.severity as severity
|
||||
from apparmor.common import AppArmorException
|
||||
from common_test import write_file
|
||||
|
||||
class SeverityBaseTest(unittest.TestCase):
|
||||
class SeverityBaseTest(AATest):
|
||||
|
||||
def setUp(self):
|
||||
def AASetup(self):
|
||||
self.sev_db = severity.Severity('severity.db')
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def _simple_severity_test(self, path, expected_rank):
|
||||
rank = self.sev_db.rank(path)
|
||||
self.assertEqual(rank, expected_rank,
|
||||
@@ -41,58 +36,44 @@ class SeverityBaseTest(unittest.TestCase):
|
||||
'expected rank %d, got %d' % (expected_rank, rank))
|
||||
|
||||
class SeverityTest(SeverityBaseTest):
|
||||
def test_perm_x(self):
|
||||
self._simple_severity_w_perm('/usr/bin/whatis', 'x', 5)
|
||||
tests = [
|
||||
(['/usr/bin/whatis', 'x' ], 5),
|
||||
(['/etc', 'x' ], 10),
|
||||
(['/dev/doublehit', 'x' ], 0),
|
||||
(['/dev/doublehit', 'rx' ], 4),
|
||||
(['/dev/doublehit', 'rwx' ], 8),
|
||||
(['/dev/tty10', 'rwx' ], 9),
|
||||
(['/var/adm/foo/**', 'rx' ], 3),
|
||||
(['/etc/apparmor/**', 'r' ], 6),
|
||||
(['/etc/**', 'r' ], 10),
|
||||
(['/usr/foo@bar', 'r' ], 10), ## filename containing @
|
||||
(['/home/foo@bar', 'rw' ], 6), ## filename containing @
|
||||
]
|
||||
|
||||
def test_perm_etc_x(self):
|
||||
self._simple_severity_w_perm('/etc', 'x', 10)
|
||||
|
||||
def test_perm_dev_x(self):
|
||||
self._simple_severity_w_perm('/dev/doublehit', 'x', 0)
|
||||
|
||||
def test_perm_dev_rx(self):
|
||||
self._simple_severity_w_perm('/dev/doublehit', 'rx', 4)
|
||||
|
||||
def test_perm_dev_rwx(self):
|
||||
self._simple_severity_w_perm('/dev/doublehit', 'rwx', 8)
|
||||
|
||||
def test_perm_tty_rwx(self):
|
||||
self._simple_severity_w_perm('/dev/tty10', 'rwx', 9)
|
||||
|
||||
def test_perm_glob_1(self):
|
||||
self._simple_severity_w_perm('/var/adm/foo/**', 'rx', 3)
|
||||
|
||||
def test_cap_kill(self):
|
||||
self._simple_severity_test('CAP_KILL', 8)
|
||||
|
||||
def test_cap_setpcap(self):
|
||||
self._simple_severity_test('CAP_SETPCAP', 9)
|
||||
|
||||
def test_cap_setpcap_lowercase(self):
|
||||
self._simple_severity_test('CAP_setpcap', 9)
|
||||
|
||||
def test_cap_unknown_1(self):
|
||||
self._simple_severity_test('CAP_UNKNOWN', 10)
|
||||
|
||||
def test_cap_unknown_2(self):
|
||||
self._simple_severity_test('CAP_K*', 10)
|
||||
|
||||
def test_perm_apparmor_glob(self):
|
||||
self._simple_severity_w_perm('/etc/apparmor/**', 'r' , 6)
|
||||
|
||||
def test_perm_etc_glob(self):
|
||||
self._simple_severity_w_perm('/etc/**', 'r' , 10)
|
||||
|
||||
def test_perm_filename_w_at_r(self):
|
||||
self._simple_severity_w_perm('/usr/foo@bar', 'r' , 10) ## filename containing @
|
||||
|
||||
def test_perm_filename_w_at_rw(self):
|
||||
self._simple_severity_w_perm('/home/foo@bar', 'rw', 6) ## filename containing @
|
||||
def _run_test(self, params, expected):
|
||||
self._simple_severity_w_perm(params[0], params[1], expected) ## filename containing @
|
||||
|
||||
def test_invalid_rank(self):
|
||||
with self.assertRaises(AppArmorException):
|
||||
self._simple_severity_w_perm('unexpected_unput', 'rw', 6)
|
||||
|
||||
class SeverityTestCap(SeverityBaseTest):
|
||||
tests = [
|
||||
('KILL', 8),
|
||||
('SETPCAP', 9),
|
||||
('setpcap', 9),
|
||||
('UNKNOWN', 10),
|
||||
('K*', 10),
|
||||
]
|
||||
|
||||
def _run_test(self, params, expected):
|
||||
cap_with_prefix = 'CAP_%s' % params
|
||||
self._simple_severity_test(cap_with_prefix, expected)
|
||||
|
||||
rank = self.sev_db.rank_capability(params)
|
||||
self.assertEqual(rank, expected, 'expected rank %d, got %d' % (expected, rank))
|
||||
|
||||
|
||||
class SeverityVarsTest(SeverityBaseTest):
|
||||
|
||||
VARIABLE_DEFINITIONS = '''
|
||||
@@ -108,40 +89,27 @@ class SeverityVarsTest(SeverityBaseTest):
|
||||
@{pids}=@{pid}
|
||||
'''
|
||||
|
||||
def setUp(self):
|
||||
super(SeverityVarsTest, self).setUp()
|
||||
self.tmpdir = tempfile.mkdtemp(prefix='aa-severity-')
|
||||
|
||||
def _init_tunables(self, content=''):
|
||||
if not content:
|
||||
content = self.VARIABLE_DEFINITIONS
|
||||
|
||||
self.rules_file = write_file(self.tmpdir, 'tunables', content)
|
||||
self.rules_file = self.writeTmpfile('tunables', content)
|
||||
|
||||
self.sev_db.load_variables(self.rules_file)
|
||||
|
||||
def tearDown(self):
|
||||
def AATeardown(self):
|
||||
self.sev_db.unload_variables()
|
||||
if os.path.exists(self.tmpdir):
|
||||
shutil.rmtree(self.tmpdir)
|
||||
|
||||
super(SeverityVarsTest, self).tearDown()
|
||||
tests = [
|
||||
(['@{PROC}/sys/vm/overcommit_memory', 'r'], 6),
|
||||
(['@{HOME}/sys/@{PROC}/overcommit_memory', 'r'], 10),
|
||||
(['/overco@{multiarch}mmit_memory', 'r'], 10),
|
||||
(['@{PROC}/sys/@{TFTP_DIR}/overcommit_memory', 'r'], 6),
|
||||
]
|
||||
|
||||
def test_proc_var(self):
|
||||
def _run_test(self, params, expected):
|
||||
self._init_tunables()
|
||||
self._simple_severity_w_perm('@{PROC}/sys/vm/overcommit_memory', 'r', 6)
|
||||
|
||||
def test_home_var(self):
|
||||
self._init_tunables()
|
||||
self._simple_severity_w_perm('@{HOME}/sys/@{PROC}/overcommit_memory', 'r', 10)
|
||||
|
||||
def test_multiarch_var(self):
|
||||
self._init_tunables()
|
||||
self._simple_severity_w_perm('/overco@{multiarch}mmit_memory', 'r', 10)
|
||||
|
||||
def test_proc_tftp_vars(self):
|
||||
self._init_tunables()
|
||||
self._simple_severity_w_perm('@{PROC}/sys/@{TFTP_DIR}/overcommit_memory', 'r', 6)
|
||||
self._simple_severity_w_perm(params[0], params[1], expected)
|
||||
|
||||
def test_include(self):
|
||||
self._init_tunables('#include <file/not/found>') # including non-existing files doesn't raise an exception
|
||||
@@ -156,20 +124,30 @@ class SeverityVarsTest(SeverityBaseTest):
|
||||
with self.assertRaises(AppArmorException):
|
||||
self._init_tunables('@{foo} = /home/\n@{foo} = /root/')
|
||||
|
||||
class SeverityDBTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.tmpdir = tempfile.mkdtemp(prefix='aa-severity-db-')
|
||||
|
||||
def tearDown(self):
|
||||
if os.path.exists(self.tmpdir):
|
||||
shutil.rmtree(self.tmpdir)
|
||||
|
||||
class SeverityDBTest(AATest):
|
||||
def _test_db(self, contents):
|
||||
self.db_file = write_file(self.tmpdir, 'severity.db', contents)
|
||||
self.db_file = self.writeTmpfile('severity.db', contents)
|
||||
self.sev_db = severity.Severity(self.db_file)
|
||||
return self.sev_db
|
||||
|
||||
tests = [
|
||||
("CAP_LEASE 18\n" , AppArmorException), # out of range
|
||||
("CAP_LEASE -1\n" , AppArmorException), # out of range
|
||||
("/etc/passwd* 0 4\n" , AppArmorException), # insufficient vals
|
||||
("/etc/passwd* 0 4 5 6\n" , AppArmorException), # too many vals
|
||||
("/etc/passwd* -2 4 6\n" , AppArmorException), # out of range
|
||||
("/etc/passwd* 12 4 6\n" , AppArmorException), # out of range
|
||||
("/etc/passwd* 2 -4 6\n" , AppArmorException), # out of range
|
||||
("/etc/passwd 2 14 6\n" , AppArmorException), # out of range
|
||||
("/etc/passwd 2 4 -12\n" , AppArmorException), # out of range
|
||||
("/etc/passwd 2 4 4294967297\n" , AppArmorException), # out of range
|
||||
("garbage line\n" , AppArmorException),
|
||||
]
|
||||
|
||||
def _run_test(self, params, expected):
|
||||
with self.assertRaises(expected):
|
||||
self._test_db(params)
|
||||
|
||||
def test_simple_db(self):
|
||||
self._test_db('''
|
||||
CAP_LEASE 8
|
||||
@@ -182,50 +160,6 @@ class SeverityDBTest(unittest.TestCase):
|
||||
def test_cap_val_min_range(self):
|
||||
self._test_db("CAP_LEASE 0\n")
|
||||
|
||||
def test_cap_val_out_of_range_1(self):
|
||||
with self.assertRaises(AppArmorException):
|
||||
self._test_db("CAP_LEASE 18\n")
|
||||
|
||||
def test_cap_val_out_of_range_2(self):
|
||||
with self.assertRaises(AppArmorException):
|
||||
self._test_db("CAP_LEASE -1\n")
|
||||
|
||||
def test_path_insufficient_vals(self):
|
||||
with self.assertRaises(AppArmorException):
|
||||
self._test_db("/etc/passwd* 0 4\n")
|
||||
|
||||
def test_path_too_many_vals(self):
|
||||
with self.assertRaises(AppArmorException):
|
||||
self._test_db("/etc/passwd* 0 4 5 6\n")
|
||||
|
||||
def test_path_outside_range_1(self):
|
||||
with self.assertRaises(AppArmorException):
|
||||
self._test_db("/etc/passwd* -2 4 6\n")
|
||||
|
||||
def test_path_outside_range_2(self):
|
||||
with self.assertRaises(AppArmorException):
|
||||
self._test_db("/etc/passwd* 12 4 6\n")
|
||||
|
||||
def test_path_outside_range_3(self):
|
||||
with self.assertRaises(AppArmorException):
|
||||
self._test_db("/etc/passwd* 2 -4 6\n")
|
||||
|
||||
def test_path_outside_range_4(self):
|
||||
with self.assertRaises(AppArmorException):
|
||||
self._test_db("/etc/passwd 2 14 6\n")
|
||||
|
||||
def test_path_outside_range_5(self):
|
||||
with self.assertRaises(AppArmorException):
|
||||
self._test_db("/etc/passwd 2 4 -12\n")
|
||||
|
||||
def test_path_outside_range_6(self):
|
||||
with self.assertRaises(AppArmorException):
|
||||
self._test_db("/etc/passwd 2 4 4294967297\n")
|
||||
|
||||
def test_garbage_line(self):
|
||||
with self.assertRaises(AppArmorException):
|
||||
self._test_db("garbage line\n")
|
||||
|
||||
def test_invalid_db(self):
|
||||
self.assertRaises(AppArmorException, severity.Severity, 'severity_broken.db')
|
||||
|
||||
@@ -236,5 +170,6 @@ class SeverityDBTest(unittest.TestCase):
|
||||
with self.assertRaises(AppArmorException):
|
||||
severity.Severity()
|
||||
|
||||
if __name__ == "__main__":
|
||||
setup_all_loops(__name__)
|
||||
if __name__ == '__main__':
|
||||
unittest.main(verbosity=2)
|
||||
|
Reference in New Issue
Block a user