[apparmor] [Patch] utils: add limited support for af_unix rules
Steve Beattie
steve at nxnw.org
Wed Aug 27 23:01:03 UTC 2014
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 <steve at 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
<sbeattie at ubuntu.com>
http://NxNW.org/~steve/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <https://lists.ubuntu.com/archives/apparmor/attachments/20140827/d25dcc70/attachment-0001.pgp>
More information about the AppArmor
mailing list