This patch adds limited support for af_unix rules in the python utilities, of the "don't touch them, but don't throw a python backtrace when coming across them, either" variety. Testcases are added as well.
Signed-off-by: Steve Beattie <st...@nxnw.org> --- utils/apparmor/aa.py | 27 +++++++++++++++++ utils/apparmor/rules.py | 15 +++++++++ utils/test/test-regex_matches.py | 33 +++++++++++++++++++++ utils/test/test-unix_parse.py | 59 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 133 insertions(+), 1 deletion(-) Index: b/utils/test/test-unix_parse.py =================================================================== --- /dev/null +++ b/utils/test/test-unix_parse.py @@ -0,0 +1,59 @@ +#! /usr/bin/env python +# ------------------------------------------------------------------ +# +# Copyright (C) 2014 Canonical Ltd. +# +# 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 published by the Free Software Foundation. +# +# ------------------------------------------------------------------ + +import apparmor.aa as aa +import unittest + +class AAParseUnixTest(unittest.TestCase): + + def _test_parse_unix_rule(self, rule): + unix = aa.parse_unix_rule(rule) + self.assertEqual(rule, unix.serialize(), + 'ptrace object returned "%s", expected "%s"' % (unix.serialize(), rule)) + + def test_parse_plain_unix_rule(self): + self._test_parse_unix_rule('unix,') + + def test_parse_r_unix_rule(self): + self._test_parse_unix_rule('unix r,') + + def test_parse_w_unix_rule(self): + self._test_parse_unix_rule('unix w,') + + def test_parse_rw_unix_rule(self): + self._test_parse_unix_rule('unix rw,') + + def test_parse_send_unix_rule(self): + self._test_parse_unix_rule('unix send,') + + def test_parse_receive_unix_rule(self): + self._test_parse_unix_rule('unix receive,') + + def test_parse_r_paren_unix_rule(self): + self._test_parse_unix_rule('unix (r),') + + def test_parse_w_paren_unix_rule(self): + self._test_parse_unix_rule('unix (w),') + + def test_parse_rw_paren_unix_rule(self): + self._test_parse_unix_rule('unix (rw),') + + def test_parse_send_paren_unix_rule(self): + self._test_parse_unix_rule('unix (send),') + + def test_parse_receive_paren_unix_rule(self): + self._test_parse_unix_rule('unix (receive),') + + def test_parse_complex_unix_rule(self): + self._test_parse_unix_rule('unix (connect, receive, send) type=stream peer=(label=unconfined,addr="@/tmp/.X11-unix/X[0-9]*"),') + +if __name__ == '__main__': + unittest.main(verbosity=2) Index: b/utils/apparmor/aa.py =================================================================== --- a/utils/apparmor/aa.py +++ b/utils/apparmor/aa.py @@ -2636,6 +2636,7 @@ RE_PROFILE_MOUNT = re.compile('^\s*(audi RE_PROFILE_SIGNAL = re.compile('^\s*(audit\s+)?(allow\s+|deny\s+)?(signal\s*,|signal\s+[^#]*\s*,)\s*(#.*)?$') RE_PROFILE_PTRACE = re.compile('^\s*(audit\s+)?(allow\s+|deny\s+)?(ptrace\s*,|ptrace\s+[^#]*\s*,)\s*(#.*)?$') RE_PROFILE_PIVOT_ROOT = re.compile('^\s*(audit\s+)?(allow\s+|deny\s+)?(pivot_root\s*,|pivot_root\s+[^#]*\s*,)\s*(#.*)?$') +RE_PROFILE_UNIX = re.compile('^\s*(audit\s+)?(allow\s+|deny\s+)?(unix\s*,|unix\s+[^#]*\s*,)\s*(#.*)?$') # match anything that's not " or #, or matching quotes with anything except quotes inside __re_no_or_quoted_hash = '([^#"]|"[^"]*")*' @@ -3110,6 +3111,28 @@ def parse_profile_data(data, file, do_in pivot_root_rules.append(pivot_root_rule) profile_data[profile][hat][allow]['pivot_root'] = pivot_root_rules + elif RE_PROFILE_UNIX.search(line): + matches = RE_PROFILE_UNIX.search(line).groups() + + if not profile: + raise AppArmorException(_('Syntax Error: Unexpected unix entry found in file: %s line: %s') % (file, lineno + 1)) + + audit = False + if matches[0]: + audit = True + allow = 'allow' + if matches[1] and matches[1].strip() == 'deny': + allow = 'deny' + unix = matches[2].strip() + + unix_rule = parse_unix_rule(unix) + unix_rule.audit = audit + unix_rule.deny = (allow == 'deny') + + unix_rules = profile_data[profile][hat][allow].get('unix', list()) + unix_rules.append(unix_rule) + profile_data[profile][hat][allow]['unix'] = unix_rules + elif RE_PROFILE_CHANGE_HAT.search(line): matches = RE_PROFILE_CHANGE_HAT.search(line).groups() @@ -3220,6 +3243,10 @@ def parse_pivot_root_rule(line): # XXX Do real parsing here return aarules.Raw_Pivot_Root_Rule(line) +def parse_unix_rule(line): + # XXX Do real parsing here + return aarules.Raw_Unix_Rule(line) + def separate_vars(vs): """Returns a list of all the values for a variable""" data = [] Index: b/utils/apparmor/rules.py =================================================================== --- a/utils/apparmor/rules.py +++ b/utils/apparmor/rules.py @@ -44,6 +44,18 @@ class DBUS_Rule(object): out += ',' return out +class _Raw_Rule(object): + audit = False + deny = False + + def __init__(self, rule): + self.rule = rule + + def serialize(self): + return "%s%s%s" % ('audit ' if self.audit else '', + 'deny ' if self.deny else '', + self.rule) + class Raw_DBUS_Rule(object): audit = False deny = False @@ -103,3 +115,6 @@ class Raw_Pivot_Root_Rule(object): return "%s%s%s" % ('audit ' if self.audit else '', 'deny ' if self.deny else '', self.rule) + +class Raw_Unix_Rule(_Raw_Rule): + pass Index: b/utils/test/test-regex_matches.py =================================================================== --- a/utils/test/test-regex_matches.py +++ b/utils/test/test-regex_matches.py @@ -58,6 +58,12 @@ regex_has_comma_testcases = [ ('pivot_root /old new%s', 'pivot_root with new'), ('pivot_root /old /new -> child%s', 'pivot_root with child'), + ('unix%s', 'bare unix'), + ('unix create%s', 'simple unix'), + ('peer=(addr=@abad1dea,label=a_profile) %s ', 'peer parens and comma'), + ('type=stream%s', 'unix type'), + ('unix (connect, receive, send)%s', 'unix perms'), + # the following fail due to inadequacies in the regex # ('dbus (r, w, %s', 'incomplete dbus action'), # ('member="{Hello,AddMatch,RemoveMatch, %s', 'incomplete {} regex'), # also invalid policy @@ -334,6 +340,31 @@ class AARegexPivotRoot(unittest.TestCase ('pivot_rootbeer /new, # comment', False), ] +class AARegexUnix(unittest.TestCase): + '''Tests for RE_PROFILE_UNIX''' + + def setUp(self): + self.regex = aa.RE_PROFILE_UNIX + + tests = [ + (' unix,', (None, None, 'unix,', None)), + (' audit unix,', ('audit', None, 'unix,', None)), + (' unix accept,', (None, None, 'unix accept,', None)), + (' allow unix connect,', (None, 'allow', 'unix connect,', None)), + (' audit allow unix bind,', ('audit', 'allow', 'unix bind,', None)), + (' deny unix bind,', (None, 'deny', 'unix bind,', None)), + ('unix peer=(label=@{profile_name}),', + (None, None, 'unix peer=(label=@{profile_name}),', None)), + ('unix (receive) peer=(label=unconfined),', + (None, None, 'unix (receive) peer=(label=unconfined),', None)), + (' unix (getattr, shutdown) peer=(addr=none),', + (None, None, 'unix (getattr, shutdown) peer=(addr=none),', None)), + ('unix (connect, receive, send) type=stream peer=(label=unconfined,addr="@/tmp/dbus-*"),', + (None, None, 'unix (connect, receive, send) type=stream peer=(label=unconfined,addr="@/tmp/dbus-*"),', None)), + ('unixlike', False), + ('deny unixlike,', False), + ] + if __name__ == '__main__': verbosity = 2 @@ -345,7 +376,7 @@ if __name__ == '__main__': test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(AARegexSplitComment)) for tests in (AARegexCapability, AARegexPath, AARegexBareFile, - AARegexDbus, AARegexMount, + AARegexDbus, AARegexMount, AARegexUnix, AARegexSignal, AARegexPtrace, AARegexPivotRoot): setup_regex_tests(tests) test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(tests)) -- Steve Beattie <sbeat...@ubuntu.com> http://NxNW.org/~steve/
signature.asc
Description: Digital signature
-- AppArmor mailing list AppArmor@lists.ubuntu.com Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor