mirror of
https://gitlab.com/apparmor/apparmor.git
synced 2025-03-04 16:35:02 +01:00
utils: Basic support for pivot_root rules
Bug: https://bugs.launchpad.net/bugs/1298678 This patch does bare bones parsing of pivot_root rules and stores the raw strings for writing them out later. It is meant to be a simple change to prevent aa.py from emitting a traceback when encountering pivot_root rules. Signed-off-by: Tyler Hicks <tyhicks@canonical.com> Acked-by: Steve Beattie <steve@nxnw.org> Acked-By: Christian Boltz <apparmor@cboltz.de>
This commit is contained in:
parent
496502b150
commit
432bf597ae
4 changed files with 175 additions and 0 deletions
|
@ -2626,6 +2626,7 @@ RE_PROFILE_DBUS = re.compile('^\s*(audit\s+)?(allow\s+|deny\s+)?(dbus[^#]*\s*,)\
|
|||
RE_PROFILE_MOUNT = re.compile('^\s*(audit\s+)?(allow\s+|deny\s+)?((mount|remount|umount)[^#]*\s*,)\s*(#.*)?$')
|
||||
RE_PROFILE_SIGNAL = re.compile('^\s*(audit\s+)?(allow\s+|deny\s+)?((signal)[^#]*\s*,)\s*(#.*)?$')
|
||||
RE_PROFILE_PTRACE = re.compile('^\s*(audit\s+)?(allow\s+|deny\s+)?((ptrace)[^#]*\s*,)\s*(#.*)?$')
|
||||
RE_PROFILE_PIVOT_ROOT = re.compile('^\s*(audit\s+)?(allow\s+|deny\s+)?((pivot_root)[^#]*\s*,)\s*(#.*)?$')
|
||||
|
||||
# match anything that's not " or #, or matching quotes with anything except quotes inside
|
||||
__re_no_or_quoted_hash = '([^#"]|"[^"]*")*'
|
||||
|
@ -2706,6 +2707,7 @@ def parse_profile_data(data, file, do_include):
|
|||
profile_data[profile][hat]['allow']['mount'] = list()
|
||||
profile_data[profile][hat]['allow']['signal'] = list()
|
||||
profile_data[profile][hat]['allow']['ptrace'] = list()
|
||||
profile_data[profile][hat]['allow']['pivot_root'] = list()
|
||||
# Save the initial comment
|
||||
if initial_comment:
|
||||
profile_data[profile][hat]['initial_comment'] = initial_comment
|
||||
|
@ -3110,6 +3112,28 @@ def parse_profile_data(data, file, do_include):
|
|||
ptrace_rules.append(ptrace_rule)
|
||||
profile_data[profile][hat][allow]['ptrace'] = ptrace_rules
|
||||
|
||||
elif RE_PROFILE_PIVOT_ROOT.search(line):
|
||||
matches = RE_PROFILE_PIVOT_ROOT.search(line).groups()
|
||||
|
||||
if not profile:
|
||||
raise AppArmorException(_('Syntax Error: Unexpected pivot_root 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'
|
||||
pivot_root = matches[2].strip()
|
||||
|
||||
pivot_root_rule = parse_pivot_root_rule(pivot_root)
|
||||
pivot_root_rule.audit = audit
|
||||
pivot_root_rule.deny = (allow == 'deny')
|
||||
|
||||
pivot_root_rules = profile_data[profile][hat][allow].get('pivot_root', list())
|
||||
pivot_root_rules.append(pivot_root_rule)
|
||||
profile_data[profile][hat][allow]['pivot_root'] = pivot_root_rules
|
||||
|
||||
elif RE_PROFILE_CHANGE_HAT.search(line):
|
||||
matches = RE_PROFILE_CHANGE_HAT.search(line).groups()
|
||||
|
||||
|
@ -3216,6 +3240,10 @@ def parse_ptrace_rule(line):
|
|||
# XXX Do real parsing here
|
||||
return aarules.Raw_Ptrace_Rule(line)
|
||||
|
||||
def parse_pivot_root_rule(line):
|
||||
# XXX Do real parsing here
|
||||
return aarules.Raw_Pivot_Root_Rule(line)
|
||||
|
||||
def separate_vars(vs):
|
||||
"""Returns a list of all the values for a variable"""
|
||||
data = []
|
||||
|
@ -3481,6 +3509,24 @@ def write_ptrace(prof_data, depth):
|
|||
data += write_ptrace_rules(prof_data, depth, 'allow')
|
||||
return data
|
||||
|
||||
def write_pivot_root_rules(prof_data, depth, allow):
|
||||
pre = ' ' * depth
|
||||
data = []
|
||||
|
||||
# no pivot_root rules, so return
|
||||
if not prof_data[allow].get('pivot_root', False):
|
||||
return data
|
||||
|
||||
for pivot_root_rule in prof_data[allow]['pivot_root']:
|
||||
data.append('%s%s' % (pre, pivot_root_rule.serialize()))
|
||||
data.append('')
|
||||
return data
|
||||
|
||||
def write_pivot_root(prof_data, depth):
|
||||
data = write_pivot_root_rules(prof_data, depth, 'deny')
|
||||
data += write_pivot_root_rules(prof_data, depth, 'allow')
|
||||
return data
|
||||
|
||||
def write_link_rules(prof_data, depth, allow):
|
||||
pre = ' ' * depth
|
||||
data = []
|
||||
|
@ -3589,6 +3635,7 @@ def write_rules(prof_data, depth):
|
|||
data += write_mount(prof_data, depth)
|
||||
data += write_signal(prof_data, depth)
|
||||
data += write_ptrace(prof_data, depth)
|
||||
data += write_pivot_root(prof_data, depth)
|
||||
data += write_links(prof_data, depth)
|
||||
data += write_paths(prof_data, depth)
|
||||
data += write_change_profile(prof_data, depth)
|
||||
|
@ -3740,6 +3787,7 @@ def serialize_profile_from_old_profile(profile_data, name, options):
|
|||
'mount': write_mount,
|
||||
'signal': write_signal,
|
||||
'ptrace': write_ptrace,
|
||||
'pivot_root': write_pivot_root,
|
||||
'link': write_links,
|
||||
'path': write_paths,
|
||||
'change_profile': write_change_profile,
|
||||
|
@ -3834,6 +3882,7 @@ def serialize_profile_from_old_profile(profile_data, name, options):
|
|||
data += write_mount(write_prof_data[name], depth)
|
||||
data += write_signal(write_prof_data[name], depth)
|
||||
data += write_ptrace(write_prof_data[name], depth)
|
||||
data += write_pivot_root(write_prof_data[name], depth)
|
||||
data += write_links(write_prof_data[name], depth)
|
||||
data += write_paths(write_prof_data[name], depth)
|
||||
data += write_change_profile(write_prof_data[name], depth)
|
||||
|
|
|
@ -91,3 +91,15 @@ class Raw_Ptrace_Rule(object):
|
|||
return "%s%s%s" % ('audit ' if self.audit else '',
|
||||
'deny ' if self.deny else '',
|
||||
self.rule)
|
||||
|
||||
class Raw_Pivot_Root_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)
|
||||
|
|
35
utils/test/test-pivot_root_parse.py
Normal file
35
utils/test/test-pivot_root_parse.py
Normal file
|
@ -0,0 +1,35 @@
|
|||
#! /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 AAParsePivotRootTest(unittest.TestCase):
|
||||
|
||||
def _test_parse_pivot_root_rule(self, rule):
|
||||
pivot_root = aa.parse_pivot_root_rule(rule)
|
||||
self.assertEqual(rule, pivot_root.serialize(),
|
||||
'pivot_root object returned "%s", expected "%s"' % (pivot_root.serialize(), rule))
|
||||
|
||||
def test_parse_plain_pivot_root_rule(self):
|
||||
self._test_parse_pivot_root_rule('pivot_root,')
|
||||
|
||||
def test_parse_old_pivot_root_rule(self):
|
||||
self._test_parse_pivot_root_rule('pivot_root /old,')
|
||||
|
||||
def test_parse_new_pivot_root_rule(self):
|
||||
self._test_parse_pivot_root_rule('pivot_root /old /new,')
|
||||
|
||||
def test_parse_child_pivot_root_rule(self):
|
||||
self._test_parse_pivot_root_rule('pivot_root /old /new -> /usr/bin/child,')
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -53,6 +53,11 @@ regex_has_comma_testcases = [
|
|||
('ptrace (tracedby, readby)%s', 'embedded parens ptrace 01'),
|
||||
('ptrace (trace) peer=/usr/bin/foo%s', 'embedded parens ptrace 02'),
|
||||
|
||||
('pivot_root%s', 'bare pivot_root'),
|
||||
('pivot_root /old%s', 'pivot_root with old'),
|
||||
('pivot_root /old new%s', 'pivot_root with new'),
|
||||
('pivot_root /old /new -> child%s', 'pivot_root with child'),
|
||||
|
||||
# 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
|
||||
|
@ -113,6 +118,8 @@ regex_split_comment_testcases = [
|
|||
('signal receive set=(usr1 usr2) peer=foo,', False),
|
||||
('ptrace, # comment', ('ptrace, ', '# comment')),
|
||||
('ptrace (trace read) peer=/usr/bin/foo,', False),
|
||||
('pivot_root, # comment', ('pivot_root, ', '# comment')),
|
||||
('pivot_root /old /new -> child,', False),
|
||||
]
|
||||
|
||||
def setup_split_comment_testcases():
|
||||
|
@ -443,6 +450,77 @@ class AARegexPtrace(unittest.TestCase):
|
|||
self.assertEqual(parsed, rule, 'Expected ptrace rule "%s", got "%s"'
|
||||
% (rule, parsed))
|
||||
|
||||
class AARegexPivotRoot(unittest.TestCase):
|
||||
'''Tests for RE_PROFILE_PIVOT_ROOT'''
|
||||
|
||||
def test_bare_pivot_root_01(self):
|
||||
'''test ' pivot_root,' '''
|
||||
|
||||
rule = 'pivot_root,'
|
||||
line = ' %s' % rule
|
||||
result = aa.RE_PROFILE_PIVOT_ROOT.search(line)
|
||||
self.assertTrue(result, 'Couldn\'t find pivot_root rule in "%s"' % line)
|
||||
parsed = result.groups()[2].strip()
|
||||
self.assertEqual(parsed, rule, 'Expected pivot_root rule "%s", got "%s"'
|
||||
% (rule, parsed))
|
||||
|
||||
def test_bare_pivot_root_02(self):
|
||||
'''test ' audit pivot_root,' '''
|
||||
|
||||
rule = 'pivot_root,'
|
||||
line = ' audit %s' % rule
|
||||
result = aa.RE_PROFILE_PIVOT_ROOT.search(line)
|
||||
self.assertTrue(result, 'Couldn\'t find pivot_root rule in "%s"' % line)
|
||||
self.assertTrue(result.groups()[0], 'Couldn\'t find audit modifier in "%s"' % line)
|
||||
parsed = result.groups()[2].strip()
|
||||
self.assertEqual(parsed, rule, 'Expected pivot_root rule "%s", got "%s"'
|
||||
% (rule, parsed))
|
||||
|
||||
def test_old_pivot_root_01(self):
|
||||
'''test ' pivot_root /old,' '''
|
||||
|
||||
rule = 'pivot_root /old,'
|
||||
line = ' %s' % rule
|
||||
result = aa.RE_PROFILE_PIVOT_ROOT.search(line)
|
||||
self.assertTrue(result, 'Couldn\'t find pivot_root rule in "%s"' % line)
|
||||
parsed = result.groups()[2].strip()
|
||||
self.assertEqual(parsed, rule, 'Expected pivot_root rule "%s", got "%s"'
|
||||
% (rule, parsed))
|
||||
|
||||
def test_new_pivot_root_01(self):
|
||||
'''test ' pivot_root /old /new,' '''
|
||||
|
||||
rule = 'pivot_root /old /new,'
|
||||
line = ' %s' % rule
|
||||
result = aa.RE_PROFILE_PIVOT_ROOT.search(line)
|
||||
self.assertTrue(result, 'Couldn\'t find pivot_root rule in "%s"' % line)
|
||||
parsed = result.groups()[2].strip()
|
||||
self.assertEqual(parsed, rule, 'Expected pivot_root rule "%s", got "%s"'
|
||||
% (rule, parsed))
|
||||
|
||||
def test_child_pivot_root_01(self):
|
||||
'''test ' pivot_root /old /new -> child,' '''
|
||||
|
||||
rule = 'pivot_root /old /new -> child,'
|
||||
line = ' %s' % rule
|
||||
result = aa.RE_PROFILE_PIVOT_ROOT.search(line)
|
||||
self.assertTrue(result, 'Couldn\'t find pivot_root rule in "%s"' % line)
|
||||
parsed = result.groups()[2].strip()
|
||||
self.assertEqual(parsed, rule, 'Expected pivot_root rule "%s", got "%s"'
|
||||
% (rule, parsed))
|
||||
|
||||
def test_child_pivot_root_02(self):
|
||||
'''test ' audit pivot_root /old /new -> child,' '''
|
||||
|
||||
rule = 'pivot_root /old /new -> child,'
|
||||
line = ' audit %s' % rule
|
||||
result = aa.RE_PROFILE_PIVOT_ROOT.search(line)
|
||||
self.assertTrue(result, 'Couldn\'t find pivot_root rule in "%s"' % line)
|
||||
self.assertTrue(result.groups()[0], 'Couldn\'t find audit modifier in "%s"' % line)
|
||||
parsed = result.groups()[2].strip()
|
||||
self.assertEqual(parsed, rule, 'Expected pivot_root rule "%s", got "%s"'
|
||||
% (rule, parsed))
|
||||
|
||||
if __name__ == '__main__':
|
||||
verbosity = 2
|
||||
|
||||
|
@ -457,6 +535,7 @@ if __name__ == '__main__':
|
|||
test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(AARegexFile))
|
||||
test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(AARegexSignal))
|
||||
test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(AARegexPtrace))
|
||||
test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(AARegexPivotRoot))
|
||||
result = unittest.TextTestRunner(verbosity=verbosity).run(test_suite)
|
||||
if not result.wasSuccessful():
|
||||
exit(1)
|
||||
|
|
Loading…
Add table
Reference in a new issue