diff --git a/utils/apparmor/aa.py b/utils/apparmor/aa.py index 5e1f0527b..1518a326e 100644 --- a/utils/apparmor/aa.py +++ b/utils/apparmor/aa.py @@ -40,7 +40,7 @@ import apparmor.ui as aaui from apparmor.aamode import str_to_mode, split_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_CHANGE_HAT, @@ -50,7 +50,7 @@ from apparmor.regex import (RE_PROFILE_START, RE_PROFILE_END, RE_PROFILE_LINK, strip_quotes, parse_profile_start_line, re_match_include ) from apparmor.profile_storage import (ProfileStorage, add_or_remove_flag, ruletypes, write_alias, - write_includes, write_list_vars ) + write_abi, write_includes, write_list_vars ) import apparmor.rules as aarules @@ -2311,6 +2311,16 @@ def parse_profile_data(data, file, do_include): # Conditional Boolean defined pass + elif RE_ABI.search(line): + if profile: + 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) @@ -2669,6 +2679,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) diff --git a/utils/apparmor/profile_storage.py b/utils/apparmor/profile_storage.py index 1d8c3f8dc..6ef4ca951 100644 --- a/utils/apparmor/profile_storage.py +++ b/utils/apparmor/profile_storage.py @@ -60,6 +60,7 @@ class ProfileStorage: data[rule] = ruletypes[rule]['ruleset']() data['alias'] = dict() + data['abi'] = [] data['include'] = dict() data['localinclude'] = dict() data['lvar'] = dict() @@ -121,6 +122,7 @@ class ProfileStorage: # "old" write functions for rule types not implemented as *Rule class yet write_functions = { + 'abi': write_abi, 'alias': write_alias, 'include': write_includes, 'links': write_links, @@ -131,6 +133,7 @@ class ProfileStorage: } write_order = [ + 'abi', 'alias', 'lvar', 'include', @@ -210,6 +213,17 @@ def write_list_vars(ref, 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): pre = ' ' * depth data = [] diff --git a/utils/apparmor/regex.py b/utils/apparmor/regex.py index 1cad58153..e3cdde365 100644 --- a/utils/apparmor/regex.py +++ b/utils/apparmor/regex.py @@ -132,6 +132,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.*)>|"(?P.*)"|(?P[^<>"]*))' + RE_EOL) diff --git a/utils/test/cleanprof_test.in b/utils/test/cleanprof_test.in index 9752a9412..ffab0e684 100644 --- a/utils/test/cleanprof_test.in +++ b/utils/test/cleanprof_test.in @@ -5,6 +5,8 @@ @{xy} = y x + abi , + @{asdf} = foo "" /usr/bin/a/simple/cleanprof/test/profile { @@ -18,6 +20,7 @@ change_profile, network inet stream, + abi "abi/4.20" , network stream, #Below rule comes from abstractions/base diff --git a/utils/test/cleanprof_test.out b/utils/test/cleanprof_test.out index cc93b6155..4f3eccb81 100644 --- a/utils/test/cleanprof_test.out +++ b/utils/test/cleanprof_test.out @@ -1,3 +1,5 @@ +abi , + alias /foo -> /bar, @{asdf} = "" foo @@ -9,6 +11,8 @@ alias /foo -> /bar, /usr/bin/a/simple/cleanprof/test/profile { + abi "abi/4.20" , + #include set rlimit nofile <= 256,