2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-09-03 07:45:50 +00:00

Move re_match_include() to regex.py and improve it

The function is basically a wrapper around a regex, so regex.py is a
much better home.

While on it, rename the regex to RE_INCLUDE, change it to named matches,
use RE_EOL to handle comments and compile it outside the function, which
should result in a (small) performance improvement.

Also rewrite re_match_include(), let it check for empty include
filenames ("#include <>") and let it raise AppArmorException in that
case.

Finally, adjust code calling it to the new location, and add some tests
for re_match_include()


Acked-by: Kshitij Gupta <kgupta8592@gmail.com>
This commit is contained in:
Christian Boltz
2015-06-19 21:41:41 +02:00
parent 5e5f8f0001
commit 2754e2964b
5 changed files with 56 additions and 20 deletions

View File

@@ -17,9 +17,10 @@ import re
import os
import apparmor.aa
from apparmor.aa import available_buttons, combine_name, delete_duplicates, is_known_rule, match_includes, re_match_include
from apparmor.aa import available_buttons, combine_name, delete_duplicates, is_known_rule, match_includes
import apparmor.aamode
from apparmor.common import AppArmorException
from apparmor.regex import re_match_include
import apparmor.severity
import apparmor.cleanprofile as cleanprofile
import apparmor.ui as aaui
@@ -267,7 +268,7 @@ class Merge(object):
done = True
elif ans == 'CMD_ALLOW':
selection = options[selected]
inc = apparmor.aa.re_match_include(selection)
inc = re_match_include(selection)
self.user.filelist[self.user.filename]['include'][inc] = True
options.pop(selected)
aaui.UI_Info(_('Adding %s to the file.') % selection)
@@ -302,7 +303,7 @@ class Merge(object):
done = True
elif ans == 'CMD_ALLOW':
selection = options[selected]
inc = apparmor.aa.re_match_include(selection)
inc = re_match_include(selection)
deleted = apparmor.aa.delete_duplicates(aa[profile][hat], inc)
aa[profile][hat]['include'][inc] = True
options.pop(selected)
@@ -524,7 +525,7 @@ class Merge(object):
elif ans == 'CMD_ALLOW':
path = options[selected]
done = True
match = apparmor.aa.re_match_include(path)
match = re_match_include(path)
if match:
inc = match
deleted = apparmor.aa.delete_duplicates(aa[profile][hat], inc)
@@ -589,7 +590,7 @@ class Merge(object):
elif ans == 'CMD_NEW':
arg = options[selected]
if not apparmor.aa.re_match_include(arg):
if not re_match_include(arg):
ans = aaui.UI_GetString(_('Enter new path: '), arg)
# if ans:
# if not matchliteral(ans, path):
@@ -603,7 +604,7 @@ class Merge(object):
elif ans == 'CMD_GLOB':
newpath = options[selected].strip()
if not apparmor.aa.re_match_include(newpath):
if not re_match_include(newpath):
newpath = apparmor.aa.glob_path(newpath)
if newpath not in options:
@@ -614,7 +615,7 @@ class Merge(object):
elif ans == 'CMD_GLOBEXT':
newpath = options[selected].strip()
if not apparmor.aa.re_match_include(newpath):
if not re_match_include(newpath):
newpath = apparmor.aa.glob_path_withext(newpath)
if newpath not in options:

View File

@@ -49,7 +49,7 @@ from apparmor.regex import (RE_PROFILE_START, RE_PROFILE_END, RE_PROFILE_LINK,
RE_PROFILE_HAT_DEF, RE_PROFILE_DBUS, RE_PROFILE_MOUNT,
RE_PROFILE_SIGNAL, RE_PROFILE_PTRACE, RE_PROFILE_PIVOT_ROOT,
RE_PROFILE_UNIX, RE_RULE_HAS_COMMA, RE_HAS_COMMENT_SPLIT,
strip_quotes, parse_profile_start_line )
strip_quotes, parse_profile_start_line, re_match_include )
import apparmor.rules as aarules
@@ -2112,15 +2112,6 @@ def match_includes(profile, rule_type, rule_obj):
return newincludes
def re_match_include(path):
"""Matches the path for include and returns the include path"""
regex_include = re.compile('^\s*#?include\s*<(.*)>\s*(#.*)?$')
match = regex_include.search(path)
if match:
return match.groups()[0]
else:
return None
def valid_include(profile, incname):
if profile and profile['include'].get(incname, False):
return False

View File

@@ -12,6 +12,7 @@
#
# ----------------------------------------------------------------------
import apparmor.aa as apparmor
from apparmor.regex import re_match_include
class Prof(object):
def __init__(self, filename):
@@ -90,7 +91,7 @@ def delete_path_duplicates(profile, profile_other, allow, same_profile=True):
if not same_profile:
deleted.append(entry)
continue
if apparmor.re_match_include(rule) or apparmor.re_match_include(entry):
if re_match_include(rule) or re_match_include(entry):
continue
# Check if the rule implies entry
if apparmor.matchliteral(rule, entry):

View File

@@ -112,6 +112,21 @@ def parse_profile_start_line(line, filename):
return result
RE_INCLUDE = re.compile('^\s*#?include\s*<(?P<magicpath>.*)>' + RE_EOL)
def re_match_include(line):
"""Matches the path for include and returns the include path"""
matches = RE_INCLUDE.search(line)
if not matches:
return None
if not matches.group('magicpath').strip():
raise AppArmorException(_('Syntax error: #include rule with empty filename'))
return matches.group('magicpath')
def strip_quotes(data):
if data[0] + data[-1] == '""':
return data[1:-1]

View File

@@ -12,9 +12,9 @@
import apparmor.aa as aa
import unittest
from common_test import AATest, setup_all_loops
from apparmor.common import AppArmorBug
from apparmor.common import AppArmorBug, AppArmorException
from apparmor.regex import strip_quotes, parse_profile_start_line, RE_PROFILE_START, RE_PROFILE_CAP
from apparmor.regex import strip_quotes, parse_profile_start_line, re_match_include, RE_PROFILE_START, RE_PROFILE_CAP
class AARegexTest(AATest):
@@ -465,6 +465,34 @@ class TestInvalid_parse_profile_start_line(AATest):
with self.assertRaises(AppArmorBug):
parse_profile_start_line(line, 'somefile')
class Test_re_match_include(AATest):
tests = [
('#include <abstractions/base>', 'abstractions/base' ),
('#include <abstractions/base> # comment', 'abstractions/base' ),
('#include<abstractions/base>#comment', 'abstractions/base' ),
(' #include <abstractions/base> ', 'abstractions/base' ),
('include <abstractions/base>', 'abstractions/base' ), # not supported by parser
# ('include foo', 'foo' ), # XXX not supported in tools yet
# ('include /foo/bar', '/foo/bar' ), # XXX not supported in tools yet
# ('include "foo"', 'foo' ), # XXX not supported in tools yet
# ('include "/foo/bar"', '/foo/bar' ), # XXX not supported in tools yet
(' some #include <abstractions/base>', None, ),
(' /etc/fstab r,', None, ),
]
def _run_test(self, params, expected):
self.assertEqual(re_match_include(params), expected)
class TestInvalid_re_match_include(AATest):
tests = [
('#include <>', AppArmorException ),
('#include < >', AppArmorException ),
]
def _run_test(self, params, expected):
with self.assertRaises(expected):
re_match_include(params)
class TestStripQuotes(AATest):
def test_strip_quotes_01(self):