From d90afe731360e6014a349d16c89581123eb1fc2f Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Fri, 5 Oct 2018 13:43:51 +0200 Subject: [PATCH] 2.10: Add basic support for abi rules to the tools Add basic "understand and keep" support for abi rules, where "understand" means to not error out when seeing an abi rule, and "keep" simply means to keep the original abi rule when serializing a profile. On the long term, abi rules should be parsed (similar to include rules), but for now, this patch is the smallest possible changeset and easy to backport. Note that the only added test is via cleanprof_test.* which is used by minitools_test.py - and does _not_ run if you do a 'make check'. Oh, and of course the simple_tests/abi/ files also get parsed by test-parser-simple-tests.py. BTW: Even serialize_profile_from_old_profile() can handle abi rules ;-) This is a backport of 072d3e04514b70bb3b29d4bfe400caa44dd574a2 / !202 to 2.10 (with some adjustments because that commit didn't appy cleanly) --- utils/apparmor/aa.py | 32 +++++++++++++++++++++++++++++--- utils/apparmor/regex.py | 1 + utils/test/cleanprof_test.in | 2 ++ utils/test/cleanprof_test.out | 4 ++++ 4 files changed, 36 insertions(+), 3 deletions(-) diff --git a/utils/apparmor/aa.py b/utils/apparmor/aa.py index d0b942116..830b04d6c 100644 --- a/utils/apparmor/aa.py +++ b/utils/apparmor/aa.py @@ -41,7 +41,7 @@ from apparmor.aamode import (str_to_mode, mode_to_str, contains, split_mode, flatten_mode, owner_flatten_mode) from apparmor.regex import (RE_PROFILE_START, RE_PROFILE_END, RE_PROFILE_LINK, - RE_PROFILE_ALIAS, + RE_ABI, RE_PROFILE_ALIAS, RE_PROFILE_BOOLEAN, RE_PROFILE_VARIABLE, RE_PROFILE_CONDITIONAL, RE_PROFILE_CONDITIONAL_VARIABLE, RE_PROFILE_CONDITIONAL_BOOLEAN, RE_PROFILE_BARE_FILE_ENTRY, RE_PROFILE_PATH_ENTRY, @@ -2849,6 +2849,18 @@ def parse_profile_data(data, file, do_include): else: profile_data[profile][hat][allow]['path'][path]['audit'] = set() + elif RE_ABI.search(line): + if profile: + if not profile_data[profile][hat].get('abi'): + profile_data[profile][hat]['abi'] = [] + profile_data[profile][hat]['abi'].append(line) + else: + if not filelist.get(file): + filelist[file] = hasher() + if not filelist[file].get('abi'): + filelist[file]['abi'] = [] + filelist[file]['abi'].append(line) + elif re_match_include(line): # Include files include_name = re_match_include(line) @@ -3256,6 +3268,17 @@ def write_change_profile(prof_data, depth): data = prof_data['change_profile'].get_clean(depth) return data +def write_abi(ref, depth): + pre = ' ' * depth + data = [] + + if ref.get('abi'): + for line in ref.get('abi'): + data.append('%s%s' % (pre, line)) + data.append('') + + return data + def write_alias(prof_data, depth): return write_pair(prof_data, depth, '', 'alias', 'alias ', ' -> ', ',', quote_if_needed) @@ -3496,7 +3519,8 @@ def write_paths(prof_data, depth): return data def write_rules(prof_data, depth): - data = write_alias(prof_data, depth) + data = write_abi(prof_data, depth) + data += write_alias(prof_data, depth) data += write_list_vars(prof_data, depth) data += write_includes(prof_data, depth) data += write_rlimits(prof_data, depth) @@ -3586,6 +3610,7 @@ def serialize_profile(profile_data, name, options): prof_filename = get_profile_filename(name) if filelist.get(prof_filename, False): + data += write_abi(filelist[prof_filename], 0) data += write_alias(filelist[prof_filename], 0) data += write_list_vars(filelist[prof_filename], 0) data += write_includes(filelist[prof_filename], 0) @@ -3658,7 +3683,8 @@ def serialize_profile_from_old_profile(profile_data, name, options): with open_file_read(prof_filename) as f_in: profile = None hat = None - write_methods = {'alias': write_alias, + write_methods = {'abi': write_abi, + 'alias': write_alias, 'lvar': write_list_vars, 'include': write_includes, 'rlimit': write_rlimits, diff --git a/utils/apparmor/regex.py b/utils/apparmor/regex.py index 290b93a68..2a04110ac 100644 --- a/utils/apparmor/regex.py +++ b/utils/apparmor/regex.py @@ -113,6 +113,7 @@ def parse_profile_start_line(line, filename): return result +RE_ABI = re.compile('^\s*#?abi\s*(<(?P.*)>|"(?P.*)"|(?P[^<>"]*))' + RE_COMMA_EOL) RE_INCLUDE = re.compile('^\s*#?include\s*<(?P.*)>' + RE_EOL) diff --git a/utils/test/cleanprof_test.in b/utils/test/cleanprof_test.in index ffe321ecf..6389a121d 100644 --- a/utils/test/cleanprof_test.in +++ b/utils/test/cleanprof_test.in @@ -2,6 +2,7 @@ #include alias /foo -> /bar , + abi , /usr/bin/a/simple/cleanprof/test/profile { # Just for the heck of it, this comment wont see the day of light @@ -9,6 +10,7 @@ #Below rule comes from abstractions/base allow /usr/share/X11/locale/** r, allow /home/*/** r, + abi "abi/4.20" , unix (receive) type=dgram, diff --git a/utils/test/cleanprof_test.out b/utils/test/cleanprof_test.out index bbaeb64a6..cae36db80 100644 --- a/utils/test/cleanprof_test.out +++ b/utils/test/cleanprof_test.out @@ -1,3 +1,5 @@ +abi , + alias /foo -> /bar, #include @@ -6,6 +8,8 @@ alias /foo -> /bar, /usr/bin/a/simple/cleanprof/test/profile { + abi "abi/4.20" , + #include unix (receive) type=dgram,