mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-31 22:35:35 +00:00
extend re_match_include_parse() to also match abi rules
... and add some tests
This commit is contained in:
@@ -145,16 +145,23 @@ RE_MAGIC_OR_QUOTED_PATH = '(<(?P<magicpath>.*)>|"(?P<quotedpath>.*)"|(?P<unquote
|
||||
RE_ABI = re.compile('^\s*#?abi\s*' + RE_MAGIC_OR_QUOTED_PATH + RE_COMMA_EOL)
|
||||
RE_INCLUDE = re.compile('^\s*#?include(?P<ifexists>\s+if\s+exists)?\s*' + RE_MAGIC_OR_QUOTED_PATH + RE_EOL)
|
||||
|
||||
def re_match_include_parse(line, rule_name):
|
||||
'''Matches the path for include, include if exists and abi rules
|
||||
|
||||
rule_name can be 'include' or 'abi'
|
||||
|
||||
def re_match_include_parse(line):
|
||||
'''Matches the path for include or include if exists.
|
||||
Returns a tuple with
|
||||
- if the "if exists" condition is given
|
||||
- the include path
|
||||
- the include/abi path
|
||||
- if the path is a magic path (enclosed in <...>)
|
||||
'''
|
||||
|
||||
matches = RE_INCLUDE.search(line)
|
||||
if rule_name == 'include':
|
||||
matches = RE_INCLUDE.search(line)
|
||||
elif rule_name == 'abi':
|
||||
matches = RE_ABI.search(line)
|
||||
else:
|
||||
raise AppArmorBug('re_match_include_parse() called with invalid rule name %s' % rule_name)
|
||||
|
||||
if not matches:
|
||||
return None, None, None
|
||||
@@ -167,31 +174,31 @@ def re_match_include_parse(line):
|
||||
elif matches.group('unquotedpath'):
|
||||
# LP: #1738879 - parser doesn't handle unquoted paths everywhere
|
||||
# path = matches.group('unquotedpath').strip()
|
||||
raise AppArmorException(_('Syntax error: #include must use quoted path or <...>'))
|
||||
raise AppArmorException(_('Syntax error: %s must use quoted path or <...>') % rule_name)
|
||||
elif matches.group('quotedpath'):
|
||||
path = matches.group('quotedpath')
|
||||
# LP: 1738880 - parser doesn't handle relative paths everywhere, and
|
||||
# neither do we (see aa.py)
|
||||
if len(path) > 0 and path[0] != '/':
|
||||
raise AppArmorException(_('Syntax error: #include must use quoted path or <...>'))
|
||||
raise AppArmorException(_('Syntax error: %s must use quoted path or <...>') % rule_name)
|
||||
|
||||
# if path is empty or the empty string
|
||||
if path is None or path == "":
|
||||
raise AppArmorException(_('Syntax error: #include rule with empty filename'))
|
||||
raise AppArmorException(_('Syntax error: %s rule with empty filename') % rule_name)
|
||||
|
||||
# LP: #1738877 - parser doesn't handle files with spaces in the name
|
||||
if re.search('\s', path):
|
||||
raise AppArmorException(_('Syntax error: #include rule filename cannot contain spaces'))
|
||||
raise AppArmorException(_('Syntax error: %s rule filename cannot contain spaces') % rule_name)
|
||||
|
||||
ifexists = False
|
||||
if matches.group('ifexists'):
|
||||
if rule_name == 'include' and matches.group('ifexists'):
|
||||
ifexists = True
|
||||
|
||||
return path, ifexists, ismagic
|
||||
|
||||
def re_match_include(line):
|
||||
''' return path of a 'include' rule '''
|
||||
(path, ifexists, ismagic) = re_match_include_parse(line)
|
||||
(path, ifexists, ismagic) = re_match_include_parse(line, 'include')
|
||||
|
||||
if not ifexists:
|
||||
return path
|
||||
|
@@ -68,7 +68,7 @@ class IncludeRule(BaseRule):
|
||||
comment = parse_comment(matches)
|
||||
|
||||
# TODO: move re_match_include_parse() from regex.py to this class after converting all code to use IncludeRule
|
||||
path, ifexists, ismagic = re_match_include_parse(raw_rule)
|
||||
path, ifexists, ismagic = re_match_include_parse(raw_rule, cls.rule_name)
|
||||
|
||||
return IncludeRule(path, ifexists, ismagic,
|
||||
audit=False, deny=False, allow_keyword=False, comment=comment)
|
||||
|
@@ -567,10 +567,47 @@ class Test_re_match_include_parse(AATest):
|
||||
(' /etc/fstab r,', (None, None, None ) ),
|
||||
('/usr/include r,', (None, None, None ) ),
|
||||
('/include r,', (None, None, None ) ),
|
||||
('abi <abi/4.19>,', (None, None, None ) ), # abi rule
|
||||
]
|
||||
|
||||
def _run_test(self, params, expected):
|
||||
self.assertEqual(re_match_include_parse(params), expected)
|
||||
self.assertEqual(re_match_include_parse(params, 'include'), expected)
|
||||
|
||||
class Test_re_match_include_parse_abi(AATest):
|
||||
tests = [
|
||||
# path if exists magic path
|
||||
('abi <abi/4.19>,', ('abi/4.19', False, True ) ), # magic path
|
||||
('abi <abi/4.19>, # comment', ('abi/4.19', False, True ) ),
|
||||
(' abi <abi/4.19> , # comment', ('abi/4.19', False, True ) ),
|
||||
('abi "/abi/4.19" ,', ('/abi/4.19', False, False) ), # quoted path starting with /
|
||||
('abi "/abi/4.19", # comment', ('/abi/4.19', False, False) ),
|
||||
(' abi "/abi/4.19" , # comment ', ('/abi/4.19', False, False) ),
|
||||
# (' abi "abi/4.19" , # comment ', ('abi/4.19', False, False) ), # quoted path, no leading /
|
||||
# ('abi abi/4.19,', ('abi/4.19', False, False) ), # without quotes
|
||||
('some abi <abi/4.19>,', (None, None, None ) ), # non-matching
|
||||
(' /etc/fstab r,', (None, None, None ) ),
|
||||
('/usr/abi r,', (None, None, None ) ),
|
||||
('/abi r,', (None, None, None ) ),
|
||||
('#include <abstractions/base>', (None, None, None ) ), # include rule path
|
||||
]
|
||||
|
||||
def _run_test(self, params, expected):
|
||||
self.assertEqual(re_match_include_parse(params, 'abi'), expected)
|
||||
|
||||
class Test_re_match_include_parse_empty_filename(AATest):
|
||||
tests = [
|
||||
(('include <>', 'include'), AppArmorException),
|
||||
(('include ""', 'include'), AppArmorException),
|
||||
(('include ', 'include'), AppArmorException),
|
||||
(('abi <>,', 'abi'), AppArmorException),
|
||||
(('abi "",', 'abi'), AppArmorException),
|
||||
(('abi ,', 'abi'), AppArmorException),
|
||||
]
|
||||
|
||||
def _run_test(self, params, expected):
|
||||
with self.assertRaises(expected):
|
||||
rule, rule_name = params
|
||||
re_match_include_parse(rule, rule_name)
|
||||
|
||||
class TestStripParenthesis(AATest):
|
||||
tests = [
|
||||
|
Reference in New Issue
Block a user