2016-10-01 20:57:09 +02:00
|
|
|
#!/usr/bin/python3
|
2013-09-28 20:43:06 +05:30
|
|
|
# ----------------------------------------------------------------------
|
|
|
|
# Copyright (C) 2013 Kshitij Gupta <kgupta8592@gmail.com>
|
2014-11-06 12:32:49 -08:00
|
|
|
# Copyright (C) 2014 Canonical, Ltd.
|
2015-05-29 23:31:56 +02:00
|
|
|
# Copyright (C) 2015 Christian Boltz <apparmor@cboltz.de>
|
2013-09-28 20:43:06 +05:30
|
|
|
#
|
|
|
|
# This program is free software; you can redistribute it and/or
|
|
|
|
# modify it under the terms of version 2 of the GNU General Public
|
|
|
|
# License as published by the Free Software Foundation.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# ----------------------------------------------------------------------
|
2013-06-21 20:08:32 +05:30
|
|
|
import unittest
|
2013-06-25 04:46:59 +05:30
|
|
|
|
2013-07-06 18:57:06 +05:30
|
|
|
import apparmor.severity as severity
|
|
|
|
from apparmor.common import AppArmorException
|
2022-08-07 20:32:07 -04:00
|
|
|
from common_test import AATest, setup_all_loops
|
2013-07-19 00:44:55 +05:30
|
|
|
|
2022-08-07 12:26:24 -04:00
|
|
|
|
2015-05-29 23:31:56 +02:00
|
|
|
class SeverityBaseTest(AATest):
|
2013-09-22 22:51:30 +05:30
|
|
|
|
2015-05-29 23:31:56 +02:00
|
|
|
def AASetup(self):
|
2021-04-14 21:32:34 +02:00
|
|
|
self.sev_db = severity.Severity('../severity.db', 'unknown')
|
2013-09-22 22:51:30 +05:30
|
|
|
|
2016-10-01 20:15:45 +02:00
|
|
|
def _capability_severity_test(self, cap, expected_rank):
|
|
|
|
rank = self.sev_db.rank_capability(cap)
|
2014-11-06 12:32:49 -08:00
|
|
|
self.assertEqual(rank, expected_rank,
|
2023-02-19 16:26:14 -05:00
|
|
|
'expected rank {}, got {}'.format(expected_rank, rank))
|
2013-09-22 22:51:30 +05:30
|
|
|
|
2014-11-06 12:32:49 -08:00
|
|
|
def _simple_severity_w_perm(self, path, perm, expected_rank):
|
2016-10-01 20:15:45 +02:00
|
|
|
rank = self.sev_db.rank_path(path, perm)
|
2014-11-06 12:32:49 -08:00
|
|
|
self.assertEqual(rank, expected_rank,
|
2023-02-19 16:26:14 -05:00
|
|
|
'expected rank {}, got {}'.format(expected_rank, rank))
|
2014-11-06 12:32:49 -08:00
|
|
|
|
2022-08-07 12:26:24 -04:00
|
|
|
|
2014-11-06 12:32:49 -08:00
|
|
|
class SeverityTest(SeverityBaseTest):
|
2022-06-18 14:30:49 -04:00
|
|
|
tests = (
|
2022-08-07 12:26:24 -04:00
|
|
|
(('/usr/bin/whatis', 'x'), 5),
|
|
|
|
(('/etc', 'x'), 'unknown'),
|
|
|
|
(('/dev/doublehit', 'x'), 0),
|
|
|
|
(('/dev/doublehit', 'rx'), 4),
|
2022-06-18 14:30:49 -04:00
|
|
|
(('/dev/doublehit', 'rwx'), 8),
|
|
|
|
(('/dev/tty10', 'rwx'), 9),
|
2022-08-07 12:26:24 -04:00
|
|
|
(('/var/adm/foo/**', 'rx'), 3),
|
|
|
|
(('/etc/apparmor/**', 'r'), 6),
|
|
|
|
(('/etc/**', 'r'), 'unknown'),
|
|
|
|
(('/usr/foo@bar', 'r'), 'unknown'), # filename containing @
|
|
|
|
(('/home/foo@bar', 'rw'), 6), # filename containing @
|
|
|
|
(('/etc/apache2/ssl.key/bar', 'r'), 7), # /etc/apache2/** (3) vs. /etc/apache2/**ssl** (7)
|
|
|
|
(('/etc/apache2/foo/ssl/bar', 'r'), 7), # additional path level triggers otherwise untested branch
|
2022-06-18 14:30:49 -04:00
|
|
|
(('/proc/sys/kernel/hotplug', 'rwx'), 10), # non-glob filename, severity depends on mode
|
|
|
|
)
|
2015-05-29 23:31:56 +02:00
|
|
|
|
|
|
|
def _run_test(self, params, expected):
|
2022-08-14 21:03:35 -04:00
|
|
|
self._simple_severity_w_perm(params[0], params[1], expected)
|
2014-11-06 12:32:49 -08:00
|
|
|
|
2015-05-29 23:31:56 +02:00
|
|
|
def test_invalid_rank(self):
|
|
|
|
with self.assertRaises(AppArmorException):
|
|
|
|
self._simple_severity_w_perm('unexpected_unput', 'rw', 6)
|
2014-11-06 12:32:49 -08:00
|
|
|
|
2022-08-07 12:26:24 -04:00
|
|
|
|
2015-05-29 23:31:56 +02:00
|
|
|
class SeverityTestCap(SeverityBaseTest):
|
2022-06-18 14:30:49 -04:00
|
|
|
tests = (
|
2015-05-29 23:31:56 +02:00
|
|
|
('KILL', 8),
|
|
|
|
('SETPCAP', 9),
|
|
|
|
('setpcap', 9),
|
2015-05-29 23:39:14 +02:00
|
|
|
('UNKNOWN', 'unknown'),
|
|
|
|
('K*', 'unknown'),
|
2015-06-06 13:59:11 +02:00
|
|
|
('__ALL__', 10),
|
2022-06-18 14:30:49 -04:00
|
|
|
)
|
2014-11-06 12:32:49 -08:00
|
|
|
|
2015-05-29 23:31:56 +02:00
|
|
|
def _run_test(self, params, expected):
|
2016-10-01 20:15:45 +02:00
|
|
|
self._capability_severity_test(params, expected)
|
2014-11-06 12:32:49 -08:00
|
|
|
|
2015-05-29 23:31:56 +02:00
|
|
|
rank = self.sev_db.rank_capability(params)
|
2023-02-19 16:26:14 -05:00
|
|
|
self.assertEqual(rank, expected, 'expected rank {}, got {}'.format(expected, rank))
|
2014-11-06 12:32:49 -08:00
|
|
|
|
|
|
|
|
|
|
|
class SeverityVarsTest(SeverityBaseTest):
|
2022-06-18 14:30:49 -04:00
|
|
|
tests = (
|
2022-08-07 12:26:24 -04:00
|
|
|
(('@{PROC}/sys/vm/overcommit_memory', 'r'), 6),
|
|
|
|
(('@{HOME}/sys/@{PROC}/overcommit_memory', 'r'), 4),
|
|
|
|
(('/overco@{multiarch}mmit_memory', 'r'), 'unknown'),
|
|
|
|
(('@{PROC}/sys/@{TFTP_DIR}/overcommit_memory', 'r'), 6),
|
|
|
|
(('@{somepaths}/somefile', 'r'), 7),
|
|
|
|
(('@{strangevar}/somefile', 'r'), 6),
|
2022-06-18 14:30:49 -04:00
|
|
|
)
|
2014-11-06 12:32:49 -08:00
|
|
|
|
2015-05-29 23:31:56 +02:00
|
|
|
def _run_test(self, params, expected):
|
2020-05-23 15:40:03 +02:00
|
|
|
vars = {
|
2022-08-07 12:26:24 -04:00
|
|
|
# Note: using [] instead of {} is intentional to keep order of checking (and therefore code coverage) constant
|
|
|
|
'@{HOME}': ['@{HOMEDIRS}/*/', '/root/'],
|
|
|
|
'@{HOMEDIRS}': ['/home/', '/storage/'],
|
|
|
|
'@{multiarch}': ['*-linux-gnu*'],
|
|
|
|
'@{TFTP_DIR}': ['/var/tftp /srv/tftpboot'],
|
|
|
|
'@{PROC}': ['/proc/'],
|
|
|
|
'@{somepaths}': ['/home/foo/downloads', '@{HOMEDIRS}/foo/.ssh/'],
|
2021-08-19 12:52:56 +02:00
|
|
|
'@{strangevar}': ['/srv/', '/proc/'],
|
2020-05-23 15:40:03 +02:00
|
|
|
}
|
|
|
|
self.sev_db.set_variables(vars)
|
2015-05-29 23:31:56 +02:00
|
|
|
self._simple_severity_w_perm(params[0], params[1], expected)
|
2014-11-06 12:32:49 -08:00
|
|
|
|
2022-08-07 12:26:24 -04:00
|
|
|
|
2015-05-29 23:31:56 +02:00
|
|
|
class SeverityDBTest(AATest):
|
2014-11-06 12:32:49 -08:00
|
|
|
def _test_db(self, contents):
|
2015-05-29 23:31:56 +02:00
|
|
|
self.db_file = self.writeTmpfile('severity.db', contents)
|
2014-11-06 12:32:49 -08:00
|
|
|
self.sev_db = severity.Severity(self.db_file)
|
|
|
|
return self.sev_db
|
|
|
|
|
2022-06-18 14:30:49 -04:00
|
|
|
tests = (
|
2022-08-07 12:26:24 -04:00
|
|
|
("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),
|
2022-06-18 14:30:49 -04:00
|
|
|
)
|
2015-05-29 23:31:56 +02:00
|
|
|
|
|
|
|
def _run_test(self, params, expected):
|
|
|
|
with self.assertRaises(expected):
|
|
|
|
self._test_db(params)
|
|
|
|
|
2014-11-06 12:32:49 -08:00
|
|
|
def test_simple_db(self):
|
2014-11-13 10:58:50 -08:00
|
|
|
self._test_db('''
|
2014-11-06 12:32:49 -08:00
|
|
|
CAP_LEASE 8
|
|
|
|
/etc/passwd* 4 8 0
|
|
|
|
''')
|
|
|
|
|
|
|
|
def test_cap_val_max_range(self):
|
2014-11-13 10:58:50 -08:00
|
|
|
self._test_db("CAP_LEASE 10\n")
|
2014-11-06 12:32:49 -08:00
|
|
|
|
|
|
|
def test_cap_val_min_range(self):
|
2014-11-13 10:58:50 -08:00
|
|
|
self._test_db("CAP_LEASE 0\n")
|
2014-11-06 12:32:49 -08:00
|
|
|
|
|
|
|
def test_invalid_db(self):
|
|
|
|
self.assertRaises(AppArmorException, severity.Severity, 'severity_broken.db')
|
|
|
|
|
|
|
|
def test_nonexistent_db(self):
|
|
|
|
self.assertRaises(IOError, severity.Severity, 'severity.db.does.not.exist')
|
|
|
|
|
|
|
|
def test_no_arg_to_severity(self):
|
2014-11-06 12:37:02 -08:00
|
|
|
with self.assertRaises(AppArmorException):
|
|
|
|
severity.Severity()
|
2013-06-21 20:08:32 +05:30
|
|
|
|
2022-08-07 12:26:24 -04:00
|
|
|
|
2015-05-29 23:31:56 +02:00
|
|
|
setup_all_loops(__name__)
|
|
|
|
if __name__ == '__main__':
|
2018-04-08 20:18:30 +02:00
|
|
|
unittest.main(verbosity=1)
|