Add in_preamble parameter to profile loading/parsing functions

in_preamble keeps track of the current parsing position.

It's True while parsing the preamble of a profile file, and when loading
an include file that is included in the preamble (typically tunables/*).

While inside a profile or parsing abstractions/*, it is False.

This commit only hands the information around and keeps in_preamble
updated, but it doesn't really get used yet.

Also adjust the tests to hand over the additional parameter to
parse_profile_data().
This commit is contained in:
Christian Boltz 2021-02-22 22:22:25 +01:00
parent d442620102
commit accc380326
Failed to generate hash of commit
3 changed files with 22 additions and 19 deletions

View file

@ -1727,7 +1727,7 @@ def read_profile(file, active_profile):
debug_logger.debug("read_profile: can't read %s - skipping" % file)
return None
profile_data = parse_profile_data(data, file, 0)
profile_data = parse_profile_data(data, file, 0, True)
if profile_data and active_profile:
attach_profile_data(aa, profile_data)
@ -1825,7 +1825,7 @@ def parse_profile_start_to_storage(line, file, lineno, profile, hat):
return (profile, hat, prof_storage)
def parse_profile_data(data, file, do_include):
def parse_profile_data(data, file, do_include, in_preamble):
profile_data = hasher()
profile = None
hat = None
@ -1863,6 +1863,8 @@ def parse_profile_data(data, file, do_include):
else:
in_contained_hat = False
in_preamble = False
(profile, hat, prof_storage) = parse_profile_start_to_storage(line, file, lineno, profile, hat)
if profile_data[profile].get(hat, False):
@ -1888,6 +1890,7 @@ def parse_profile_data(data, file, do_include):
else:
parsed_profiles.append(profile)
profile = None
in_preamble = True
initial_comment = ''
@ -1938,7 +1941,7 @@ def parse_profile_data(data, file, do_include):
active_profiles.add_inc_ie(file, rule_obj)
for incname in rule_obj.get_full_paths(profile_dir):
load_include(incname)
load_include(incname, in_preamble)
elif RE_PROFILE_MOUNT.search(line):
matches = RE_PROFILE_MOUNT.search(line).groups()
@ -2429,7 +2432,7 @@ def include_dir_filelist(include_name):
return files
def load_include(incname):
def load_include(incname, in_preamble=False):
load_includeslist = [incname]
while load_includeslist:
incfile = load_includeslist.pop(0)
@ -2440,7 +2443,7 @@ def load_include(incname):
pass # already read, do nothing
elif os.path.isfile(incfile):
data = get_include_data(incfile)
incdata = parse_profile_data(data, incfile, True)
incdata = parse_profile_data(data, incfile, True, in_preamble)
attach_profile_data(include, incdata)
#If the include is a directory means include all subfiles
elif os.path.isdir(incfile):
@ -2464,10 +2467,10 @@ def get_subdirectories(current_dir):
return os.walk(current_dir).__next__()[1]
def loadincludes():
loadincludes_dir('tunables')
loadincludes_dir('abstractions')
loadincludes_dir('tunables', True)
loadincludes_dir('abstractions', False)
def loadincludes_dir(subdir):
def loadincludes_dir(subdir, in_preamble):
idir = os.path.join(profile_dir, subdir)
if os.path.isdir(idir): # if directory doesn't exist, silently skip loading it
@ -2477,7 +2480,7 @@ def loadincludes_dir(subdir):
continue
else:
fi = os.path.join(dirpath, fi)
load_include(fi)
load_include(fi, in_preamble)
def glob_common(path):
globs = []

View file

@ -521,7 +521,7 @@ class AaTest_parse_profile_start_errors(AATest):
class AaTest_parse_profile_data(AATest):
def test_parse_empty_profile_01(self):
prof = parse_profile_data('/foo {\n}\n'.split(), 'somefile', False)
prof = parse_profile_data('/foo {\n}\n'.split(), 'somefile', False, False)
self.assertEqual(list(prof.keys()), ['/foo'])
self.assertEqual(list(prof['/foo'].keys()), ['/foo'])
@ -532,20 +532,20 @@ class AaTest_parse_profile_data(AATest):
def test_parse_duplicate_profile(self):
with self.assertRaises(AppArmorException):
# file contains two profiles with the same name
parse_profile_data('profile /foo {\n}\nprofile /foo {\n}\n'.split(), 'somefile', False)
parse_profile_data('profile /foo {\n}\nprofile /foo {\n}\n'.split(), 'somefile', False, False)
def test_parse_duplicate_child_profile(self):
with self.assertRaises(AppArmorException):
# file contains two child profiles with the same name
parse_profile_data('profile /foo {\nprofile /bar {\n}\nprofile /bar {\n}\n}\n'.split(), 'somefile', False)
parse_profile_data('profile /foo {\nprofile /bar {\n}\nprofile /bar {\n}\n}\n'.split(), 'somefile', False, False)
def test_parse_duplicate_hat(self):
with self.assertRaises(AppArmorException):
# file contains two hats with the same name
parse_profile_data('profile /foo {\n^baz {\n}\n^baz {\n}\n}\n'.split(), 'somefile', False)
parse_profile_data('profile /foo {\n^baz {\n}\n^baz {\n}\n}\n'.split(), 'somefile', False, False)
def test_parse_xattrs_01(self):
prof = parse_profile_data('/foo xattrs=(user.bar=bar) {\n}\n'.split(), 'somefile', False)
prof = parse_profile_data('/foo xattrs=(user.bar=bar) {\n}\n'.split(), 'somefile', False, False)
self.assertEqual(list(prof.keys()), ['/foo'])
self.assertEqual(list(prof['/foo'].keys()), ['/foo'])
@ -555,7 +555,7 @@ class AaTest_parse_profile_data(AATest):
self.assertEqual(prof['/foo']['/foo']['xattrs'], 'user.bar=bar')
def test_parse_xattrs_02(self):
prof = parse_profile_data('/foo xattrs=(user.bar=bar user.foo=*) {\n}\n'.split(), 'somefile', False)
prof = parse_profile_data('/foo xattrs=(user.bar=bar user.foo=*) {\n}\n'.split(), 'somefile', False, False)
self.assertEqual(list(prof.keys()), ['/foo'])
self.assertEqual(list(prof['/foo'].keys()), ['/foo'])
@ -566,7 +566,7 @@ class AaTest_parse_profile_data(AATest):
def test_parse_xattrs_03(self):
d = '/foo xattrs=(user.bar=bar) flags=(complain) {\n}\n'
prof = parse_profile_data(d.split(), 'somefile', False)
prof = parse_profile_data(d.split(), 'somefile', False, False)
self.assertEqual(list(prof.keys()), ['/foo'])
self.assertEqual(list(prof['/foo'].keys()), ['/foo'])
@ -579,7 +579,7 @@ class AaTest_parse_profile_data(AATest):
with self.assertRaises(AppArmorException):
# flags before xattrs
d = '/foo flags=(complain) xattrs=(user.bar=bar) {\n}\n'
parse_profile_data(d.split(), 'somefile', False)
parse_profile_data(d.split(), 'somefile', False, False)
class AaTest_write_header(AATest):
tests = [

View file

@ -430,12 +430,12 @@ class TestParseParserTests(AATest):
apparmor.active_profiles.init_file(params['file'])
if expected:
apparmor.parse_profile_data(data, params['file'], 0)
apparmor.parse_profile_data(data, params['file'], 0, True)
apparmor.active_profiles.get_all_merged_variables(params['file'], apparmor.include_list_recursive(apparmor.active_profiles.files[params['file']]))
else:
with self.assertRaises(AppArmorException):
apparmor.parse_profile_data(data, params['file'], 0)
apparmor.parse_profile_data(data, params['file'], 0, True)
apparmor.active_profiles.get_all_merged_variables(params['file'], apparmor.include_list_recursive(apparmor.active_profiles.files[params['file']]))
def parse_test_profiles(file_with_path):