From d15bdabaef1bc18bdd58766b106e111db7c6cb51 Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Wed, 22 Aug 2018 22:24:43 +0200 Subject: [PATCH 01/46] Remove TODO notes from no-longer-failing tests simple.pl reported TODO passed: 71448, 71459-71460, 71494, 71577 This commit removes the TODO note from the tests that now work as expected. --- parser/tst/simple_tests/vars/vars_profile_name_14.sd | 1 - parser/tst/simple_tests/vars/vars_profile_name_25.sd | 1 - parser/tst/simple_tests/vars/vars_profile_name_26.sd | 1 - parser/tst/simple_tests/xtrans/minimize-x-conflict.sd | 1 - parser/tst/simple_tests/xtrans/x-conflict.sd | 1 - 5 files changed, 5 deletions(-) diff --git a/parser/tst/simple_tests/vars/vars_profile_name_14.sd b/parser/tst/simple_tests/vars/vars_profile_name_14.sd index feffe8139..d2b94c9fc 100644 --- a/parser/tst/simple_tests/vars/vars_profile_name_14.sd +++ b/parser/tst/simple_tests/vars/vars_profile_name_14.sd @@ -1,6 +1,5 @@ #=DESCRIPTION reference variables in rules that also have alternations #=EXRESULT PASS -#=TODO # This test needs check on @{FOO} attachment having leading / post var expansion @{FOO}=/bar /baz diff --git a/parser/tst/simple_tests/vars/vars_profile_name_25.sd b/parser/tst/simple_tests/vars/vars_profile_name_25.sd index 56ce8bae7..bba4ceecb 100644 --- a/parser/tst/simple_tests/vars/vars_profile_name_25.sd +++ b/parser/tst/simple_tests/vars/vars_profile_name_25.sd @@ -1,6 +1,5 @@ #=DESCRIPTION reference variables is null #=EXRESULT FAIL -#=TODO #needs post var expansion check that variable contained a value @{FOO}= diff --git a/parser/tst/simple_tests/vars/vars_profile_name_26.sd b/parser/tst/simple_tests/vars/vars_profile_name_26.sd index e81acb944..850de8653 100644 --- a/parser/tst/simple_tests/vars/vars_profile_name_26.sd +++ b/parser/tst/simple_tests/vars/vars_profile_name_26.sd @@ -1,6 +1,5 @@ #=DESCRIPTION reference variables is null #=EXRESULT FAIL -#=TODO #needs post var expansion check that variable contained a value @{FOO}= diff --git a/parser/tst/simple_tests/xtrans/minimize-x-conflict.sd b/parser/tst/simple_tests/xtrans/minimize-x-conflict.sd index 429795602..33524fd0c 100644 --- a/parser/tst/simple_tests/xtrans/minimize-x-conflict.sd +++ b/parser/tst/simple_tests/xtrans/minimize-x-conflict.sd @@ -1,7 +1,6 @@ # #=DESCRIPTION test for conflict resolution in minimization phase of dfa gen #=EXRESULT PASS -#=TODO # /usr/bin/foo { diff --git a/parser/tst/simple_tests/xtrans/x-conflict.sd b/parser/tst/simple_tests/xtrans/x-conflict.sd index 92215f9fe..7b19b8747 100644 --- a/parser/tst/simple_tests/xtrans/x-conflict.sd +++ b/parser/tst/simple_tests/xtrans/x-conflict.sd @@ -1,7 +1,6 @@ # #=DESCRIPTION test for conflict resolution in minimization phase of dfa gen #=EXRESULT FAIL -#=TODO # /usr/bin/foo { /b* px, From bc783372b879b8f090044b3793a9ca49cc30cd87 Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Mon, 22 Oct 2018 22:35:10 +0200 Subject: [PATCH 02/46] Add is_attachment parameter to write_profile The minitools call write_profile(), write_profile_feedback_ui() and serialize_profile() with the _attachment_ as parameter. However, aa-logprof etc. call them with the _profile name_ as parameter. This patch adds an is_attachment parameter to write_profile() and write_profile_feedback_ui(). It also passes it through to serialize_profile() via the options parameter. If is_attachment is True, the parameter will be handled as attachment, otherwise it is expected to be a profile name. tools.py gets changed to set is_attachment to True when calling the functions listed above to make clear that the parameter is an attachment. Note: This patch only adds the is_attachment parameter/option, but doesn't change any behaviour. That will happen in the next patch. --- utils/apparmor/aa.py | 8 ++++---- utils/apparmor/tools.py | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/utils/apparmor/aa.py b/utils/apparmor/aa.py index 1518a326e..579a8c1d3 100644 --- a/utils/apparmor/aa.py +++ b/utils/apparmor/aa.py @@ -2703,11 +2703,11 @@ def serialize_profile(profile_data, name, options): return string + '\n' -def write_profile_ui_feedback(profile): +def write_profile_ui_feedback(profile, is_attachment=False): aaui.UI_Info(_('Writing updated profile for %s.') % profile) - write_profile(profile) + write_profile(profile, is_attachment) -def write_profile(profile): +def write_profile(profile, is_attachment=False): prof_filename = None if aa[profile][profile].get('filename', False): prof_filename = aa[profile][profile]['filename'] @@ -2722,7 +2722,7 @@ def write_profile(profile): #os.chmod(newprof.name, permission_600) pass - serialize_options = {'METADATA': True} + serialize_options = {'METADATA': True, 'is_attachment': is_attachment} profile_string = serialize_profile(aa[profile], profile, serialize_options) newprof.write(profile_string) diff --git a/utils/apparmor/tools.py b/utils/apparmor/tools.py index c812158dc..39d79fb3b 100644 --- a/utils/apparmor/tools.py +++ b/utils/apparmor/tools.py @@ -220,14 +220,14 @@ class aa_tools: while ans != 'CMD_SAVE_CHANGES': ans, arg = q.promptUser() if ans == 'CMD_SAVE_CHANGES': - apparmor.write_profile_ui_feedback(program) + apparmor.write_profile_ui_feedback(program, True) self.reload_profile(filename) elif ans == 'CMD_VIEW_CHANGES': #oldprofile = apparmor.serialize_profile(apparmor.original_aa[program], program, {}) - newprofile = apparmor.serialize_profile(apparmor.aa[program], program, {}) + newprofile = apparmor.serialize_profile(apparmor.aa[program], program, {'is_attachment': True}) aaui.UI_Changes(filename, newprofile, comments=True) else: - apparmor.write_profile_ui_feedback(program) + apparmor.write_profile_ui_feedback(program, True) self.reload_profile(filename) else: raise apparmor.AppArmorException(_('The profile for %s does not exists. Nothing to clean.') % program) From ec741424f81e152598035324b6fde604427e0a63 Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Mon, 22 Oct 2018 22:51:34 +0200 Subject: [PATCH 03/46] split get_profile_filename into .._from_profile_name and .._from_attachment Split get_profile_filename() into - get_profile_filename_from_profile_name() (parameter: a profile name) - get_profile_filename_from_attachment() (parameter: an attachment) Currently both functions call get_profile_filename_orig() (formerly get_profile_filename()) so the behaviour doesn't change yet. The most important part of this commit is changing all get_profile_filename() calls to use one of the new functions to make clear if they specify a profile or an attachment/executable as parameter. As promised, the is_attachment parameter starts to get used in this patch ;-) Note: The get_new parameter (which I'll explain in the patch actually using it) is set to True in all calls to the new functions. The long term plan is to get rid of it in most cases (hence defaulting to False), but that will need more testing. --- utils/aa-genprof | 2 +- utils/aa-mergeprof | 2 +- utils/apparmor/aa.py | 44 +++++++++++++++++++++++++++-------------- utils/apparmor/tools.py | 9 +++++---- 4 files changed, 36 insertions(+), 21 deletions(-) diff --git a/utils/aa-genprof b/utils/aa-genprof index 9e3279bc5..834c2d4c3 100755 --- a/utils/aa-genprof +++ b/utils/aa-genprof @@ -107,7 +107,7 @@ apparmor.check_qualifiers(program) apparmor.loadincludes() -profile_filename = apparmor.get_profile_filename(program) +profile_filename = apparmor.get_profile_filename_from_attachment(program, True) if os.path.exists(profile_filename): apparmor.helpers[program] = apparmor.get_profile_flags(profile_filename, program) else: diff --git a/utils/aa-mergeprof b/utils/aa-mergeprof index 8988e1956..f0bddf171 100755 --- a/utils/aa-mergeprof +++ b/utils/aa-mergeprof @@ -75,7 +75,7 @@ def find_files_from_profiles(profiles): apparmor.aa.read_profiles() for profile_name in profiles: - profile_to_filename[profile_name] = apparmor.aa.get_profile_filename(profile_name) + profile_to_filename[profile_name] = apparmor.aa.get_profile_filename_from_profile_name(profile_name, True) reset_aa() diff --git a/utils/apparmor/aa.py b/utils/apparmor/aa.py index 579a8c1d3..6d90840c7 100644 --- a/utils/apparmor/aa.py +++ b/utils/apparmor/aa.py @@ -217,7 +217,15 @@ def find_executable(bin_path): return full_bin return None -def get_profile_filename(profile): +def get_profile_filename_from_profile_name(profile, get_new=False): + """Returns the full profile name for the given profile name""" + return get_profile_filename_orig(profile) + +def get_profile_filename_from_attachment(profile, get_new=False): + """Returns the full profile name for the given attachment""" + return get_profile_filename_orig(profile) + +def get_profile_filename_orig(profile): """Returns the full profile name""" if existing_profiles.get(profile, False): return existing_profiles[profile] @@ -238,7 +246,7 @@ def name_to_prof_filename(prof_filename): else: bin_path = find_executable(prof_filename) if bin_path: - prof_filename = get_profile_filename(bin_path) + prof_filename = get_profile_filename_from_attachment(bin_path, True) if os.path.isfile(prof_filename): return (prof_filename, bin_path) @@ -464,7 +472,7 @@ def create_new_profile(localfile, is_stub=False): def delete_profile(local_prof): """Deletes the specified file from the disk and remove it from our list""" - profile_file = get_profile_filename(local_prof) + profile_file = get_profile_filename_from_profile_name(local_prof, True) if os.path.isfile(profile_file): os.remove(profile_file) if aa.get(local_prof, False): @@ -560,7 +568,7 @@ def activate_repo_profiles(url, profiles, complain): attach_profile_data(aa, profile_data) write_profile(pname) if complain: - fname = get_profile_filename(pname) + fname = get_profile_filename_from_profile_name(pname, True) change_profile_flags(profile_dir + fname, None, 'complain', True) aaui.UI_Info(_('Setting %s to complain mode.') % pname) except Exception as e: @@ -592,7 +600,7 @@ def autodep(bin_name, pname=''): # Create a new profile if no existing profile if not profile_data: profile_data = create_new_profile(pname) - file = get_profile_filename(pname) + file = get_profile_filename_from_profile_name(pname, True) profile_data[pname][pname]['filename'] = None # will be stored in /etc/apparmor.d when saving, so it shouldn't carry the extra_profile_dir filename attach_profile_data(aa, profile_data) attach_profile_data(original_aa, profile_data) @@ -695,7 +703,7 @@ def profile_exists(program): if existing_profiles.get(program, False): return True # Check the disk for profile - prof_path = get_profile_filename(program) + prof_path = get_profile_filename_from_attachment(program, True) #print(prof_path) if os.path.isfile(prof_path): # Add to cache of profile @@ -1088,9 +1096,9 @@ def handle_children(profile, hat, root): options += 'd' # Define the default option default = None - if 'p' in options and os.path.exists(get_profile_filename(exec_target)): + if 'p' in options and os.path.exists(get_profile_filename_from_attachment(exec_target, True)): default = 'CMD_px' - sys.stdout.write(_('Target profile exists: %s\n') % get_profile_filename(exec_target)) + sys.stdout.write(_('Target profile exists: %s\n') % get_profile_filename_from_attachment(exec_target, True)) elif 'i' in options: default = 'CMD_ix' elif 'c' in options: @@ -1104,7 +1112,7 @@ def handle_children(profile, hat, root): parent_uses_ld_xxx = check_for_LD_XXX(profile) sev_db.unload_variables() - sev_db.load_variables(get_profile_filename(profile)) + sev_db.load_variables(get_profile_filename_from_profile_name(profile, True)) severity = sev_db.rank_path(exec_target, 'x') # Prompt portion starts @@ -1228,7 +1236,7 @@ def handle_children(profile, hat, root): profile_changes[pid] = '%s' % profile # Check profile exists for px - if not os.path.exists(get_profile_filename(exec_target)): + if not os.path.exists(get_profile_filename_from_attachment(exec_target, True)): ynans = 'y' if 'i' in exec_mode: ynans = aaui.UI_YesNo(_('A profile for %s does not exist.\nDo you want to create one?') % exec_target, 'n') @@ -1362,7 +1370,7 @@ def ask_the_questions(log_dict): UI_SelectUpdatedRepoProfile(profile, p) sev_db.unload_variables() - sev_db.load_variables(get_profile_filename(profile)) + sev_db.load_variables(get_profile_filename_from_profile_name(profile, True)) # Sorted list of hats with the profile name coming first hats = list(filter(lambda key: key != profile, sorted(log_dict[aamode][profile].keys()))) @@ -1867,7 +1875,7 @@ def save_profiles(): if aa[which][which].get('filename', False): oldprofile = aa[which][which]['filename'] else: - oldprofile = get_profile_filename(which) + oldprofile = get_profile_filename_from_attachment(which, True) serialize_options = {'METADATA': True} newprofile = serialize_profile(aa[which], which, serialize_options) @@ -2677,7 +2685,11 @@ def serialize_profile(profile_data, name, options): # comment.replace('\\n', '\n') # string += comment + '\n' - prof_filename = get_profile_filename(name) + if options.get('is_attachment'): + prof_filename = get_profile_filename_from_attachment(name, True) + else: + prof_filename = get_profile_filename_from_profile_name(name, True) + if filelist.get(prof_filename, False): data += write_abi(filelist[prof_filename], 0) data += write_alias(filelist[prof_filename], 0) @@ -2711,8 +2723,10 @@ def write_profile(profile, is_attachment=False): prof_filename = None if aa[profile][profile].get('filename', False): prof_filename = aa[profile][profile]['filename'] + elif is_attachment: + prof_filename = get_profile_filename_from_attachment(profile, True) else: - prof_filename = get_profile_filename(profile) + prof_filename = get_profile_filename_from_profile_name(profile, True) newprof = tempfile.NamedTemporaryFile('w', suffix='~', delete=False, dir=profile_dir) if os.path.exists(prof_filename): @@ -2844,7 +2858,7 @@ def reload_base(bin_path): if not check_for_apparmor(): return None - prof_filename = get_profile_filename(bin_path) + prof_filename = get_profile_filename_from_profile_name(bin_path, True) # XXX use reload_profile() from tools.py instead (and don't hide output in /dev/null) subprocess.call("cat '%s' | %s -I%s -r >/dev/null 2>&1" % (prof_filename, parser, profile_dir), shell=True) diff --git a/utils/apparmor/tools.py b/utils/apparmor/tools.py index 39d79fb3b..f1f051956 100644 --- a/utils/apparmor/tools.py +++ b/utils/apparmor/tools.py @@ -1,5 +1,6 @@ # ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta +# Copyright (C) 2015-2018 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -66,12 +67,12 @@ class aa_tools: profile = fq_path else: program = fq_path - profile = apparmor.get_profile_filename(fq_path) + profile = apparmor.get_profile_filename_from_attachment(fq_path, True) else: which = apparmor.which(p) if which is not None: program = apparmor.get_full_path(which) - profile = apparmor.get_profile_filename(program) + profile = apparmor.get_profile_filename_from_attachment(program, True) elif os.path.exists(os.path.join(apparmor.profile_dir, p)): program = None profile = apparmor.get_full_path(os.path.join(apparmor.profile_dir, p)).strip() @@ -190,7 +191,7 @@ class aa_tools: apparmor.check_qualifiers(program) - if os.path.exists(apparmor.get_profile_filename(program)) and not self.force: + if os.path.exists(apparmor.get_profile_filename_from_attachment(program, True)) and not self.force: aaui.UI_Info(_('Profile for %s already exists - skipping.') % program) else: apparmor.autodep(program) @@ -198,7 +199,7 @@ class aa_tools: apparmor.reload(program) def clean_profile(self, program): - filename = apparmor.get_profile_filename(program) + filename = apparmor.get_profile_filename_from_attachment(program, True) import apparmor.cleanprofile as cleanprofile prof = cleanprofile.Prof(filename) cleanprof = cleanprofile.CleanProf(True, prof, prof) From a6b8d14908dafb3667f05984d39b7e3889503dcc Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Mon, 22 Oct 2018 23:42:17 +0200 Subject: [PATCH 04/46] split off get_new_profile_filename() ... and call it from get_profile_filename_* if get_new is True (= always with the current code) --- utils/apparmor/aa.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/utils/apparmor/aa.py b/utils/apparmor/aa.py index 6d90840c7..ff35e96e2 100644 --- a/utils/apparmor/aa.py +++ b/utils/apparmor/aa.py @@ -219,17 +219,32 @@ def find_executable(bin_path): def get_profile_filename_from_profile_name(profile, get_new=False): """Returns the full profile name for the given profile name""" - return get_profile_filename_orig(profile) + + filename = get_profile_filename_orig(profile) + if filename: + return filename + + if get_new: + return get_new_profile_filename(profile) def get_profile_filename_from_attachment(profile, get_new=False): """Returns the full profile name for the given attachment""" - return get_profile_filename_orig(profile) + + filename = get_profile_filename_orig(profile) + if filename: + return filename + + if get_new: + return get_new_profile_filename(profile) def get_profile_filename_orig(profile): """Returns the full profile name""" if existing_profiles.get(profile, False): return existing_profiles[profile] - elif profile.startswith('/'): + +def get_new_profile_filename(profile): + '''Compose filename for a new profile''' + if profile.startswith('/'): # Remove leading / profile = profile[1:] else: From 8809218ac8cfb89a6c8b2109511960c8aab944aa Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Mon, 22 Oct 2018 23:11:22 +0200 Subject: [PATCH 05/46] Move updating existing_profiles out of parse_profile_data() parse_profile_data() returns the parsed profiles, but writes to existing_profiles directly. read_profiles() calls parse_profile_data() and already handles adding the parsed profiles to aa, original_aa or extras, which means updating existing_profiles there is a much better place. This commit also includes a hidden change: Previously, when parsing include files, they were also added to existing_profiles. This is superfluous, only real profiles need to be stored there. --- utils/apparmor/aa.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/utils/apparmor/aa.py b/utils/apparmor/aa.py index ff35e96e2..dd51205fc 100644 --- a/utils/apparmor/aa.py +++ b/utils/apparmor/aa.py @@ -2105,9 +2105,21 @@ def read_profile(file, active_profile): if profile_data and active_profile: attach_profile_data(aa, profile_data) attach_profile_data(original_aa, profile_data) + + for profile in profile_data: # TODO: also honor hats + name = profile_data[profile][profile]['name'] + filename = profile_data[profile][profile]['filename'] + + existing_profiles[name] = filename + elif profile_data: attach_profile_data(extras, profile_data) + for profile in profile_data: # TODO: also honor hats + name = profile_data[profile][profile]['name'] + filename = profile_data[profile][profile]['filename'] + + existing_profiles[name] = filename def attach_profile_data(profiles, profile_data): # Make deep copy of data to avoid changes to @@ -2199,9 +2211,6 @@ def parse_profile_data(data, file, do_include): if pps_set_hat_external: profile_data[profile][hat]['external'] = True - # Profile stored - existing_profiles[profile] = file - # save profile name and filename profile_data[profile][hat]['name'] = profile profile_data[profile][hat]['filename'] = file From 789c4658e22ef42e76fd55c14e31fcaa93ef574b Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Sun, 21 Oct 2018 20:39:51 +0200 Subject: [PATCH 06/46] add ProfileList class to store list of profiles ProfileList is meant to store the list of profiles (both name and attachment) and in which files they live. Also add unittests to make sure everything works as expected. --- utils/apparmor/profile_list.py | 73 ++++++++++++++++++++ utils/test/test-profile-list.py | 114 ++++++++++++++++++++++++++++++++ 2 files changed, 187 insertions(+) create mode 100644 utils/apparmor/profile_list.py create mode 100644 utils/test/test-profile-list.py diff --git a/utils/apparmor/profile_list.py b/utils/apparmor/profile_list.py new file mode 100644 index 000000000..f500f3a04 --- /dev/null +++ b/utils/apparmor/profile_list.py @@ -0,0 +1,73 @@ +# ---------------------------------------------------------------------- +# Copyright (C) 2018 Christian Boltz +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of version 2 of the GNU General Public +# License as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# ---------------------------------------------------------------------- + +from apparmor.aare import AARE +from apparmor.common import AppArmorBug, AppArmorException + +# setup module translations +from apparmor.translations import init_translation +_ = init_translation() + + +class ProfileList: + ''' Stores the list of profiles (both name and attachment) and in which files they live ''' + + def __init__(self): + self.profile_names = {} # profile name -> filename + self.attachments = {} # attachment -> filename + self.attachments_AARE = {} # AARE(attachment) -> filename + + def add(self, filename, profile_name, attachment): + ''' Add the given profile and attachment to the list ''' + + if not filename: + raise AppArmorBug('Empty filename given to ProfileList') + + if not profile_name and not attachment: + raise AppArmorBug('Neither profile name or attachment given') + + if profile_name in self.profile_names: + raise AppArmorException(_('Profile %(profile_name)s exists in %(filename)s and %(filename2)s' % {'profile_name': profile_name, 'filename': filename, 'filename2': self.profile_names[profile_name]})) + + if attachment in self.attachments: + raise AppArmorException(_('Profile for %(profile_name)s exists in %(filename)s and %(filename2)s' % {'profile_name': attachment, 'filename': filename, 'filename2': self.attachments[attachment]})) + + if profile_name: + self.profile_names[profile_name] = filename + + if attachment: + self.attachments[attachment] = filename + self.attachments_AARE[attachment] = AARE(attachment, True) + + def filename_from_profile_name(self, name): + ''' Return profile filename for the given profile name, or None ''' + + return self.profile_names.get(name, None) + + def filename_from_attachment(self, attachment): + ''' Return profile filename for the given attachment/executable path, or None ''' + + if not attachment.startswith( ('/', '@', '{') ): + raise AppArmorBug('Called filename_from_attachment with non-path attachment: %s' % attachment) + + # plain path + if self.attachments.get(attachment): + return self.attachments[attachment] + + # try AARE matches to cover profile names with alternations and wildcards + for path in self.attachments.keys(): + if self.attachments_AARE[path].match(attachment): + return self.attachments[path] # XXX this returns the first match, not necessarily the best one + + return None # nothing found diff --git a/utils/test/test-profile-list.py b/utils/test/test-profile-list.py new file mode 100644 index 000000000..5976ad5aa --- /dev/null +++ b/utils/test/test-profile-list.py @@ -0,0 +1,114 @@ +#! /usr/bin/python3 +# ------------------------------------------------------------------ +# +# Copyright (C) 2018 Christian Boltz +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of version 2 of the GNU General Public +# License published by the Free Software Foundation. +# +# ------------------------------------------------------------------ + +import unittest +from common_test import AATest, setup_all_loops + +from apparmor.common import AppArmorBug, AppArmorException +from apparmor.profile_list import ProfileList + +class TestAdd(AATest): + def AASetup(self): + self.pl = ProfileList() + + def testEmpty(self): + self.assertEqual(self.pl.profile_names, {}) + self.assertEqual(self.pl.attachments, {}) + + def testAdd_1(self): + self.pl.add('/etc/apparmor.d/bin.foo', 'foo', '/bin/foo') + self.assertEqual(self.pl.profile_names, {'foo': '/etc/apparmor.d/bin.foo'}) + self.assertEqual(self.pl.attachments, {'/bin/foo': '/etc/apparmor.d/bin.foo'}) + + def testAdd_2(self): + self.pl.add('/etc/apparmor.d/bin.foo', None, '/bin/foo') + self.assertEqual(self.pl.profile_names, {}) + self.assertEqual(self.pl.attachments, {'/bin/foo': '/etc/apparmor.d/bin.foo'}) + + def testAdd_3(self): + self.pl.add('/etc/apparmor.d/bin.foo', 'foo', None) + self.assertEqual(self.pl.profile_names, {'foo': '/etc/apparmor.d/bin.foo'}) + self.assertEqual(self.pl.attachments, {}) + + + def testAddError_1(self): + with self.assertRaises(AppArmorBug): + self.pl.add('', 'foo', '/bin/foo') # no filename + + def testAddError_2(self): + with self.assertRaises(AppArmorBug): + self.pl.add('/etc/apparmor.d/bin.foo', None, None) # neither attachment or profile name + + def testAddError_twice_1(self): + self.pl.add('/etc/apparmor.d/bin.foo', 'foo', '/bin/foo') + with self.assertRaises(AppArmorException): + self.pl.add('/etc/apparmor.d/bin.foo', 'foo', '/bin/foo') + + def testAddError_twice_2(self): + self.pl.add('/etc/apparmor.d/bin.foo', 'foo', '/bin/foo') + with self.assertRaises(AppArmorException): + self.pl.add('/etc/apparmor.d/bin.foo', 'foo', None) + + def testAddError_twice_3(self): + self.pl.add('/etc/apparmor.d/bin.foo', None, '/bin/foo') + with self.assertRaises(AppArmorException): + self.pl.add('/etc/apparmor.d/bin.foo', 'foo', '/bin/foo') + + def testAddError_twice_4(self): + self.pl.add('/etc/apparmor.d/bin.foo', None, '/bin/foo') + with self.assertRaises(AppArmorException): + self.pl.add('/etc/apparmor.d/bin.foo', 'foo', '/bin/foo') + + def testAddError_twice_5(self): + self.pl.add('/etc/apparmor.d/bin.foo', 'foo', None) + with self.assertRaises(AppArmorException): + self.pl.add('/etc/apparmor.d/bin.foo', 'foo', '/bin/foo') + +class TestFilename_from_profile_name(AATest): + tests = [ + ('foo', '/etc/apparmor.d/bin.foo'), + ('/bin/foo', None), + ('bar', None), + ] + + def AASetup(self): + self.pl = ProfileList() + self.pl.add('/etc/apparmor.d/bin.foo', 'foo', '/bin/foo') + + def _run_test(self, params, expected): + self.assertEqual(self.pl.filename_from_profile_name(params), expected) + +class TestFilename_from_attachment(AATest): + tests = [ + ('/bin/foo', '/etc/apparmor.d/bin.foo'), + ('/bin/baz', '/etc/apparmor.d/bin.baz'), + ('/bin/foobar', '/etc/apparmor.d/bin.foobar'), + ('@{foo}', None), # XXX variables not supported yet (and @{foo} isn't defined in this test) + ('/bin/404', None), + ] + + def AASetup(self): + self.pl = ProfileList() + self.pl.add('/etc/apparmor.d/bin.foo', 'foo', '/bin/foo') + self.pl.add('/etc/apparmor.d/bin.baz', 'baz', '/bin/ba*') + self.pl.add('/etc/apparmor.d/bin.foobar', 'foobar', '/bin/foo{bar,baz}') + + def _run_test(self, params, expected): + self.assertEqual(self.pl.filename_from_attachment(params), expected) + + def test_non_path_attachment(self): + with self.assertRaises(AppArmorBug): + self.pl.filename_from_attachment('foo') + + +setup_all_loops(__name__) +if __name__ == '__main__': + unittest.main(verbosity=1) From 4d722f18397dd35b208548d4c841b955c41ac7ce Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Mon, 22 Oct 2018 23:56:07 +0200 Subject: [PATCH 07/46] Replace existing_profiles & fix minitools for named profiles Technical stuff first: Replace existing_profiles (a dict with the filenames for both active and inactive profiles) with active_profiles and extra_profiles which are ProfileList()s and store the active profiles and those in the extra directory separately. Thanks to ProfileList, now also the relation between attachments and filenames is easily available. Also replace all usage of existing_profiles with active_profiles and extra_profiles, and adjust it to the ProfileList syntax everywhere. With this change, several bugs in aa-complain and the other minitools get fixed: - aa-complain etc. never found profiles that have a profile name (the attachment wasn't checked) - even if the profile name was given as parameter to aa-complain, it first did "which $parameter" so it never matched on named profiles - profile names with alternations (without attachment specification) also never matched because the old code didn't use AARE. References: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=882047#92 (search for "As usual" ;-) Just for completeness - the matching still doesn't honor/expand variables in the profile name. --- utils/aa-mergeprof | 4 +-- utils/apparmor/aa.py | 44 +++++++++++++---------- utils/apparmor/logparser.py | 13 +++---- utils/test/test-libapparmor-test_multi.py | 13 +++++-- 4 files changed, 45 insertions(+), 29 deletions(-) diff --git a/utils/aa-mergeprof b/utils/aa-mergeprof index f0bddf171..40fbbe23d 100755 --- a/utils/aa-mergeprof +++ b/utils/aa-mergeprof @@ -1,7 +1,7 @@ #! /usr/bin/python3 # ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta -# Copyright (C) 2014-2017 Christian Boltz +# Copyright (C) 2014-2018 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -57,7 +57,7 @@ def reset_aa(): apparmor.aa.aa = apparmor.aa.hasher() apparmor.aa.filelist = apparmor.aa.hasher() apparmor.aa.include = dict() - apparmor.aa.existing_profiles = apparmor.aa.hasher() + apparmor.aa.active_profiles = apparmor.aa.ProfileList() apparmor.aa.original_aa = apparmor.aa.hasher() def find_profiles_from_files(files): diff --git a/utils/apparmor/aa.py b/utils/apparmor/aa.py index dd51205fc..30ad07af3 100644 --- a/utils/apparmor/aa.py +++ b/utils/apparmor/aa.py @@ -1,6 +1,6 @@ # ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta -# Copyright (C) 2014-2017 Christian Boltz +# Copyright (C) 2014-2018 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -49,6 +49,8 @@ from apparmor.regex import (RE_PROFILE_START, RE_PROFILE_END, RE_PROFILE_LINK, RE_PROFILE_UNIX, RE_RULE_HAS_COMMA, RE_HAS_COMMENT_SPLIT, strip_quotes, parse_profile_start_line, re_match_include ) +from apparmor.profile_list import ProfileList + from apparmor.profile_storage import (ProfileStorage, add_or_remove_flag, ruletypes, write_alias, write_abi, write_includes, write_list_vars ) @@ -89,7 +91,8 @@ extra_profile_dir = None # To keep track of previously included profile fragments include = dict() -existing_profiles = dict() +active_profiles = ProfileList() +extra_profiles = ProfileList() # To store the globs entered by users so they can be provided again # format: user_globs['/foo*'] = AARE('/foo*') @@ -220,7 +223,7 @@ def find_executable(bin_path): def get_profile_filename_from_profile_name(profile, get_new=False): """Returns the full profile name for the given profile name""" - filename = get_profile_filename_orig(profile) + filename = active_profiles.filename_from_profile_name(profile) if filename: return filename @@ -230,18 +233,13 @@ def get_profile_filename_from_profile_name(profile, get_new=False): def get_profile_filename_from_attachment(profile, get_new=False): """Returns the full profile name for the given attachment""" - filename = get_profile_filename_orig(profile) + filename = active_profiles.filename_from_attachment(profile) if filename: return filename if get_new: return get_new_profile_filename(profile) -def get_profile_filename_orig(profile): - """Returns the full profile name""" - if existing_profiles.get(profile, False): - return existing_profiles[profile] - def get_new_profile_filename(profile): '''Compose filename for a new profile''' if profile.startswith('/'): @@ -527,7 +525,8 @@ def get_profile(prof_name): profile_hash[uname]['profile'] = serialize_profile(inactive_profile[prof_name], prof_name, {}) profile_hash[uname]['profile_data'] = inactive_profile - existing_profiles.pop(prof_name) # remove profile filename from list to force storing in /etc/apparmor.d/ instead of extra_profile_dir + # no longer necessary after splitting active and extra profiles + # existing_profiles.pop(prof_name) # remove profile filename from list to force storing in /etc/apparmor.d/ instead of extra_profile_dir # If no profiles in repo and no inactive profiles if not profile_hash.keys(): @@ -715,15 +714,16 @@ def profile_exists(program): """Returns True if profile exists, False otherwise""" # Check cache of profiles - if existing_profiles.get(program, False): + if active_profiles.filename_from_attachment(program): return True # Check the disk for profile prof_path = get_profile_filename_from_attachment(program, True) #print(prof_path) if os.path.isfile(prof_path): # Add to cache of profile - existing_profiles[program] = prof_path - return True + raise AppArmorBug('Reached strange condition in profile_exists(), please open a bugreport!') + # active_profiles[program] = prof_path + # return True return False def sync_profile(): @@ -1792,7 +1792,7 @@ def set_logfile(filename): def do_logprof_pass(logmark='', passno=0, log_pid=log_pid): # set up variables for this pass # transitions = hasher() - global existing_profiles + global active_profiles global sev_db # aa = hasher() # profile_changes = hasher() @@ -1809,13 +1809,13 @@ def do_logprof_pass(logmark='', passno=0, log_pid=log_pid): if not sev_db: sev_db = apparmor.severity.Severity(CONFDIR + '/severity.db', _('unknown')) #print(pid) - #print(existing_profiles) + #print(active_profiles) ##if not repo_cf and cfg['repostory']['url']: ## repo_cfg = read_config('repository.conf') ## if not repo_cfg['repository'].get('enabled', False) or repo_cfg['repository]['enabled'] not in ['yes', 'no']: ## UI_ask_to_enable_repo() - log_reader = apparmor.logparser.ReadLog(log_pid, logfile, existing_profiles, profile_dir) + log_reader = apparmor.logparser.ReadLog(log_pid, logfile, active_profiles, profile_dir) log = log_reader.read_log(logmark) #read_log(logmark) @@ -2108,18 +2108,26 @@ def read_profile(file, active_profile): for profile in profile_data: # TODO: also honor hats name = profile_data[profile][profile]['name'] + attachment = profile_data[profile][profile]['attachment'] filename = profile_data[profile][profile]['filename'] - existing_profiles[name] = filename + if not attachment and name.startswith('/'): + active_profiles.add(filename, name, name) # use name as name and attachment + else: + active_profiles.add(filename, name, attachment) elif profile_data: attach_profile_data(extras, profile_data) for profile in profile_data: # TODO: also honor hats name = profile_data[profile][profile]['name'] + attachment = profile_data[profile][profile]['attachment'] filename = profile_data[profile][profile]['filename'] - existing_profiles[name] = filename + if not attachment and name.startswith('/'): + extra_profiles.add(filename, name, name) # use name as name and attachment + else: + extra_profiles.add(filename, name, attachment) def attach_profile_data(profiles, profile_data): # Make deep copy of data to avoid changes to diff --git a/utils/apparmor/logparser.py b/utils/apparmor/logparser.py index d21271f8c..f0961d930 100644 --- a/utils/apparmor/logparser.py +++ b/utils/apparmor/logparser.py @@ -1,6 +1,6 @@ # ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta -# Copyright (C) 2015-2016 Christian Boltz +# Copyright (C) 2015-2018 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -44,11 +44,11 @@ class ReadLog: # used to pre-filter log lines so that we hand over only relevant lines to LibAppArmor parsing RE_LOG_ALL = re.compile('(' + '|'.join(RE_log_parts) + ')') - def __init__(self, pid, filename, existing_profiles, profile_dir): + def __init__(self, pid, filename, active_profiles, profile_dir): self.filename = filename self.profile_dir = profile_dir self.pid = pid - self.existing_profiles = existing_profiles + self.active_profiles = active_profiles self.log = [] self.debug_logger = DebugLogger('ReadLog') self.LOG = None @@ -447,15 +447,16 @@ class ReadLog: def profile_exists(self, program): """Returns True if profile exists, False otherwise""" # Check cache of profiles - if self.existing_profiles.get(program, False): + if self.active_profiles.filename_from_profile_name(program): return True # Check the disk for profile prof_path = self.get_profile_filename(program) #print(prof_path) if os.path.isfile(prof_path): # Add to cache of profile - self.existing_profiles[program] = prof_path - return True + raise AppArmorBug('This should never happen, please open a bugreport!') + # self.active_profiles[program] = prof_path + # return True return False def get_profile_filename(self, profile): diff --git a/utils/test/test-libapparmor-test_multi.py b/utils/test/test-libapparmor-test_multi.py index bc53e9cda..ef703e6c5 100644 --- a/utils/test/test-libapparmor-test_multi.py +++ b/utils/test/test-libapparmor-test_multi.py @@ -1,7 +1,7 @@ #! /usr/bin/python3 # ------------------------------------------------------------------ # -# Copyright (C) 2015 Christian Boltz +# Copyright (C) 2015-2018 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -18,6 +18,7 @@ from apparmor.common import open_file_read import apparmor.aa from apparmor.logparser import ReadLog +from apparmor.profile_list import ProfileList class TestLibapparmorTestMulti(AATest): '''Parse all libraries/libapparmor/testsuite/test_multi tests and compare the result with the *.out files''' @@ -249,9 +250,15 @@ def logfile_to_profile(logfile): if '//' in profile: profile, hat = profile.split('//') - apparmor.aa.existing_profiles = {profile: profile_dummy_file} + apparmor.aa.active_profiles = ProfileList() - log_reader = ReadLog(dict(), logfile, apparmor.aa.existing_profiles, '') + # optional for now, might be needed one day + # if profile.startswith('/'): + # apparmor.aa.active_profiles.add(profile_dummy_file, profile, profile) + # else: + apparmor.aa.active_profiles.add(profile_dummy_file, profile, '') + + log_reader = ReadLog(dict(), logfile, apparmor.aa.active_profiles, '') log = log_reader.read_log('') for root in log: From 29da17310e3c88d5a4c4a625bbadf44aacb9a5ef Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Fri, 2 Nov 2018 17:00:33 +0100 Subject: [PATCH 08/46] replace -1 return codes with 255 Technically "return -1" returns 255, so we should write it that way. (found by shellcheck) --- parser/rc.apparmor.functions | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/parser/rc.apparmor.functions b/parser/rc.apparmor.functions index 9edded527..7060cf736 100644 --- a/parser/rc.apparmor.functions +++ b/parser/rc.apparmor.functions @@ -243,10 +243,10 @@ failstop_system() { if [ $level -ne "1" ] ; then aa_log_failure_msg "- could not start AppArmor. Changing to runlevel 1" telinit 1; - return -1; + return 255; fi aa_log_failure_msg "- could not start AppArmor." - return -1 + return 255 } module_panic() { @@ -259,7 +259,7 @@ module_panic() { rc=$? return $rc ;; *) aa_log_failure_msg "- invalid AppArmor module fail option" - return -1 ;; + return 255 ;; esac } From b95f9bdd3b1937c4944da3de48d5e128e580d53d Mon Sep 17 00:00:00 2001 From: intrigeri Date: Tue, 30 Oct 2018 10:52:18 +0000 Subject: [PATCH 09/46] apparmor(7): Document various debugging options. Credits go to John Johansen for most of the information and the initial phrasing. Bug-Debian: https://bugs.debian.org/826218 --- parser/apparmor.pod | 50 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/parser/apparmor.pod b/parser/apparmor.pod index e4725d751..575200290 100644 --- a/parser/apparmor.pod +++ b/parser/apparmor.pod @@ -143,6 +143,56 @@ messages with the KERN facility. Thus, REJECTING and PERMITTING messages may go to either F or F, depending upon local configuration. +=head1 DEBUGGING + +AppArmor provides a few facilities to log more information, +which can help debugging profiles. + +=head2 Enable debug mode + +When debug mode is enabled, AppArmor will log a few extra messages to +dmesg (not via the audit subsystem). For example, the logs will tell +whether environment scrubbing has been applied. + +To enable debug mode, run: + + echo 1 > /sys/module/apparmor/parameters/debug + +=head2 Turn off deny audit quieting + +By default, operations that trigger C rules are not logged. +This is called I. + +To turn off deny audit quieting, run: + + echo -n noquiet >/sys/module/apparmor/parameters/audit + +=head2 Force audit mode + +AppArmor can log a message for every operation that triggers a rule +configured in the policy. This is called I. + +B Force audit mode can be extremely noisy even for a single profile, +let alone when enabled globally. + +To set a specific profile in force audit mode, add the C flag: + + profile foo flags=(audit) { ... } + +To enable force audit mode globally, run: + + echo -n all > /sys/module/apparmor/parameters/audit + +If auditd is not running, to avoid losing too many of the extra log +messages, you will likely have to turn off rate limiting by doing: + + echo 0 > /proc/sys/kernel/printk_ratelimit + +But even then the kernel ring buffer may overflow and you might +lose messages. + +Else, if auditd is running, see auditd(8) and auditd.conf(5). + =head1 FILES =over 4 From a3305b512d2fdafa9f8e225f481daa577636d175 Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Tue, 6 Nov 2018 21:33:12 +0100 Subject: [PATCH 10/46] disable abi/ok_10 and abi/ok_12 tests Both result in "superfluous TODO" (for unknown reason), but fail after removing the TODO. Disable the tests until we find out why they have this strange behaviour, to unblock merging the "error out on superfluous TODO" patch. --- parser/tst/simple_tests/abi/ok_10.sd | 1 + parser/tst/simple_tests/abi/ok_12.sd | 1 + 2 files changed, 2 insertions(+) diff --git a/parser/tst/simple_tests/abi/ok_10.sd b/parser/tst/simple_tests/abi/ok_10.sd index 1825e9797..9a9dee5ab 100644 --- a/parser/tst/simple_tests/abi/ok_10.sd +++ b/parser/tst/simple_tests/abi/ok_10.sd @@ -2,6 +2,7 @@ #=DESCRIPTION abi testing - abi path quotes in <> with spaces #=EXRESULT PASS #=TODO +#=DISABLED - results in "superfluous TODO", but fails after removing TODO abi < "abi/4.19">, diff --git a/parser/tst/simple_tests/abi/ok_12.sd b/parser/tst/simple_tests/abi/ok_12.sd index 442b62c92..1433575a5 100644 --- a/parser/tst/simple_tests/abi/ok_12.sd +++ b/parser/tst/simple_tests/abi/ok_12.sd @@ -2,6 +2,7 @@ #=DESCRIPTION abi testing - abi path quotes in <> with spaces #=EXRESULT PASS #=TODO +#=DISABLED - results in "superfluous TODO", but fails after removing TODO abi < "abi/4.19" >, From 4b26850e14abe86569e4cf587bbd4ef197b383b5 Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Thu, 20 Sep 2018 00:49:42 +0200 Subject: [PATCH 11/46] error out on superfluous TODOs If a test is marked as TODO, but matches its EXRESULT, this means the TODO is superfluous and (probably) a change fixed what the TODO was for. Instead of more or less ignoring such superfluous TODOs, error out to make the change visible instantly. --- parser/tst/simple.pl | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/parser/tst/simple.pl b/parser/tst/simple.pl index e11d95230..36fd70ccb 100755 --- a/parser/tst/simple.pl +++ b/parser/tst/simple.pl @@ -131,9 +131,13 @@ sub test_profile { } elsif ($coredump) { ok(0, "$profile: Produced core dump (signal $signal): $description"); } elsif ($istodo) { - TODO: { - local $TODO = "Unfixed testcase."; - ok($expass ? !$result : $result, "TODO: $profile: $description"); + if ($expass != $result) { + fail("TODO passed unexpectedly: $profile: $description"); + } else { + TODO: { + local $TODO = "Unfixed testcase."; + ok($expass ? !$result : $result, "TODO: $profile: $description"); + } } } else { ok($expass ? !$result : $result, "$profile: $description"); From 197b5d63fee6ce46eeeb1b902ec35529f2ab007c Mon Sep 17 00:00:00 2001 From: Eric Chiang Date: Tue, 6 Nov 2018 19:00:20 -0800 Subject: [PATCH 12/46] parser/libapparmor_re: expand comment of firstpos, lastpos, followpos Elaborate in class comment of firstpos, lastpos, followpos, and nullable fields beyond just referencing the Dragon book. Also add the section of the book these are explained in. --- parser/libapparmor_re/expr-tree.h | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/parser/libapparmor_re/expr-tree.h b/parser/libapparmor_re/expr-tree.h index 1715c238a..9100db32f 100644 --- a/parser/libapparmor_re/expr-tree.h +++ b/parser/libapparmor_re/expr-tree.h @@ -116,13 +116,34 @@ public: } /** - * See the "Dragon Book" for an explanation of nullable, firstpos, - * lastpos, and followpos. + * firstpos, lastpos, and followpos are used to convert the syntax tree + * to a DFA. + * + * firstpos holds nodes that can match the first character of a string + * that matches the syntax tree. For the regex 'a*bcd', firstpos holds + * the 'a' and 'b' nodes. firstpos is used to determine the start state + * of the DFA. + * + * lastpos is the same as firstpos for the last character. For the regex + * 'a*bcd', lastpos holds the 'd' node. lastpos is used to determine the + * accepting states of the DFA. + * + * followpos holds the set of nodes that can match a character directly + * after the current node. For the regexp 'a*bcd', the followpos of the + * 'a' node are the 'b' node and the 'a' node itself. followpos is used + * to determine the transitions of the DFA. + * + * nullable indicates that a node can match the empty string. It is used + * to compute firstpos and lastpos. + * + * See the "Dragon Book" 2nd Edition section 3.9.2 for an in-depth + * explanation. */ virtual void compute_nullable() { } virtual void compute_firstpos() = 0; virtual void compute_lastpos() = 0; virtual void compute_followpos() { } + virtual int eq(Node *other) = 0; virtual ostream &dump(ostream &os) = 0; void dump_syntax_tree(ostream &os); From 2438179b76a4a66cf50164874003cf823f8900cf Mon Sep 17 00:00:00 2001 From: Vincas Dargis Date: Thu, 8 Nov 2018 20:00:45 +0200 Subject: [PATCH 13/46] Use @{sys} tunable in profiles and abstractions Commit aa065287909f6a3115bfaf02bee85d323e46b706 made @{sys} tunable available by default. Update profiles and abstractions to actually use @{sys} tunable for better confinement in the future (when @{sys} becomes kernel var). Closes LP#1728551 --- profiles/apparmor.d/abstractions/base | 4 +-- .../apparmor.d/abstractions/dri-enumerate | 3 +- profiles/apparmor.d/abstractions/nvidia | 2 +- .../apparmor.d/abstractions/opencl-common | 6 ++-- profiles/apparmor.d/abstractions/opencl-intel | 2 +- .../apparmor.d/abstractions/opencl-nvidia | 4 +-- profiles/apparmor.d/abstractions/opencl-pocl | 32 +++++++++---------- .../abstractions/ubuntu-browsers.d/java | 8 ++--- profiles/apparmor.d/abstractions/video | 4 +-- profiles/apparmor.d/abstractions/vulkan | 2 +- profiles/apparmor.d/apache2.d/phpsysinfo | 14 ++++---- profiles/apparmor.d/nvidia_modprobe | 10 +++--- profiles/apparmor.d/sbin.syslog-ng | 2 +- profiles/apparmor.d/usr.sbin.dnsmasq | 6 ++-- 14 files changed, 49 insertions(+), 50 deletions(-) diff --git a/profiles/apparmor.d/abstractions/base b/profiles/apparmor.d/abstractions/base index 533bfb011..2a39ee04c 100644 --- a/profiles/apparmor.d/abstractions/base +++ b/profiles/apparmor.d/abstractions/base @@ -90,8 +90,8 @@ @{PROC}/meminfo r, @{PROC}/stat r, @{PROC}/cpuinfo r, - /sys/devices/system/cpu/ r, - /sys/devices/system/cpu/online r, + @{sys}/devices/system/cpu/ r, + @{sys}/devices/system/cpu/online r, # glibc's *printf protections read the maps file @{PROC}/@{pid}/{maps,auxv,status} r, diff --git a/profiles/apparmor.d/abstractions/dri-enumerate b/profiles/apparmor.d/abstractions/dri-enumerate index 1162a08e2..e101be5cb 100644 --- a/profiles/apparmor.d/abstractions/dri-enumerate +++ b/profiles/apparmor.d/abstractions/dri-enumerate @@ -4,6 +4,5 @@ # needs to enumerate graphic devices (as with drmParsePciDeviceInfo() from # libdrm). - # TODO: use @{sys} after it's moved into tunables/kernelvars (LP: #1728551) - /sys/devices/pci[0-9]*/**/{device,subsystem_device,subsystem_vendor,uevent,vendor} r, + @{sys}/devices/pci[0-9]*/**/{device,subsystem_device,subsystem_vendor,uevent,vendor} r, diff --git a/profiles/apparmor.d/abstractions/nvidia b/profiles/apparmor.d/abstractions/nvidia index b65e8a01b..b01ef8b55 100644 --- a/profiles/apparmor.d/abstractions/nvidia +++ b/profiles/apparmor.d/abstractions/nvidia @@ -19,7 +19,7 @@ @{PROC}/driver/nvidia/params r, @{PROC}/modules r, - /sys/devices/system/memory/block_size_bytes r, + @{sys}/devices/system/memory/block_size_bytes r, owner @{HOME}/.nv/ w, owner @{HOME}/.nv/GLCache/ rw, diff --git a/profiles/apparmor.d/abstractions/opencl-common b/profiles/apparmor.d/abstractions/opencl-common index bbf773174..0ad3d559a 100644 --- a/profiles/apparmor.d/abstractions/opencl-common +++ b/profiles/apparmor.d/abstractions/opencl-common @@ -4,7 +4,7 @@ # System files /etc/OpenCL/** r, - /sys/bus/pci/devices/ r, # libpocl.so -> libhwlock.so, libnvidia-opencl.so, beignet/libcl.so -> libdrm_intel.so - /sys/devices/system/node/ r, # for clGetPlatformIDs() from libOpenCL.so - /sys/devices/system/node/node[0-9]*/meminfo r, # for clGetPlatformIDs() from libOpenCL.so + @{sys}/bus/pci/devices/ r, # libpocl.so -> libhwlock.so, libnvidia-opencl.so, beignet/libcl.so -> libdrm_intel.so + @{sys}/devices/system/node/ r, # for clGetPlatformIDs() from libOpenCL.so + @{sys}/devices/system/node/node[0-9]*/meminfo r, # for clGetPlatformIDs() from libOpenCL.so diff --git a/profiles/apparmor.d/abstractions/opencl-intel b/profiles/apparmor.d/abstractions/opencl-intel index db414c5b2..353eeca29 100644 --- a/profiles/apparmor.d/abstractions/opencl-intel +++ b/profiles/apparmor.d/abstractions/opencl-intel @@ -12,6 +12,6 @@ # System files /dev/dri/card[0-9]* rw, # beignet/libcl.so - /sys/devices/pci[0-9]*/**/{class,config,resource,revision} r, # libcl.so -> libdrm_intel.so -> libpciaccess.so (move to dri-enumerate ?) + @{sys}/devices/pci[0-9]*/**/{class,config,resource,revision} r, # libcl.so -> libdrm_intel.so -> libpciaccess.so (move to dri-enumerate ?) /usr/lib/@{multiarch}/beignet/** r, diff --git a/profiles/apparmor.d/abstractions/opencl-nvidia b/profiles/apparmor.d/abstractions/opencl-nvidia index 5fcfab987..8a4764ecb 100644 --- a/profiles/apparmor.d/abstractions/opencl-nvidia +++ b/profiles/apparmor.d/abstractions/opencl-nvidia @@ -16,8 +16,8 @@ # libnvidia-opencl.so rules: /dev/nvidia-uvm rw, /dev/nvidia-uvm-tools rw, - /sys/devices/pci[0-9]*/**/config r, - /sys/devices/system/memory/block_size_bytes r, + @{sys}/devices/pci[0-9]*/**/config r, + @{sys}/devices/system/memory/block_size_bytes r, /usr/share/nvidia/** r, @{PROC}/devices r, @{PROC}/sys/vm/mmap_min_addr r, diff --git a/profiles/apparmor.d/abstractions/opencl-pocl b/profiles/apparmor.d/abstractions/opencl-pocl index d47823947..054689abc 100644 --- a/profiles/apparmor.d/abstractions/opencl-pocl +++ b/profiles/apparmor.d/abstractions/opencl-pocl @@ -11,22 +11,22 @@ # System files / r, # libpocl.so -> libhwloc.so - /sys/bus/pci/slots/ r, # libpocl.so -> hwloc_topology_load() from libhwloc.so - /sys/bus/{cpu,node}/devices/ r, # libpocl.so -> libhwlock.so - /sys/class/net/ r, # libpocl.so -> hwloc_pci_traverse_lookuposdevices_cb() from libhwloc.so - /sys/devices/pci[0-9]*/**/ r, # for libpocl -> hwloc_linux_lookup_block_class() from libhwloc.so - /sys/devices/pci[0-9]*/**/block/*/dev r, # libpocl.so -> hwloc_linux_lookup_host_block_class() from libhwloc.so - /sys/devices/pci[0-9]*/**/{class,local_cpus} r, # libpocl.so -> libhwlock.so - /sys/devices/pci[0-9]*/*/net/*/address r, # libpocl.so -> hwloc_pci_traverse_lookuposdevices_cb() from libhwloc.so - /sys/devices/system/cpu/ r, # libpocl.so -> libnuma.so - /sys/devices/system/cpu/cpu[0-9]*/cache/index[0-9]*/* r, # libpocl.so -> libhwloc.so - /sys/devices/system/cpu/cpu[0-9]*/online r, # libpocl.so -> libhwlock.so - /sys/devices/system/cpu/cpu[0-9]*/topology/* r, # *_siblings, physical_package_id and lot's of others, for libpocl.so -> libhwloc.so - /sys/devices/system/cpu/cpufreq/policy[0-9]*/* r, # for clGetPlatformIDs() from libpocl.so - /sys/devices/system/cpu/possible r, # libpocl.so -> libhwloc.so - /sys/devices/virtual/dmi/id/{,*} r, # libpocl.so -> libhwloc.so - /sys/fs/cgroup/cpuset/cpuset.{cpus,mems} r, # libpocl.so -> libhwloc.so - /sys/kernel/mm/hugepages{/,/**} r, # libpocl.so -> libhwloc.so + @{sys}/bus/pci/slots/ r, # libpocl.so -> hwloc_topology_load() from libhwloc.so + @{sys}/bus/{cpu,node}/devices/ r, # libpocl.so -> libhwlock.so + @{sys}/class/net/ r, # libpocl.so -> hwloc_pci_traverse_lookuposdevices_cb() from libhwloc.so + @{sys}/devices/pci[0-9]*/**/ r, # for libpocl -> hwloc_linux_lookup_block_class() from libhwloc.so + @{sys}/devices/pci[0-9]*/**/block/*/dev r, # libpocl.so -> hwloc_linux_lookup_host_block_class() from libhwloc.so + @{sys}/devices/pci[0-9]*/**/{class,local_cpus} r, # libpocl.so -> libhwlock.so + @{sys}/devices/pci[0-9]*/*/net/*/address r, # libpocl.so -> hwloc_pci_traverse_lookuposdevices_cb() from libhwloc.so + @{sys}/devices/system/cpu/ r, # libpocl.so -> libnuma.so + @{sys}/devices/system/cpu/cpu[0-9]*/cache/index[0-9]*/* r, # libpocl.so -> libhwloc.so + @{sys}/devices/system/cpu/cpu[0-9]*/online r, # libpocl.so -> libhwlock.so + @{sys}/devices/system/cpu/cpu[0-9]*/topology/* r, # *_siblings, physical_package_id and lot's of others, for libpocl.so -> libhwloc.so + @{sys}/devices/system/cpu/cpufreq/policy[0-9]*/* r, # for clGetPlatformIDs() from libpocl.so + @{sys}/devices/system/cpu/possible r, # libpocl.so -> libhwloc.so + @{sys}/devices/virtual/dmi/id/{,*} r, # libpocl.so -> libhwloc.so + @{sys}/fs/cgroup/cpuset/cpuset.{cpus,mems} r, # libpocl.so -> libhwloc.so + @{sys}/kernel/mm/hugepages{/,/**} r, # libpocl.so -> libhwloc.so /usr/share/pocl/** r, /{,var/}run/udev/data/*:* r, # libpocl.so -> hwloc_linux_block_class_fillinfos() from libhwloc.so diff --git a/profiles/apparmor.d/abstractions/ubuntu-browsers.d/java b/profiles/apparmor.d/abstractions/ubuntu-browsers.d/java index 4a3a54a32..8193a5c9f 100644 --- a/profiles/apparmor.d/abstractions/ubuntu-browsers.d/java +++ b/profiles/apparmor.d/abstractions/ubuntu-browsers.d/java @@ -41,8 +41,8 @@ @{PROC}/@{pid}/ r, @{PROC}/@{pid}/fd/ r, @{PROC}/filesystems r, - /sys/devices/system/cpu/ r, - /sys/devices/system/cpu/** r, + @{sys}/devices/system/cpu/ r, + @{sys}/devices/system/cpu/** r, /usr/share/** r, /var/lib/dbus/machine-id r, @@ -88,8 +88,8 @@ @{PROC}/@{pid}/ r, @{PROC}/@{pid}/fd/ r, @{PROC}/filesystems r, - /sys/devices/system/cpu/ r, - /sys/devices/system/cpu/** r, + @{sys}/devices/system/cpu/ r, + @{sys}/devices/system/cpu/** r, /usr/share/** r, /var/lib/dbus/machine-id r, diff --git a/profiles/apparmor.d/abstractions/video b/profiles/apparmor.d/abstractions/video index 61cebaed6..00a834681 100644 --- a/profiles/apparmor.d/abstractions/video +++ b/profiles/apparmor.d/abstractions/video @@ -2,5 +2,5 @@ # video device access # System devices - /sys/class/video4linux r, - /sys/class/video4linux/** r, + @{sys}/class/video4linux r, + @{sys}/class/video4linux/** r, diff --git a/profiles/apparmor.d/abstractions/vulkan b/profiles/apparmor.d/abstractions/vulkan index 4e991dfe2..39b5d5ff9 100644 --- a/profiles/apparmor.d/abstractions/vulkan +++ b/profiles/apparmor.d/abstractions/vulkan @@ -5,7 +5,7 @@ /dev/dri/ r, # libvulkan_radeon.so, libvulkan_intel.so (Mesa) /etc/vulkan/{explicit,implicit}_layer.d/{,*.json} r, # for drmGetMinorNameForFD() from libvulkan_intel.so (Mesa) - /sys/devices/pci[0-9]*/*/drm/ r, + @{sys}/devices/pci[0-9]*/*/drm/ r, /usr/share/vulkan/icd.d/{,*.json} r, /usr/share/vulkan/{explicit,implicit}_layer.d/{,*.json} r, diff --git a/profiles/apparmor.d/apache2.d/phpsysinfo b/profiles/apparmor.d/apache2.d/phpsysinfo index 669f7a491..af730910e 100644 --- a/profiles/apparmor.d/apache2.d/phpsysinfo +++ b/profiles/apparmor.d/apache2.d/phpsysinfo @@ -20,13 +20,13 @@ /etc/phpsysinfo/config.php r, /etc/udev/udev.conf r, @{PROC}/** r, - /sys/bus/ r, - /sys/bus/pci/devices/ r, - /sys/bus/pci/slots/ r, - /sys/bus/pci/slots/** r, - /sys/bus/usb/devices/ r, - /sys/class/ r, - /sys/devices/** r, + @{sys}/bus/ r, + @{sys}/bus/pci/devices/ r, + @{sys}/bus/pci/slots/ r, + @{sys}/bus/pci/slots/** r, + @{sys}/bus/usb/devices/ r, + @{sys}/class/ r, + @{sys}/devices/** r, /usr/bin/ r, /usr/bin/apt-cache ixr, /usr/bin/dpkg-query ixr, diff --git a/profiles/apparmor.d/nvidia_modprobe b/profiles/apparmor.d/nvidia_modprobe index 907820fba..01f714ca7 100644 --- a/profiles/apparmor.d/nvidia_modprobe +++ b/profiles/apparmor.d/nvidia_modprobe @@ -24,8 +24,8 @@ profile nvidia_modprobe { /dev/nvidia-uvm w, /dev/nvidia-uvm-tools w, - /sys/bus/pci/devices/ r, - /sys/devices/pci[0-9]*/**/config r, + @{sys}/bus/pci/devices/ r, + @{sys}/devices/pci[0-9]*/**/config r, @{PROC}/devices r, @{PROC}/modules r, @{PROC}/sys/kernel/modprobe r, @@ -51,9 +51,9 @@ profile nvidia_modprobe { /etc/modprobe.d/{,*.conf} r, /etc/nvidia/current/*.conf r, - /sys/module/ipmi_devintf/initstate r, - /sys/module/ipmi_msghandler/initstate r, - /sys/module/nvidia/initstate r, + @{sys}/module/ipmi_devintf/initstate r, + @{sys}/module/ipmi_msghandler/initstate r, + @{sys}/module/nvidia/initstate r, @{PROC}/cmdline r, } diff --git a/profiles/apparmor.d/sbin.syslog-ng b/profiles/apparmor.d/sbin.syslog-ng index b179b3e6c..12f1b6dc8 100644 --- a/profiles/apparmor.d/sbin.syslog-ng +++ b/profiles/apparmor.d/sbin.syslog-ng @@ -47,7 +47,7 @@ profile syslog-ng /{usr/,}{bin,sbin}/syslog-ng { /etc/hosts.deny r, /etc/hosts.allow r, /{usr/,}{bin,sbin}/syslog-ng mr, - /sys/devices/system/cpu/online r, + @{sys}/devices/system/cpu/online r, /usr/share/syslog-ng/** r, /var/lib/syslog-ng/syslog-ng-?????.qf rw, # chrooted applications diff --git a/profiles/apparmor.d/usr.sbin.dnsmasq b/profiles/apparmor.d/usr.sbin.dnsmasq index f2e6847d1..fba51259d 100644 --- a/profiles/apparmor.d/usr.sbin.dnsmasq +++ b/profiles/apparmor.d/usr.sbin.dnsmasq @@ -107,9 +107,9 @@ profile dnsmasq /usr/{bin,sbin}/dnsmasq flags=(attach_disconnected) { owner @{PROC}/@{pid}/net/psched r, owner @{PROC}/@{pid}/status r, - /sys/devices/system/cpu/ r, - /sys/devices/system/node/ r, - /sys/devices/system/node/*/meminfo r, + @{sys}/devices/system/cpu/ r, + @{sys}/devices/system/node/ r, + @{sys}/devices/system/node/*/meminfo r, # libvirt lease and status files for dnsmasq /var/lib/libvirt/dnsmasq/*.leases rw, From 0d5ab43d592245d011b2614e6e20fc7cb851c53c Mon Sep 17 00:00:00 2001 From: John Johansen Date: Sat, 3 Nov 2018 07:15:16 -0700 Subject: [PATCH 14/46] rc.apparmor.functions: drop module loading support The apparmor kernel "module" has not been a loadable module for more than a decade, it must be built into the kernel and due configuration requirements it will never go back to being a loadable module. Remove the long unfunctioning load_module support from the init script. PR: https://gitlab.com/apparmor/apparmor/merge_requests/257 Signed-off-by: John Johansen Acked-by: seth.arnold@canonical.com --- parser/rc.apparmor.functions | 42 +++++++----------------------------- 1 file changed, 8 insertions(+), 34 deletions(-) diff --git a/parser/rc.apparmor.functions b/parser/rc.apparmor.functions index 7060cf736..3a25108ec 100644 --- a/parser/rc.apparmor.functions +++ b/parser/rc.apparmor.functions @@ -325,42 +325,16 @@ unmount_subdomainfs() { fi } -load_module() { - local rc=0 - if modinfo -F filename apparmor > /dev/null 2>&1 ; then - MODULE=apparmor - elif modinfo -F filename ${OLD_MODULE} > /dev/null 2>&1 ; then - MODULE=${OLD_MODULE} - fi - - if ! is_apparmor_present apparmor subdomain ; then - aa_action "Loading AppArmor module" /sbin/modprobe -q $MODULE $1 - rc=$? - if [ $rc -ne 0 ] ; then - module_panic - rc=$? - if [ $rc -ne 0 ] ; then - exit $rc - fi - fi - fi - - if ! is_apparmor_loaded ; then - return 1 - fi - - return $rc -} - apparmor_start() { aa_log_daemon_msg "Starting AppArmor" - if ! is_apparmor_loaded ; then - load_module - rc=$? - if [ $rc -ne 0 ] ; then - aa_log_end_msg $rc - return $rc - fi + if ! is_apparmor_present ; then + aa_log_failure_msg "Starting AppArmor - failed, To enable AppArmor, ensure your kernel is configured with CONFIG_SECURITY_APPARMOR=y then add 'security=apparmor apparmor=1' to the kernel command line" + aa_log_end_msg 1 + return 1 + elif ! is_apparmor_loaded ; then + aa_log_failure_msg "Starting AppArmor - AppArmor control files aren't available under /sys/kernel/security/, please make sure securityfs is mounted." + aa_log_end_msg 1 + return 1 fi if [ ! -w "$SFS_MOUNTPOINT/.load" ] ; then From 94ff870f78ad32053392b19b4600b4b5584e3bfb Mon Sep 17 00:00:00 2001 From: John Johansen Date: Sat, 3 Nov 2018 16:39:49 -0700 Subject: [PATCH 15/46] remove subdomainfs support It has been over 10 years since transition from subdomainfs to using securityfs. Lets drop this deprecated code. PR: https://gitlab.com/apparmor/apparmor/merge_requests/258 Signed-off-by: John Johansen Acked-by: seth.arnold@canonical.com --- changehat/mod_apparmor/mod_apparmor.pod | 2 +- parser/Makefile | 6 +- parser/apparmor.pod | 2 +- parser/apparmor_parser.pod | 4 +- parser/parser_include.c | 68 +----------- parser/rc.apparmor.functions | 98 +---------------- parser/subdomain.conf | 53 --------- parser/subdomain.conf.pod | 104 ------------------ tests/stress/{subdomain => apparmor}/Makefile | 0 .../{subdomain => apparmor}/change_hat.c | 0 .../change_hat.profile.pre | 0 tests/stress/{subdomain => apparmor}/child.c | 0 .../{subdomain => apparmor}/child.profile.pre | 0 tests/stress/{subdomain => apparmor}/kill.sh | 0 tests/stress/{subdomain => apparmor}/open.c | 0 .../{subdomain => apparmor}/open.profile.pre | 0 .../{subdomain => apparmor}/s-2.4.20.sh | 0 tests/stress/{subdomain => apparmor}/s.sh | 0 .../{subdomain => apparmor}/sh.profile.pre | 0 .../stress/{subdomain => apparmor}/stress.sh | 0 .../{subdomain => apparmor}/stress.sh-2.4.20 | 0 .../{subdomain => apparmor}/uservars.inc | 0 utils/apparmor/config.py | 2 +- 23 files changed, 14 insertions(+), 325 deletions(-) delete mode 100644 parser/subdomain.conf delete mode 100644 parser/subdomain.conf.pod rename tests/stress/{subdomain => apparmor}/Makefile (100%) rename tests/stress/{subdomain => apparmor}/change_hat.c (100%) rename tests/stress/{subdomain => apparmor}/change_hat.profile.pre (100%) rename tests/stress/{subdomain => apparmor}/child.c (100%) rename tests/stress/{subdomain => apparmor}/child.profile.pre (100%) rename tests/stress/{subdomain => apparmor}/kill.sh (100%) rename tests/stress/{subdomain => apparmor}/open.c (100%) rename tests/stress/{subdomain => apparmor}/open.profile.pre (100%) rename tests/stress/{subdomain => apparmor}/s-2.4.20.sh (100%) rename tests/stress/{subdomain => apparmor}/s.sh (100%) rename tests/stress/{subdomain => apparmor}/sh.profile.pre (100%) rename tests/stress/{subdomain => apparmor}/stress.sh (100%) rename tests/stress/{subdomain => apparmor}/stress.sh-2.4.20 (100%) rename tests/stress/{subdomain => apparmor}/uservars.inc (100%) diff --git a/changehat/mod_apparmor/mod_apparmor.pod b/changehat/mod_apparmor/mod_apparmor.pod index f9352ee78..54f9f36d6 100644 --- a/changehat/mod_apparmor/mod_apparmor.pod +++ b/changehat/mod_apparmor/mod_apparmor.pod @@ -139,7 +139,7 @@ them at L. =head1 SEE ALSO -apparmor(7), subdomain.conf(5), apparmor_parser(8), aa_change_hat(2) and +apparmor(7), apparmor_parser(8), aa_change_hat(2) and L. =cut diff --git a/parser/Makefile b/parser/Makefile index 73e88f5c2..558d9616b 100644 --- a/parser/Makefile +++ b/parser/Makefile @@ -30,7 +30,7 @@ SYSTEMD_UNIT_DIR=${DESTDIR}/usr/lib/systemd/system CONFDIR=/etc/apparmor INSTALL_CONFDIR=${DESTDIR}${CONFDIR} LOCALEDIR=/usr/share/locale -MANPAGES=apparmor.d.5 apparmor.7 apparmor_parser.8 subdomain.conf.5 aa-teardown.8 +MANPAGES=apparmor.d.5 apparmor.7 apparmor_parser.8 aa-teardown.8 YACC := bison YFLAGS := -d @@ -72,9 +72,6 @@ endif # Internationalization support. Define a package and a LOCALEDIR EXTRA_CFLAGS+=-DPACKAGE=\"${NAME}\" -DLOCALEDIR=\"${LOCALEDIR}\" -# Compile-time configuration of the location of the config file -EXTRA_CFLAGS+=-DSUBDOMAIN_CONFDIR=\"${CONFDIR}\" - SRCS = parser_common.c parser_include.c parser_interface.c parser_lex.c \ parser_main.c parser_misc.c parser_merge.c parser_symtab.c \ parser_yacc.c parser_regex.c parser_variable.c parser_policy.c \ @@ -373,7 +370,6 @@ install-arch: $(INSTALLDEPS) .PHONY: install-indep install-indep: indep install -m 755 -d $(INSTALL_CONFDIR) - install -m 644 subdomain.conf $(INSTALL_CONFDIR) install -m 644 parser.conf $(INSTALL_CONFDIR) install -m 755 -d ${DESTDIR}/var/lib/apparmor install -m 755 -d $(APPARMOR_BIN_PREFIX) diff --git a/parser/apparmor.pod b/parser/apparmor.pod index 575200290..4d731f3cb 100644 --- a/parser/apparmor.pod +++ b/parser/apparmor.pod @@ -212,7 +212,7 @@ Else, if auditd is running, see auditd(8) and auditd.conf(5). =head1 SEE ALSO apparmor_parser(8), aa_change_hat(2), apparmor.d(5), -subdomain.conf(5), aa-autodep(1), clean(1), +aa-autodep(1), clean(1), auditd(8), aa-unconfined(8), aa-enforce(1), aa-complain(1), and L. diff --git a/parser/apparmor_parser.pod b/parser/apparmor_parser.pod index bcf25f983..ede3509c6 100644 --- a/parser/apparmor_parser.pod +++ b/parser/apparmor_parser.pod @@ -179,7 +179,7 @@ defined as relative paths. Add element n to the search path when resolving #include directives defined as an absolute paths. -=item -f n, --subdomainfs n +=item -f n, --apparmorfs n Set the location of the apparmor security filesystem (default is "/sys/kernel/security/apparmor"). @@ -408,7 +408,7 @@ L. =head1 SEE ALSO -apparmor(7), apparmor.d(5), subdomain.conf(5), aa_change_hat(2), and +apparmor(7), apparmor.d(5), aa_change_hat(2), and L. =cut diff --git a/parser/parser_include.c b/parser/parser_include.c index 9fc8b83b5..d31248816 100644 --- a/parser/parser_include.c +++ b/parser/parser_include.c @@ -17,21 +17,21 @@ * along with this program; if not, contact Canonical, Ltd. */ -/* Handle subdomain includes, as a straight forward preprocessing phase. +/* Handle apparmor includes, as a straight forward preprocessing phase. While we are at it we will strip comments. Why? because it made it easier. We support 2 types of includes #include which searches for the first occurance of name in the - subdomain directory path. + apparmor directory path. #include "name" which will search for a relative or absolute pathed file -p : preprocess only. Dump output to stdout -I path : add a path to be search by #include < > --b path : set the base path to something other than /etc/subdomain.d +-b path : set the base path to something other than /etc/apparmor.d */ @@ -57,13 +57,6 @@ /* maximum depth of nesting */ #define MAX_NEST_LEVEL 100 -/* Location of the subdomain.conf file */ -#ifdef SUBDOMAIN_CONFDIR -#define SUBDOMAIN_CONF SUBDOMAIN_CONFDIR "/subdomain.conf" -#else /* !defined SUBDOMAIN_CONFDIR */ -#define SUBDOMAIN_CONF "/etc/subdomain.conf" -#endif /* SUBDOMAIN_CONFDIR */ - static char *path[MAX_PATH] = { NULL }; static int npath = 0; @@ -71,12 +64,11 @@ static int fgetline(FILE * f, char *buffer, size_t len); static int stripcomment(char *s); static char *stripblanks(char *s); -/* default base directory is /etc/subdomain.d, it can be overriden +/* default base directory is /etc/apparmor.d, it can be overriden with the -b option. */ const char *basedir; static const char *default_basedir = "/etc/apparmor.d"; -static const char *old_basedir = "/etc/subdomain.d"; /* set up basedir so that it can be overridden/used later. */ @@ -94,12 +86,6 @@ void init_base_dir(void) basedir = default_basedir; return; } - - rc = stat(old_basedir, &sbuf); - if (rc == 0 && S_ISDIR(sbuf.st_mode)) { - basedir = old_basedir; - return; - } } /* Set the base dir. Used to change default path for relative includes */ @@ -164,53 +150,9 @@ int add_search_dir(const char *dir) return 1; } -/* Parse Subdomain.conf and put the default dirs in place. - - subdomain.conf is a shell sourcable file - we only parse entries starting with - SUBDOMAIN_PATH= - - if there are multiple entries with SUBDOMAIN_PATH= - each will get added. - - SUBDOMAIN_PATH=/etc/subdomain.d:/etc/subdomain.d/include - is the same as - SUBDOMAIN_PATH=/etc/subdomain.d - SUBDOMAIN_PATH=/etc/subdomain.d/include */ void parse_default_paths(void) { - autofclose FILE *f; - char buf[1024]; - char *t, *s; - int saved_npath = npath; - - f = fopen(SUBDOMAIN_CONF, "r"); - if (f == NULL) - goto out; - - memset(buf, 0, sizeof(buf)); - - while (fgetline(f, buf, 1024)) { - if (stripcomment(buf) && (t = strstr(buf, "SUBDOMAIN_PATH="))) { - t += 15; - /* handle : separating path elements */ - do { - s = strchr(t, ':'); - if (s) - *s = 0; - if (!add_search_dir(stripblanks(t))) - break; - if (s) - t = s + 1; - } while (s != NULL); - } - } - - /* if subdomain.conf doesn't set a base search dir set it to this */ -out: - if (npath - saved_npath == 0) { - add_search_dir(basedir); - } + add_search_dir(basedir); } FILE *search_path(char *filename, char **fullpath) diff --git a/parser/rc.apparmor.functions b/parser/rc.apparmor.functions index 3a25108ec..8201a9b35 100644 --- a/parser/rc.apparmor.functions +++ b/parser/rc.apparmor.functions @@ -33,25 +33,12 @@ CONFIG_DIR=/etc/apparmor MODULE=apparmor -OLD_MODULE=subdomain if [ -f "${CONFIG_DIR}/${MODULE}.conf" ] ; then APPARMOR_CONF="${CONFIG_DIR}/${MODULE}.conf" -elif [ -f "${CONFIG_DIR}/${OLD_MODULE}.conf" ] ; then - APPARMOR_CONF="${CONFIG_DIR}/${OLD_MODULE}.conf" -elif [ -f "/etc/immunix/subdomain.conf" ] ; then - aa_log_warning_msg "/etc/immunix/subdomain.conf is deprecated, use ${CONFIG_DIR}/subdomain.conf instead" - APPARMOR_CONF="/etc/immunix/subdomain.conf" -elif [ -f "/etc/subdomain.conf" ] ; then - aa_log_warning_msg "/etc/subdomain.conf is deprecated, use ${CONFIG_DIR}/subdomain.conf instead" - APPARMOR_CONF="/etc/subdomain.conf" else aa_log_warning_msg "Unable to find config file in ${CONFIG_DIR}, installation problem?" fi -# Read configuration options from /etc/subdomain.conf, default is to -# warn if subdomain won't load. -SUBDOMAIN_MODULE_PANIC="warn" -SUBDOMAIN_ENABLE_OWLSM="no" APPARMOR_ENABLE_AAEVENTD="no" if [ -f "${APPARMOR_CONF}" ] ; then @@ -61,28 +48,18 @@ fi PARSER=/sbin/apparmor_parser -# SUBDOMAIN_DIR and APPARMOR_DIR might be defined in subdomain.conf|apparmor.conf +# APPARMOR_DIR might be defined in apparmor.conf if [ -d "${APPARMOR_DIR}" ] ; then PROFILE_DIR=${APPARMOR_DIR} -elif [ -d "${SUBDOMAIN_DIR}" ] ; then - PROFILE_DIR=${SUBDOMAIN_DIR} elif [ -d /etc/apparmor.d ] ; then PROFILE_DIR=/etc/apparmor.d -elif [ -d /etc/subdomain.d ] ; then - PROFILE_DIR=/etc/subdomain.d fi ABSTRACTIONS="-I${PROFILE_DIR}" AA_EV_BIN=/usr/sbin/aa-eventd AA_EV_PIDFILE=/var/run/aa-eventd.pid AA_STATUS=/usr/sbin/aa-status -SD_EV_BIN=/usr/sbin/sd-event-dispatch.pl -SD_EV_PIDFILE=/var/run/sd-event-dispatch.init.pid -SD_STATUS=/usr/sbin/subdomain_status SECURITYFS=/sys/kernel/security -SUBDOMAINFS_MOUNTPOINT=$(grep subdomainfs /etc/fstab | \ - sed -e 's|^[[:space:]]*[^[:space:]]\+[[:space:]]\+\(/[^[:space:]]*\)[[:space:]]\+subdomainfs.*$|\1|' 2> /dev/null) - # keep exit status from parser during profile load. 0 is good, 1 is bad STATUS=0 @@ -96,9 +73,6 @@ is_apparmor_present() { shift done - # check for subdomainfs version of module - grep -qE "^($modules)[[:space:]]" /proc/modules - [ $? -ne 0 -a -d /sys/module/apparmor ] return $? @@ -249,44 +223,17 @@ failstop_system() { return 255 } -module_panic() { - # the module failed to load, determine what action should be taken - - case "$SUBDOMAIN_MODULE_PANIC" in - "warn"|"WARN") - return 1 ;; - "panic"|"PANIC") failstop_system - rc=$? - return $rc ;; - *) aa_log_failure_msg "- invalid AppArmor module fail option" - return 255 ;; - esac -} - is_apparmor_loaded() { if ! is_securityfs_mounted ; then mount_securityfs fi - mount_subdomainfs - if [ -f "${SECURITYFS}/${MODULE}/profiles" ]; then SFS_MOUNTPOINT="${SECURITYFS}/${MODULE}" return 0 fi - if [ -f "${SECURITYFS}/${OLD_MODULE}/profiles" ]; then - SFS_MOUNTPOINT="${SECURITYFS}/${OLD_MODULE}" - return 0 - fi - - if [ -f "${SUBDOMAINFS_MOUNTPOINT}/profiles" ]; then - SFS_MOUNTPOINT=${SUBDOMAINFS_MOUNTPOINT} - return 0 - fi - - # check for subdomainfs version of module - is_apparmor_present apparmor subdomain + is_apparmor_present apparmor return $? } @@ -305,26 +252,6 @@ mount_securityfs() { return 0 } - -mount_subdomainfs() { - # for backwords compatibility - if grep -q subdomainfs /proc/filesystems && \ - ! grep -q subdomainfs /proc/mounts && \ - [ -n "${SUBDOMAINFS_MOUNTPOINT}" ]; then - aa_action "Mounting subdomainfs on ${SUBDOMAINFS_MOUNTPOINT}" \ - mount "${SUBDOMAINFS_MOUNTPOINT}" - return $? - fi - return 0 -} - -unmount_subdomainfs() { - SUBDOMAINFS=$(grep subdomainfs /proc/mounts | cut -d" " -f2 2> /dev/null) - if [ -n "${SUBDOMAINFS}" ]; then - aa_action "Unmounting subdomainfs" umount ${SUBDOMAINFS} - fi -} - apparmor_start() { aa_log_daemon_msg "Starting AppArmor" if ! is_apparmor_present ; then @@ -358,7 +285,7 @@ apparmor_start() { remove_profiles() { - # removing profiles as we directly read from subdomainfs + # removing profiles as we directly read from apparmorfs # doesn't work, since we are removing entries which screws up # our position. Lets hope there are never enough profiles to # overflow the variable @@ -406,11 +333,8 @@ apparmor_kill() { return 1 fi - unmount_subdomainfs if is_apparmor_present apparmor ; then MODULE=apparmor - elif is_apparmor_present subdomain ; then - MODULE=subdomain else aa_log_failure_msg "AppArmor is builtin" return 1 @@ -457,27 +381,11 @@ apparmor_try_restart() { return $? } -configure_owlsm () { - if [ "${SUBDOMAIN_ENABLE_OWLSM}" = "yes" -a -f ${SFS_MOUNTPOINT}/control/owlsm ] ; then - # Sigh, the "sh -c" is necessary for the SuSE aa_action - # and it can't be abstracted out as a seperate function, as - # that breaks under RedHat's action, which needs a - # binary to invoke. - aa_action "Enabling OWLSM extension" sh -c "echo -n \"1\" > \"${SFS_MOUNTPOINT}/control/owlsm\"" - elif [ -f "${SFS_MOUNTPOINT}/control/owlsm" ] ; then - aa_action "Disabling OWLSM extension" sh -c "echo -n \"0\" > \"${SFS_MOUNTPOINT}/control/owlsm\"" - fi -} - apparmor_status () { if test -x ${AA_STATUS} ; then ${AA_STATUS} --verbose return $? fi - if test -x ${SD_STATUS} ; then - ${SD_STATUS} --verbose - return $? - fi if ! is_apparmor_loaded ; then echo "AppArmor is not loaded." rc=1 diff --git a/parser/subdomain.conf b/parser/subdomain.conf deleted file mode 100644 index 20e7cab91..000000000 --- a/parser/subdomain.conf +++ /dev/null @@ -1,53 +0,0 @@ -# subdomain.conf is a shared AppArmor configuration file that is sh sourcable. - -################## AppArmor init.d configuration ################ - -# Move this to /etc/sysconfig/apparmor eventually -## Path: System/AppArmor -## Description: Enable the OWLSM extension to AppArmor -## Type: yesno -## Default: no -# -# Enable OWLSM extension to AppArmor? -# OWLSM is an extension to AppArmor that prevents processes from -# following symlinks they don't own and creating hardlinks to files they -# don't own, in an attempt to prevent /tmp race attacks. However, OWLSM -# can break some applications, so is disabled by default. -SUBDOMAIN_ENABLE_OWLSM="no" - -## Path: System/AppArmor -## Description: Enable the AppArmor event daemon for reporting -## Type: yesno -## Default: no -# -# Enable the AppArmor event daemon for reporting? -APPARMOR_ENABLE_AAEVENTD="no" - -#SUBDOMAIN_MODULE_PANIC=XXX -#This option controls how subdomain behaves when the init script attempts -#to load the AppArmor module and fails. There are 4 options -#warn - log a failure message. (default behavior) -#build - attempt to build the AppArmor module is the module can't be loaded. -# If successful -# the module will be built for the running kernel and loaded. -# If the build fails -# a failure message is logged -#panic - If the AppArmor module fails to load -# a failure message will be logged -# and the machine will drop to runlevel 1 (single user) -#build-panic - If the AppArmor module fails to load -# attempt to build the module -# If building the module fails -# panic (drop to runlevel 1) - -#SUBDOMAIN_MODULE_PANIC=warn - -################## subdomain_parser configuration ################ - -#SUBDOMAIN_PATH=XXXX -#This option specifies the include path that the subdomain_parser will -#use by default. If no entry is specified /etc/subdomain.d is used by -#default. - -#SUBDOMAIN_PATH=/etc/subdomain.d - diff --git a/parser/subdomain.conf.pod b/parser/subdomain.conf.pod deleted file mode 100644 index b38f7488c..000000000 --- a/parser/subdomain.conf.pod +++ /dev/null @@ -1,104 +0,0 @@ -# ---------------------------------------------------------------------- -# Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, -# 2008, 2009 -# NOVELL (All rights reserved) -# -# Copyright (c) 2010 - 2012 -# Canonical Ltd. (All rights reserved) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of version 2 of the GNU General Public -# License published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, contact Novell, Inc. -# ---------------------------------------------------------------------- - - -=pod - -=head1 NAME - -/etc/apparmor/subdomain.conf - configuration file for fine-tuning the -behavior of the AppArmor security tool. - -=head1 DESCRIPTION - -The AppArmor security tool can be configured to have -certain default behaviors based on configuration options set -in subdomain.conf. There are two variables that can be set in -subdomain.conf: B, and B. - -=begin comment - -FIXME keep quiet about OWLSM support for now. - -=head2 SUBDOMAIN_ENABLE_OWLSM - -This veriable is a yes/no toggle and is by default set to I. - -This variable determines whether the AppArmor initscript will enable -or disable the OWLsm security extension to AppArmor when the AppArmor -security tool is started. When enabled the OWLsm feature prevents programs -from following symlinks in temporary directories that are not owned by -the program's UID, and prevents processes from creating hardlinks to -files not owned by their UID. - -=end comment - -=head2 SUBDOMAIN_PATH - -This variable accepts a string (path), and is by default set to -'/etc/apparmor.d/' This variable defines where the AppArmor security -tool looks for its policy definitions (a.k.a. AppArmor profiles). - -=head2 SUBDOMAIN_MODULE_PANIC - -This variable accepts a string that is one of four values: I, -I, I, or I, and is set by default to I. - -This setting controls the behavior of the AppArmor initscript if it -cannot successfully load the AppArmor kernel module on startup. The four -possible settings are: - -=over 4 - -=item I - -Log a failure message (the default behavior). - -=item I - -Attempt to build the AppArmor module against the currently running -kernel. If the compilation is successful, the module will be loaded and -AppArmor started; if the compilation fails, a failure message is logged. - -=item I - -Log a failure message and drop to runlevel 1 (single user). - -=item I - -Attempt to build the module against the running kernel (like I) -and if the compilation fails, drop to runlevel 1 (single user). - -=back - -=head1 BUGS - -Setting the initscript to recompile the module will fail on SUSE, as the -module source is no longer installed by default. However, the module has -been included with the SUSE kernel, so no rebuilding should be necessary. - -If you find any additional bugs, please report them at -L. - -=head1 SEE ALSO - -apparmor(7), apparmor_parser(8), and -L. diff --git a/tests/stress/subdomain/Makefile b/tests/stress/apparmor/Makefile similarity index 100% rename from tests/stress/subdomain/Makefile rename to tests/stress/apparmor/Makefile diff --git a/tests/stress/subdomain/change_hat.c b/tests/stress/apparmor/change_hat.c similarity index 100% rename from tests/stress/subdomain/change_hat.c rename to tests/stress/apparmor/change_hat.c diff --git a/tests/stress/subdomain/change_hat.profile.pre b/tests/stress/apparmor/change_hat.profile.pre similarity index 100% rename from tests/stress/subdomain/change_hat.profile.pre rename to tests/stress/apparmor/change_hat.profile.pre diff --git a/tests/stress/subdomain/child.c b/tests/stress/apparmor/child.c similarity index 100% rename from tests/stress/subdomain/child.c rename to tests/stress/apparmor/child.c diff --git a/tests/stress/subdomain/child.profile.pre b/tests/stress/apparmor/child.profile.pre similarity index 100% rename from tests/stress/subdomain/child.profile.pre rename to tests/stress/apparmor/child.profile.pre diff --git a/tests/stress/subdomain/kill.sh b/tests/stress/apparmor/kill.sh similarity index 100% rename from tests/stress/subdomain/kill.sh rename to tests/stress/apparmor/kill.sh diff --git a/tests/stress/subdomain/open.c b/tests/stress/apparmor/open.c similarity index 100% rename from tests/stress/subdomain/open.c rename to tests/stress/apparmor/open.c diff --git a/tests/stress/subdomain/open.profile.pre b/tests/stress/apparmor/open.profile.pre similarity index 100% rename from tests/stress/subdomain/open.profile.pre rename to tests/stress/apparmor/open.profile.pre diff --git a/tests/stress/subdomain/s-2.4.20.sh b/tests/stress/apparmor/s-2.4.20.sh similarity index 100% rename from tests/stress/subdomain/s-2.4.20.sh rename to tests/stress/apparmor/s-2.4.20.sh diff --git a/tests/stress/subdomain/s.sh b/tests/stress/apparmor/s.sh similarity index 100% rename from tests/stress/subdomain/s.sh rename to tests/stress/apparmor/s.sh diff --git a/tests/stress/subdomain/sh.profile.pre b/tests/stress/apparmor/sh.profile.pre similarity index 100% rename from tests/stress/subdomain/sh.profile.pre rename to tests/stress/apparmor/sh.profile.pre diff --git a/tests/stress/subdomain/stress.sh b/tests/stress/apparmor/stress.sh similarity index 100% rename from tests/stress/subdomain/stress.sh rename to tests/stress/apparmor/stress.sh diff --git a/tests/stress/subdomain/stress.sh-2.4.20 b/tests/stress/apparmor/stress.sh-2.4.20 similarity index 100% rename from tests/stress/subdomain/stress.sh-2.4.20 rename to tests/stress/apparmor/stress.sh-2.4.20 diff --git a/tests/stress/subdomain/uservars.inc b/tests/stress/apparmor/uservars.inc similarity index 100% rename from tests/stress/subdomain/uservars.inc rename to tests/stress/apparmor/uservars.inc diff --git a/utils/apparmor/config.py b/utils/apparmor/config.py index 64334c9b7..b8fcc0d38 100644 --- a/utils/apparmor/config.py +++ b/utils/apparmor/config.py @@ -40,7 +40,7 @@ from apparmor.common import AppArmorException, open_file_read # , warn, msg, # CFG = None # REPO_CFG = None -# SHELL_FILES = ['easyprof.conf', 'notify.conf', 'parser.conf', 'subdomain.conf'] +# SHELL_FILES = ['easyprof.conf', 'notify.conf', 'parser.conf'] class Config(object): def __init__(self, conf_type, conf_dir='/etc/apparmor'): self.CONF_DIR = conf_dir From 3a89e9811f7ee56172a008dbea1deecb1ac533b1 Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Fri, 9 Nov 2018 17:22:17 +0100 Subject: [PATCH 16/46] Remove traces of aa-eventd aa-eventd and its initscripts have been moved to deprecated/ in 2014 and didn't get any serious updates for several more years, so it's most probably useless and/or broken nowadays. This also means we don't need to keep the AA_EV_BIN and AA_EV_PIDFILE variables in rc.apparmor.functions anymore. --- parser/rc.apparmor.functions | 2 -- 1 file changed, 2 deletions(-) diff --git a/parser/rc.apparmor.functions b/parser/rc.apparmor.functions index 8201a9b35..17854f82f 100644 --- a/parser/rc.apparmor.functions +++ b/parser/rc.apparmor.functions @@ -55,8 +55,6 @@ elif [ -d /etc/apparmor.d ] ; then PROFILE_DIR=/etc/apparmor.d fi ABSTRACTIONS="-I${PROFILE_DIR}" -AA_EV_BIN=/usr/sbin/aa-eventd -AA_EV_PIDFILE=/var/run/aa-eventd.pid AA_STATUS=/usr/sbin/aa-status SECURITYFS=/sys/kernel/security From 2809060bec4a6511e84f5d7cbc80079c1cdc92a8 Mon Sep 17 00:00:00 2001 From: John Johansen Date: Sat, 20 Oct 2018 15:59:51 -0700 Subject: [PATCH 17/46] parser: limit the number of passes expr tree simplification does Expr tree simplification makes multiple passes at simplifying the expression tree trying to use fatoring rules and heuristics to achieve the minimum tree, so that dfa construction has fewer nodes to deal with. Unfortunately expr tree simplification can slow some policy compiles, dependent on the type of expressions generated, down, and even worse is currently subject to never terminating on some expressions as the left and right passes keep undoing each others work. Limiting the number of passes that expr tree simplification does can provide most of its benefits (later passes generally have diminishing returns), reduces the overhead it has on simple policy where it is of little benefit, and insures that simplifications can not get stuck in an infinite loop due to the left and right passes ping-ponging on each others factoring. Note: This also results in a performance improvement in evince compiles, and general policy compiles because it achieves a better balance between time spent on simplifying the tree to remove nodes and time the dfa build requires to build with extra nodes and then eliminate with minimization. $ time apparmor_parser -QT /etc/apparmor.d/usr.bin.evince real 0m2.744s user 0m2.714s sys 0m0.028s vs. $ time apparmor_parser -QT /etc/apparmor.d/usr.bin.evince real 0m2.992s user 0m2.979s sys 0m0.012s and $ time apparmor_parser -QT /etc/apparmor.d/ real 0m3.568s user 0m14.529s sys 0m0.152s vs. $ time apparmor_parser -QT /etc/apparmor.d/ real 0m3.741s user 0m15.400s sys 0m0.179s PR: https://gitlab.com/apparmor/apparmor/merge_requests/246 Signed-off-by: John Johansen Acked-by: Seth Arnold --- parser/libapparmor_re/expr-tree.cc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/parser/libapparmor_re/expr-tree.cc b/parser/libapparmor_re/expr-tree.cc index a80f9037f..69c24a072 100644 --- a/parser/libapparmor_re/expr-tree.cc +++ b/parser/libapparmor_re/expr-tree.cc @@ -549,9 +549,14 @@ static void count_tree_nodes(Node *t, struct node_counts *counts) #include "stdint.h" #include "apparmor_re.h" +// maximum number of passes to iterate on the expression tree doing +// simplification passes. Simplification may exit sooner if no changes +// are made. +#define MAX_PASSES 1 Node *simplify_tree(Node *t, dfaflags_t flags) { - bool update; + bool update = true; + int i; if (flags & DFA_DUMP_TREE_STATS) { struct node_counts counts = { 0, 0, 0, 0, 0, 0, 0, 0 }; @@ -562,7 +567,7 @@ Node *simplify_tree(Node *t, dfaflags_t flags) counts.alt, counts.plus, counts.star, counts.any, counts.cat); } - do { + for (i = 0; update && i < MAX_PASSES; i++) { update = false; //default to right normalize first as this reduces the number //of trailing nodes which might follow an internal * @@ -588,7 +593,7 @@ Node *simplify_tree(Node *t, dfaflags_t flags) else dir--; } - } while (update); + } if (flags & DFA_DUMP_TREE_STATS) { struct node_counts counts = { 0, 0, 0, 0, 0, 0, 0, 0 }; count_tree_nodes(t, &counts); From 7ba8dc7e2efece9358024ecd5ab3ae23f119530a Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Mon, 12 Nov 2018 15:51:15 +0100 Subject: [PATCH 18/46] Drop APPARMOR_ENABLE_AAEVENTD This is another trace of aa-eventd which is deprecated since years. --- parser/rc.apparmor.functions | 2 -- 1 file changed, 2 deletions(-) diff --git a/parser/rc.apparmor.functions b/parser/rc.apparmor.functions index 17854f82f..410a94239 100644 --- a/parser/rc.apparmor.functions +++ b/parser/rc.apparmor.functions @@ -39,8 +39,6 @@ else aa_log_warning_msg "Unable to find config file in ${CONFIG_DIR}, installation problem?" fi -APPARMOR_ENABLE_AAEVENTD="no" - if [ -f "${APPARMOR_CONF}" ] ; then #parse the conf file to see what we should do . "${APPARMOR_CONF}" From 4efff35bf8991fcdda3f16e65a036826b9b5cf5f Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Tue, 13 Nov 2018 17:53:49 +0100 Subject: [PATCH 19/46] parse_profile_data(): Ensure last line in a profile is valid 'lastline' gets merged into 'line' (and reset to None) when reading the next line. If 'lastline' isn't empty after reading the whole profile, this means there's something unparseable at the end of the profile, therefore parse_profile_data() should error out. Also remove some simple_tests testcases from the 'exception_not_raised' list - they only didn't raise the exception because the invalid rule was the last line in the affected profile. Thanks to Eric Chiang for accidently (and maybe even unnoticedly ;-) discovering this bug while adding some xattr testcases that surprisingly didn't fail in the tools. --- utils/apparmor/aa.py | 5 +++++ utils/test/test-parser-simple-tests.py | 10 ---------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/utils/apparmor/aa.py b/utils/apparmor/aa.py index 30ad07af3..fd44c8092 100644 --- a/utils/apparmor/aa.py +++ b/utils/apparmor/aa.py @@ -2544,6 +2544,11 @@ def parse_profile_data(data, file, do_include): else: raise AppArmorException(_('Syntax Error: Unknown line found in file %(file)s line %(lineno)s:\n %(line)s') % { 'file': file, 'lineno': lineno + 1, 'line': line }) + if lastline: + # lastline gets merged into line (and reset to None) when reading the next line. + # If it isn't empty, this means there's something unparseable at the end of the profile + raise AppArmorException(_('Syntax Error: Unknown line found in file %(file)s line %(lineno)s:\n %(line)s') % { 'file': file, 'lineno': lineno + 1, 'line': lastline }) + # Below is not required I'd say if not do_include: for hatglob in cfg['required_hats'].keys(): diff --git a/utils/test/test-parser-simple-tests.py b/utils/test/test-parser-simple-tests.py index cee6e2529..19453d641 100644 --- a/utils/test/test-parser-simple-tests.py +++ b/utils/test/test-parser-simple-tests.py @@ -40,11 +40,6 @@ skip_startswith = ( # testcases that should raise an exception, but don't exception_not_raised = [ # most abi/bad_* aren't detected as bad by the basic implementation in the tools - 'abi/bad_1.sd', - 'abi/bad_2.sd', - 'abi/bad_3.sd', - 'abi/bad_4.sd', - 'abi/bad_5.sd', 'abi/bad_10.sd', 'abi/bad_11.sd', 'abi/bad_12.sd', @@ -155,13 +150,9 @@ exception_not_raised = [ 'unix/bad_regex_04.sd', 'unix/bad_shutdown_1.sd', 'unix/bad_shutdown_2.sd', - 'vars/boolean/boolean_bad_1.sd', 'vars/boolean/boolean_bad_2.sd', 'vars/boolean/boolean_bad_3.sd', 'vars/boolean/boolean_bad_4.sd', - 'vars/boolean/boolean_bad_6.sd', - 'vars/boolean/boolean_bad_7.sd', - 'vars/boolean/boolean_bad_8.sd', 'vars/vars_bad_3.sd', 'vars/vars_bad_4.sd', 'vars/vars_bad_5.sd', @@ -200,7 +191,6 @@ exception_not_raised = [ 'vars/vars_recursion_2.sd', 'vars/vars_recursion_3.sd', 'vars/vars_recursion_4.sd', - 'vars/vars_simple_assignment_10.sd', 'vars/vars_simple_assignment_3.sd', 'vars/vars_simple_assignment_8.sd', 'vars/vars_simple_assignment_9.sd', From 7496fad27ff7cc75f0ef2ce8271ff6d80cc4a545 Mon Sep 17 00:00:00 2001 From: Steve Beattie Date: Fri, 16 Nov 2018 10:42:07 -0800 Subject: [PATCH 20/46] tests: fix make clean target Make the tests/stress 'make clean' target cope with the rename from subdomain to apparmor. Signed-off-by: Steve Beattie --- tests/stress/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/stress/Makefile b/tests/stress/Makefile index e7bef13df..fb756f20f 100644 --- a/tests/stress/Makefile +++ b/tests/stress/Makefile @@ -1,4 +1,4 @@ -SUBDIRS=subdomain +SUBDIRS=apparmor .PHONY: clean clean: From 04c91d5256e199553cda67b2f81a981bf2e1f795 Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Sun, 18 Nov 2018 17:20:30 +0100 Subject: [PATCH 21/46] Drop unused activate_repo_profiles() --- utils/apparmor/aa.py | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/utils/apparmor/aa.py b/utils/apparmor/aa.py index fd44c8092..8686cc7fb 100644 --- a/utils/apparmor/aa.py +++ b/utils/apparmor/aa.py @@ -573,21 +573,6 @@ def get_profile(prof_name): profile_data = parse_repo_profile(prof_name, repo_url, p) return profile_data -def activate_repo_profiles(url, profiles, complain): - read_profiles() - try: - for p in profiles: - pname = p[0] - profile_data = parse_repo_profile(pname, url, p[1]) - attach_profile_data(aa, profile_data) - write_profile(pname) - if complain: - fname = get_profile_filename_from_profile_name(pname, True) - change_profile_flags(profile_dir + fname, None, 'complain', True) - aaui.UI_Info(_('Setting %s to complain mode.') % pname) - except Exception as e: - sys.stderr.write(_("Error activating profiles: %s") % e) - def autodep(bin_name, pname=''): bin_full = None global repo_cfg From 8b4e76a7d5d87cafb964faa87368dd2b6842f4b8 Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Sun, 18 Nov 2018 20:09:21 +0100 Subject: [PATCH 22/46] Fix viewing a local inactive profile in aa-genprof aa-genprof checks if one of the profiles in the extra profile dir matches the binary, and proposes to use that profile as a starting point. Since 4d722f18397dd35b208548d4c841b955c41ac7ce the "(V)iew profile" option to display the proposed profile was broken. The easiest fix is to remember the filename in the extras directory, and display the file from there. Sidenote: when choosing to use the extra profile, it gets written to disk without any problems, so this bug really only affected "(V)iew profile" to preview the proposed extra profile. --- utils/apparmor/aa.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/utils/apparmor/aa.py b/utils/apparmor/aa.py index fd44c8092..16d6b75ea 100644 --- a/utils/apparmor/aa.py +++ b/utils/apparmor/aa.py @@ -519,6 +519,7 @@ def get_profile(prof_name): if inactive_profile: uname = 'Inactive local profile for %s' % prof_name inactive_profile[prof_name][prof_name]['flags'] = 'complain' + orig_filename = inactive_profile[prof_name][prof_name]['filename'] # needed for CMD_VIEW_PROFILE inactive_profile[prof_name][prof_name]['filename'] = '' profile_hash[uname]['username'] = uname profile_hash[uname]['profile_type'] = 'INACTIVE_LOCAL' @@ -560,11 +561,7 @@ def get_profile(prof_name): q.selected = options.index(options[arg]) if ans == 'CMD_VIEW_PROFILE': pager = get_pager() - proc = subprocess.Popen(pager, stdin=subprocess.PIPE) - # proc.communicate('Profile submitted by %s:\n\n%s\n\n' % - # (options[arg], p['profile'])) - proc.communicate(p['profile'].encode()) - proc.kill() + subprocess.call([pager, orig_filename]) elif ans == 'CMD_USE_PROFILE': if p['profile_type'] == 'INACTIVE_LOCAL': profile_data = p['profile_data'] From 170e8d6ac8eb867d40f3361e1814b2304d647860 Mon Sep 17 00:00:00 2001 From: Jamie Strandboge Date: Mon, 19 Nov 2018 16:13:57 -0600 Subject: [PATCH 23/46] deny ~/.mutt** in private-files and audit deny ~/.aws in private-files-strict Signed-Off-By: Jamie Strandboge --- profiles/apparmor.d/abstractions/private-files | 1 + profiles/apparmor.d/abstractions/private-files-strict | 1 + 2 files changed, 2 insertions(+) diff --git a/profiles/apparmor.d/abstractions/private-files b/profiles/apparmor.d/abstractions/private-files index 0a659f132..09f6d9bdc 100644 --- a/profiles/apparmor.d/abstractions/private-files +++ b/profiles/apparmor.d/abstractions/private-files @@ -6,6 +6,7 @@ # lot of false positives when reading contents of directories) deny @{HOME}/.*history mrwkl, deny @{HOME}/.fetchmail* mrwkl, + deny @{HOME}/.mutt** mrwkl, deny @{HOME}/.viminfo* mrwkl, deny @{HOME}/.*~ mrwkl, deny @{HOME}/.*.swp mrwkl, diff --git a/profiles/apparmor.d/abstractions/private-files-strict b/profiles/apparmor.d/abstractions/private-files-strict index 60ea72a06..31934318f 100644 --- a/profiles/apparmor.d/abstractions/private-files-strict +++ b/profiles/apparmor.d/abstractions/private-files-strict @@ -5,6 +5,7 @@ #include # potentially extremely sensitive files + audit deny @{HOME}/.aws/{,**} mrwkl, audit deny @{HOME}/.gnupg/{,**} mrwkl, audit deny @{HOME}/.ssh/{,**} mrwkl, audit deny @{HOME}/.gnome2_private/{,**} mrwkl, From 228b92ce5ab287aad76954751cb5e8fb2ea8ce4d Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Wed, 28 Nov 2018 22:50:09 +0100 Subject: [PATCH 24/46] Ignore *.orig and *.rej files when loading profiles or: get rc.apparmor.functions in sync with the tools and libapparmor. This was "accidently" reported by Ralph on the opensuse-support mailinglist. --- parser/rc.apparmor.functions | 2 ++ 1 file changed, 2 insertions(+) diff --git a/parser/rc.apparmor.functions b/parser/rc.apparmor.functions index 410a94239..7b606bc28 100644 --- a/parser/rc.apparmor.functions +++ b/parser/rc.apparmor.functions @@ -83,6 +83,8 @@ skip_profile() { local profile=$1 if [ "${profile%.rpmnew}" != "${profile}" -o \ "${profile%.rpmsave}" != "${profile}" -o \ + "${profile%.orig}" != "${profile}" -o \ + "${profile%.rej}" != "${profile}" -o \ -e "${PROFILE_DIR}/disable/`basename ${profile}`" -o \ "${profile%\~}" != "${profile}" ] ; then return 1 From 01648c6a61519a01d5bf54270c3a75557f1cb5cb Mon Sep 17 00:00:00 2001 From: Steve Beattie Date: Sun, 25 Mar 2018 22:02:54 -0700 Subject: [PATCH 25/46] profiles/postfix-master: use profile name instead of match pattern Convert postfix's master profile to use a named profile (postfix-master) rather than the exec path match pattern. Adjust postfix-common abstraction to take this into account. Rename profile name in the profiles/apparmor/profiles/extras/ directory to match the profile name. Signed-off-by: Steve Beattie --- profiles/apparmor.d/abstractions/postfix-common | 6 +++--- .../extras/{usr.lib.postfix.master => postfix.master} | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) rename profiles/apparmor/profiles/extras/{usr.lib.postfix.master => postfix.master} (92%) diff --git a/profiles/apparmor.d/abstractions/postfix-common b/profiles/apparmor.d/abstractions/postfix-common index 86e38880e..ab5210504 100644 --- a/profiles/apparmor.d/abstractions/postfix-common +++ b/profiles/apparmor.d/abstractions/postfix-common @@ -1,7 +1,7 @@ # ------------------------------------------------------------------ # # Copyright (C) 2002-2005 Novell/SUSE -# Copyright (C) 2015 Canonical, Ltd. +# Copyright (C) 2015-2018 Canonical, Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -16,9 +16,9 @@ capability sys_chroot, # postfix's master can send us signals - signal receive peer=/usr/lib/postfix/master, + signal receive peer=postfix-master, - unix (send, receive) peer=(label=/usr/lib/postfix/master), + unix (send, receive) peer=(label=postfix-master), /etc/mailname r, /etc/postfix/*.cf r, diff --git a/profiles/apparmor/profiles/extras/usr.lib.postfix.master b/profiles/apparmor/profiles/extras/postfix.master similarity index 92% rename from profiles/apparmor/profiles/extras/usr.lib.postfix.master rename to profiles/apparmor/profiles/extras/postfix.master index c0f9c5490..377e772fb 100644 --- a/profiles/apparmor/profiles/extras/usr.lib.postfix.master +++ b/profiles/apparmor/profiles/extras/postfix.master @@ -1,6 +1,7 @@ # ------------------------------------------------------------------ # # Copyright (C) 2002-2006 Novell/SUSE +# Copyright (C) 2018 Canonical, Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -10,7 +11,7 @@ #include -/usr/lib/postfix/master { +profile postfix-master /usr/lib/postfix/{sbin/,}master { #include #include #include @@ -30,7 +31,7 @@ /usr/lib/postfix/cleanup Px, /usr/lib/postfix/flush Px, /usr/lib/postfix/local Px, - /usr/lib/postfix/master rmix, + /usr/lib/postfix/{sbin/,}master rmix, /usr/lib/postfix/nqmgr Px, /usr/lib/postfix/proxymap Px, /usr/lib/postfix/pickup Px, From 39ca2adff651aff52b951e194507b4216c7d67e6 Mon Sep 17 00:00:00 2001 From: Steve Beattie Date: Sun, 25 Mar 2018 22:17:15 -0700 Subject: [PATCH 26/46] profiles/postfix: use named profiles Convert all the postfix subprocesses to using named profiles instead of path match profiles, and adjust exec paths for newer debian/ubuntu releses. Rename profiles to match profile names. Signed-off-by: Steve Beattie --- .../extras/{usr.lib.postfix.anvil => postfix.anvil} | 5 +++-- .../extras/{usr.lib.postfix.bounce => postfix.bounce} | 5 +++-- .../extras/{usr.lib.postfix.cleanup => postfix.cleanup} | 5 +++-- .../extras/{usr.lib.postfix.discard => postfix.discard} | 5 +++-- .../extras/{usr.lib.postfix.error => postfix.error} | 6 ++++-- .../extras/{usr.lib.postfix.flush => postfix.flush} | 5 +++-- .../profiles/extras/{usr.lib.postfix.lmtp => postfix.lmtp} | 6 ++++-- .../extras/{usr.lib.postfix.local => postfix.local} | 5 +++-- .../extras/{usr.lib.postfix.nqmgr => postfix.nqmgr} | 5 +++-- .../extras/{usr.lib.postfix.oqmgr => postfix.oqmgr} | 5 +++-- .../extras/{usr.lib.postfix.pickup => postfix.pickup} | 5 +++-- .../profiles/extras/{usr.lib.postfix.pipe => postfix.pipe} | 6 ++++-- .../extras/{usr.lib.postfix.proxymap => postfix.proxymap} | 5 +++-- .../profiles/extras/{usr.lib.postfix.qmgr => postfix.qmgr} | 6 ++++-- .../extras/{usr.lib.postfix.qmqpd => postfix.qmqpd} | 5 +++-- .../extras/{usr.lib.postfix.scache => postfix.scache} | 5 +++-- .../extras/{usr.lib.postfix.showq => postfix.showq} | 5 +++-- .../profiles/extras/{usr.lib.postfix.smtp => postfix.smtp} | 5 +++-- .../extras/{usr.lib.postfix.smtpd => postfix.smtpd} | 5 +++-- .../extras/{usr.lib.postfix.verify => postfix.spawn} | 5 +++-- .../extras/{usr.lib.postfix.tlsmgr => postfix.tlsmgr} | 5 +++-- ....lib.postfix.trivial-rewrite => postfix.trivial-rewrite} | 5 +++-- .../extras/{usr.lib.postfix.spawn => postfix.verify} | 5 +++-- .../extras/{usr.lib.postfix.virtual => postfix.virtual} | 6 ++++-- 24 files changed, 77 insertions(+), 48 deletions(-) rename profiles/apparmor/profiles/extras/{usr.lib.postfix.anvil => postfix.anvil} (83%) rename profiles/apparmor/profiles/extras/{usr.lib.postfix.bounce => postfix.bounce} (92%) rename profiles/apparmor/profiles/extras/{usr.lib.postfix.cleanup => postfix.cleanup} (87%) rename profiles/apparmor/profiles/extras/{usr.lib.postfix.discard => postfix.discard} (76%) rename profiles/apparmor/profiles/extras/{usr.lib.postfix.error => postfix.error} (84%) rename profiles/apparmor/profiles/extras/{usr.lib.postfix.flush => postfix.flush} (91%) rename profiles/apparmor/profiles/extras/{usr.lib.postfix.lmtp => postfix.lmtp} (82%) rename profiles/apparmor/profiles/extras/{usr.lib.postfix.local => postfix.local} (91%) rename profiles/apparmor/profiles/extras/{usr.lib.postfix.nqmgr => postfix.nqmgr} (93%) rename profiles/apparmor/profiles/extras/{usr.lib.postfix.oqmgr => postfix.oqmgr} (80%) rename profiles/apparmor/profiles/extras/{usr.lib.postfix.pickup => postfix.pickup} (83%) rename profiles/apparmor/profiles/extras/{usr.lib.postfix.pipe => postfix.pipe} (84%) rename profiles/apparmor/profiles/extras/{usr.lib.postfix.proxymap => postfix.proxymap} (81%) rename profiles/apparmor/profiles/extras/{usr.lib.postfix.qmgr => postfix.qmgr} (93%) rename profiles/apparmor/profiles/extras/{usr.lib.postfix.qmqpd => postfix.qmqpd} (79%) rename profiles/apparmor/profiles/extras/{usr.lib.postfix.scache => postfix.scache} (81%) rename profiles/apparmor/profiles/extras/{usr.lib.postfix.showq => postfix.showq} (93%) rename profiles/apparmor/profiles/extras/{usr.lib.postfix.smtp => postfix.smtp} (92%) rename profiles/apparmor/profiles/extras/{usr.lib.postfix.smtpd => postfix.smtpd} (93%) rename profiles/apparmor/profiles/extras/{usr.lib.postfix.verify => postfix.spawn} (79%) rename profiles/apparmor/profiles/extras/{usr.lib.postfix.tlsmgr => postfix.tlsmgr} (83%) rename profiles/apparmor/profiles/extras/{usr.lib.postfix.trivial-rewrite => postfix.trivial-rewrite} (82%) rename profiles/apparmor/profiles/extras/{usr.lib.postfix.spawn => postfix.verify} (79%) rename profiles/apparmor/profiles/extras/{usr.lib.postfix.virtual => postfix.virtual} (82%) diff --git a/profiles/apparmor/profiles/extras/usr.lib.postfix.anvil b/profiles/apparmor/profiles/extras/postfix.anvil similarity index 83% rename from profiles/apparmor/profiles/extras/usr.lib.postfix.anvil rename to profiles/apparmor/profiles/extras/postfix.anvil index dc5c63bfa..69c579c67 100644 --- a/profiles/apparmor/profiles/extras/usr.lib.postfix.anvil +++ b/profiles/apparmor/profiles/extras/postfix.anvil @@ -1,6 +1,7 @@ # ------------------------------------------------------------------ # # Copyright (C) 2002-2006 Novell/SUSE +# Copyright (C) 2018 Canonical, Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -10,7 +11,7 @@ #include -/usr/lib/postfix/anvil { +profile postfix-anvil /usr/lib/postfix/{sbin/,}anvil { #include #include #include @@ -18,7 +19,7 @@ capability setgid, capability setuid, - /usr/lib/postfix/anvil rmix, + /usr/lib/postfix/{sbin/,}anvil rmix, /etc/postfix/main.cf r, /{var/spool/postfix/,}private/anvil rw, diff --git a/profiles/apparmor/profiles/extras/usr.lib.postfix.bounce b/profiles/apparmor/profiles/extras/postfix.bounce similarity index 92% rename from profiles/apparmor/profiles/extras/usr.lib.postfix.bounce rename to profiles/apparmor/profiles/extras/postfix.bounce index 70a6f65aa..094b1924a 100644 --- a/profiles/apparmor/profiles/extras/usr.lib.postfix.bounce +++ b/profiles/apparmor/profiles/extras/postfix.bounce @@ -1,6 +1,7 @@ # ------------------------------------------------------------------ # # Copyright (C) 2002-2006 Novell/SUSE +# Copyright (C) 2018 Canonical, Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -10,7 +11,7 @@ #include -/usr/lib/postfix/bounce { +profile postfix-bounce /usr/lib/postfix/{sbin/,}bounce { #include #include #include @@ -18,7 +19,7 @@ capability setgid, capability setuid, - /usr/lib/postfix/bounce rmix, + /usr/lib/postfix/{sbin/,}bounce rmix, /{var/spool/postfix/,}active/[0-9A-F]/[0-9A-F]/* rwl, /{var/spool/postfix/,}active/[0-9A-F]/[0-9A-F]/ rwl, diff --git a/profiles/apparmor/profiles/extras/usr.lib.postfix.cleanup b/profiles/apparmor/profiles/extras/postfix.cleanup similarity index 87% rename from profiles/apparmor/profiles/extras/usr.lib.postfix.cleanup rename to profiles/apparmor/profiles/extras/postfix.cleanup index a01b37e09..9f20836f6 100644 --- a/profiles/apparmor/profiles/extras/usr.lib.postfix.cleanup +++ b/profiles/apparmor/profiles/extras/postfix.cleanup @@ -1,6 +1,7 @@ # ------------------------------------------------------------------ # # Copyright (C) 2002-2006 Novell/SUSE +# Copyright (C) 2018 Canonical, Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -10,14 +11,14 @@ #include -/usr/lib/postfix/cleanup { +profile postfix-cleanup /usr/lib/postfix/{sbin/,}cleanup { #include #include #include capability net_bind_service, - /usr/lib/postfix/cleanup rmix, + /usr/lib/postfix/{sbin/,}cleanup rmix, /{var/spool/postfix/,}incoming/[0-9]*.[0-9]* rwl, /{var/spool/postfix/,}incoming/[0-9A-F]/[0-9A-F]/* rwl, diff --git a/profiles/apparmor/profiles/extras/usr.lib.postfix.discard b/profiles/apparmor/profiles/extras/postfix.discard similarity index 76% rename from profiles/apparmor/profiles/extras/usr.lib.postfix.discard rename to profiles/apparmor/profiles/extras/postfix.discard index 17e2add6b..b695bacbc 100644 --- a/profiles/apparmor/profiles/extras/usr.lib.postfix.discard +++ b/profiles/apparmor/profiles/extras/postfix.discard @@ -1,6 +1,7 @@ # ------------------------------------------------------------------ # # Copyright (C) 2002-2005 Novell/SUSE +# Copyright (C) 2018 Canonical, Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -11,8 +12,8 @@ #include -/usr/lib/postfix/discard { +profile postfix-discard /usr/lib/postfix/{sbin/,}discard { #include - /usr/lib/postfix/discard rmix, + /usr/lib/postfix/{sbin/,}discard rmix, } diff --git a/profiles/apparmor/profiles/extras/usr.lib.postfix.error b/profiles/apparmor/profiles/extras/postfix.error similarity index 84% rename from profiles/apparmor/profiles/extras/usr.lib.postfix.error rename to profiles/apparmor/profiles/extras/postfix.error index 3942c146c..0f6370a35 100644 --- a/profiles/apparmor/profiles/extras/usr.lib.postfix.error +++ b/profiles/apparmor/profiles/extras/postfix.error @@ -2,6 +2,7 @@ # # Copyright (C) 2002-2006 Novell/SUSE # Copyright (C) 2017 Christian Boltz +# Copyright (C) 2018 Canonical, Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -11,13 +12,14 @@ #include -/usr/lib/postfix/error { +profile postfix-error /usr/lib/postfix/{sbin/,}error { #include #include #include + /usr/lib/postfix/{sbin/,}error rmix, + @{PROC}/sys/kernel/ngroups_max r, - /usr/lib/postfix/error mrix, owner /var/spool/postfix/active/* rwk, /var/spool/postfix/pid/unix.error rwk, /var/spool/postfix/pid/unix.retry rwk, diff --git a/profiles/apparmor/profiles/extras/usr.lib.postfix.flush b/profiles/apparmor/profiles/extras/postfix.flush similarity index 91% rename from profiles/apparmor/profiles/extras/usr.lib.postfix.flush rename to profiles/apparmor/profiles/extras/postfix.flush index f3d1c3fa2..ffbfb4798 100644 --- a/profiles/apparmor/profiles/extras/usr.lib.postfix.flush +++ b/profiles/apparmor/profiles/extras/postfix.flush @@ -1,6 +1,7 @@ # ------------------------------------------------------------------ # # Copyright (C) 2002-2006 Novell/SUSE +# Copyright (C) 2018 Canonical, Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -10,7 +11,7 @@ #include -/usr/lib/postfix/flush { +profile postfix-flush /usr/lib/postfix/{sbin/,}flush { #include #include #include @@ -18,7 +19,7 @@ capability setgid, capability setuid, - /usr/lib/postfix/flush rmix, + /usr/lib/postfix/{sbin/,}flush rmix, /{var/spool/postfix/,}deferred/ r, /{var/spool/postfix/,}deferred/[0-9A-F]/[0-9A-F]/* rwl, diff --git a/profiles/apparmor/profiles/extras/usr.lib.postfix.lmtp b/profiles/apparmor/profiles/extras/postfix.lmtp similarity index 82% rename from profiles/apparmor/profiles/extras/usr.lib.postfix.lmtp rename to profiles/apparmor/profiles/extras/postfix.lmtp index ab7fc2f14..867d9d603 100644 --- a/profiles/apparmor/profiles/extras/usr.lib.postfix.lmtp +++ b/profiles/apparmor/profiles/extras/postfix.lmtp @@ -2,6 +2,7 @@ # # Copyright (C) 2002-2006 Novell/SUSE # Copyright (C) 2017 Christian Boltz +# Copyright (C) 2018 Canonical, Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -11,12 +12,13 @@ #include -/usr/lib/postfix/lmtp { +profile postfix-lmtp /usr/lib/postfix/{sbin/,}lmtp { #include #include #include - /usr/lib/postfix/lmtp mrix, + /usr/lib/postfix/{sbin/,}lmtp rmix, + /var/spool/postfix/active/* rwk, /var/spool/postfix/pid/unix.lmtp rwk, diff --git a/profiles/apparmor/profiles/extras/usr.lib.postfix.local b/profiles/apparmor/profiles/extras/postfix.local similarity index 91% rename from profiles/apparmor/profiles/extras/usr.lib.postfix.local rename to profiles/apparmor/profiles/extras/postfix.local index 71296ee6f..d4484b121 100644 --- a/profiles/apparmor/profiles/extras/usr.lib.postfix.local +++ b/profiles/apparmor/profiles/extras/postfix.local @@ -1,6 +1,7 @@ # ------------------------------------------------------------------ # # Copyright (C) 2002-2006 Novell/SUSE +# Copyright (C) 2018 Canonical, Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -10,7 +11,7 @@ #include -/usr/lib/postfix/local { +profile postfix-local /usr/lib/postfix/{sbin/,}local { #include #include #include @@ -23,7 +24,7 @@ /var/mailman/mail/wrapper Px, /usr/bin/mlmmj-recieve Px, - /usr/lib/postfix/local rmix, + /usr/lib/postfix/{sbin/,}local rmix, /{usr/,}bin/bash mixr, /{usr/,}bin/date mixr, diff --git a/profiles/apparmor/profiles/extras/usr.lib.postfix.nqmgr b/profiles/apparmor/profiles/extras/postfix.nqmgr similarity index 93% rename from profiles/apparmor/profiles/extras/usr.lib.postfix.nqmgr rename to profiles/apparmor/profiles/extras/postfix.nqmgr index e892a8932..6ced80769 100644 --- a/profiles/apparmor/profiles/extras/usr.lib.postfix.nqmgr +++ b/profiles/apparmor/profiles/extras/postfix.nqmgr @@ -1,6 +1,7 @@ # ------------------------------------------------------------------ # # Copyright (C) 2002-2006 Novell/SUSE +# Copyright (C) 2018 Canonical, Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -10,12 +11,12 @@ #include -/usr/lib/postfix/nqmgr { +profile postfix-nqmgr /usr/lib/postfix/{sbin/,}nqmgr { #include #include #include - /usr/lib/postfix/nqmgr rmix, + /usr/lib/postfix/{sbin/,}nqmgr rmix, /{var/spool/postfix/,}active/ r, /{var/spool/postfix/,}active/[0-9A-F]/ r, diff --git a/profiles/apparmor/profiles/extras/usr.lib.postfix.oqmgr b/profiles/apparmor/profiles/extras/postfix.oqmgr similarity index 80% rename from profiles/apparmor/profiles/extras/usr.lib.postfix.oqmgr rename to profiles/apparmor/profiles/extras/postfix.oqmgr index ee2f0d7ec..7cb107b3d 100644 --- a/profiles/apparmor/profiles/extras/usr.lib.postfix.oqmgr +++ b/profiles/apparmor/profiles/extras/postfix.oqmgr @@ -1,6 +1,7 @@ # ------------------------------------------------------------------ # # Copyright (C) 2002-2005 Novell/SUSE +# Copyright (C) 2018 Canonical, Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -11,10 +12,10 @@ #include -/usr/lib/postfix/oqmgr { +profile postfix-oqmgr /usr/lib/postfix/{sbin/,}oqmgr { #include #include #include - /usr/lib/postfix/oqmgr rmix, + /usr/lib/postfix/{sbin/,}oqmgr rmix, } diff --git a/profiles/apparmor/profiles/extras/usr.lib.postfix.pickup b/profiles/apparmor/profiles/extras/postfix.pickup similarity index 83% rename from profiles/apparmor/profiles/extras/usr.lib.postfix.pickup rename to profiles/apparmor/profiles/extras/postfix.pickup index 079db7c46..b8d40662f 100644 --- a/profiles/apparmor/profiles/extras/usr.lib.postfix.pickup +++ b/profiles/apparmor/profiles/extras/postfix.pickup @@ -1,6 +1,7 @@ # ------------------------------------------------------------------ # # Copyright (C) 2002-2006 Novell/SUSE +# Copyright (C) 2018 Canonical, Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -10,12 +11,12 @@ #include -/usr/lib/postfix/pickup { +profile postfix-pickup /usr/lib/postfix/{sbin/,}pickup { #include #include #include - /usr/lib/postfix/pickup rmix, + /usr/lib/postfix/{sbin/,}pickup rmix, /{var/spool/postfix/,}public/cleanup w, /{var/spool/postfix/,}public/pickup r, diff --git a/profiles/apparmor/profiles/extras/usr.lib.postfix.pipe b/profiles/apparmor/profiles/extras/postfix.pipe similarity index 84% rename from profiles/apparmor/profiles/extras/usr.lib.postfix.pipe rename to profiles/apparmor/profiles/extras/postfix.pipe index 9f0a9466f..93639cb5e 100644 --- a/profiles/apparmor/profiles/extras/usr.lib.postfix.pipe +++ b/profiles/apparmor/profiles/extras/postfix.pipe @@ -2,6 +2,7 @@ # # Copyright (C) 2006 Novell/SUSE # Copyright (C) 2017 Christian Boltz +# Copyright (C) 2018 Canonical, Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -11,12 +12,13 @@ #include -/usr/lib/postfix/pipe { +profile postfix-pipe /usr/lib/postfix/{sbin/,}pipe { #include #include #include - /usr/lib/postfix/pipe mrix, + /usr/lib/postfix/{sbin/,}pipe rmix, + /var/spool/postfix/active/* rwk, /var/spool/postfix/private/bounce w, /var/spool/postfix/private/defer w, diff --git a/profiles/apparmor/profiles/extras/usr.lib.postfix.proxymap b/profiles/apparmor/profiles/extras/postfix.proxymap similarity index 81% rename from profiles/apparmor/profiles/extras/usr.lib.postfix.proxymap rename to profiles/apparmor/profiles/extras/postfix.proxymap index 28e3a9c62..b65221642 100644 --- a/profiles/apparmor/profiles/extras/usr.lib.postfix.proxymap +++ b/profiles/apparmor/profiles/extras/postfix.proxymap @@ -1,6 +1,7 @@ # ------------------------------------------------------------------ # # Copyright (C) 2002-2006 Novell/SUSE +# Copyright (C) 2018 Canonical, Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -10,7 +11,7 @@ #include -/usr/lib/postfix/proxymap { +profile postfix-proxymap /usr/lib/postfix/{sbin/,}proxymap { #include #include #include @@ -18,7 +19,7 @@ capability setgid, capability setuid, - /usr/lib/postfix/proxymap rmix, + /usr/lib/postfix/{sbin/,}proxymap rmix, /etc/postfix/main.cf r, @{PROC}/net/if_inet6 r, diff --git a/profiles/apparmor/profiles/extras/usr.lib.postfix.qmgr b/profiles/apparmor/profiles/extras/postfix.qmgr similarity index 93% rename from profiles/apparmor/profiles/extras/usr.lib.postfix.qmgr rename to profiles/apparmor/profiles/extras/postfix.qmgr index b1aff32eb..7aa24016f 100644 --- a/profiles/apparmor/profiles/extras/usr.lib.postfix.qmgr +++ b/profiles/apparmor/profiles/extras/postfix.qmgr @@ -1,6 +1,7 @@ # ------------------------------------------------------------------ # # Copyright (C) 2002-2006 Novell/SUSE +# Copyright (C) 2018 Canonical, Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -10,12 +11,13 @@ #include -/usr/lib/postfix/qmgr { +profile postfix-qmgr /usr/lib/postfix/{sbin/,}qmgr { #include #include #include - /usr/lib/postfix/qmgr rmix, + /usr/lib/postfix/{sbin/,}qmgr rmix, + /{var/spool/postfix/,}active/ r, /{var/spool/postfix/,}active/[0-9A-F]/[0-9A-F]/* rwl, /{var/spool/postfix/,}active/[0-9A-F]/[0-9A-F]/ rwl, diff --git a/profiles/apparmor/profiles/extras/usr.lib.postfix.qmqpd b/profiles/apparmor/profiles/extras/postfix.qmqpd similarity index 79% rename from profiles/apparmor/profiles/extras/usr.lib.postfix.qmqpd rename to profiles/apparmor/profiles/extras/postfix.qmqpd index 24c114bd4..29b74da52 100644 --- a/profiles/apparmor/profiles/extras/usr.lib.postfix.qmqpd +++ b/profiles/apparmor/profiles/extras/postfix.qmqpd @@ -1,6 +1,7 @@ # ------------------------------------------------------------------ # # Copyright (C) 2002-2006 Novell/SUSE +# Copyright (C) 2018 Canonical, Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -10,10 +11,10 @@ #include -/usr/lib/postfix/qmqpd { +profile postfix-qmqpd /usr/lib/postfix/{sbin/,}qmqpd { #include #include #include - /usr/lib/postfix/qmqpd rmix, + /usr/lib/postfix/{sbin/,}qmqpd rmix, } diff --git a/profiles/apparmor/profiles/extras/usr.lib.postfix.scache b/profiles/apparmor/profiles/extras/postfix.scache similarity index 81% rename from profiles/apparmor/profiles/extras/usr.lib.postfix.scache rename to profiles/apparmor/profiles/extras/postfix.scache index 11d4b5c55..b6aa9e2ee 100644 --- a/profiles/apparmor/profiles/extras/usr.lib.postfix.scache +++ b/profiles/apparmor/profiles/extras/postfix.scache @@ -1,6 +1,7 @@ # ------------------------------------------------------------------ # # Copyright (C) 2002-2005 Novell/SUSE +# Copyright (C) 2018 Canonical, Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -12,12 +13,12 @@ #include -/usr/lib/postfix/scache { +profile postfix-scache /usr/lib/postfix/{sbin/,}scache { #include #include #include - /usr/lib/postfix/scache rmix, + /usr/lib/postfix/{sbin/,}scache rmix, /{,var/}run/nscd/group r, } diff --git a/profiles/apparmor/profiles/extras/usr.lib.postfix.showq b/profiles/apparmor/profiles/extras/postfix.showq similarity index 93% rename from profiles/apparmor/profiles/extras/usr.lib.postfix.showq rename to profiles/apparmor/profiles/extras/postfix.showq index d5703f89f..9306c9d99 100644 --- a/profiles/apparmor/profiles/extras/usr.lib.postfix.showq +++ b/profiles/apparmor/profiles/extras/postfix.showq @@ -1,6 +1,7 @@ # ------------------------------------------------------------------ # # Copyright (C) 2002-2006 Novell/SUSE +# Copyright (C) 2018 Canonical, Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -10,12 +11,12 @@ #include -/usr/lib/postfix/showq { +profile postfix-showq /usr/lib/postfix/{sbin/,}showq { #include #include #include - /usr/lib/postfix/showq rmix, + /usr/lib/postfix/{sbin/,}showq rmix, /{var/spool/postfix/,}active/ r, /{var/spool/postfix/,}active/[0-9A-F]/[0-9A-F]/* r, diff --git a/profiles/apparmor/profiles/extras/usr.lib.postfix.smtp b/profiles/apparmor/profiles/extras/postfix.smtp similarity index 92% rename from profiles/apparmor/profiles/extras/usr.lib.postfix.smtp rename to profiles/apparmor/profiles/extras/postfix.smtp index 4a8a8c207..24ed86f0e 100644 --- a/profiles/apparmor/profiles/extras/usr.lib.postfix.smtp +++ b/profiles/apparmor/profiles/extras/postfix.smtp @@ -1,6 +1,7 @@ # ------------------------------------------------------------------ # # Copyright (C) 2002-2006 Novell/SUSE +# Copyright (C) 2018 Canonical, Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -10,7 +11,7 @@ #include -/usr/lib/postfix/smtp { +profile postfix-smtp /usr/lib/postfix/{sbin/,}smtp { #include #include #include @@ -20,7 +21,7 @@ capability dac_read_search, capability net_bind_service, - /usr/lib/postfix/smtp rmix, + /usr/lib/postfix/{sbin/,}smtp rmix, /{var/spool/postfix/,}active/[0-9A-F]/[0-9A-F]/* rwl, /{var/spool/postfix/,}active/[0-9A-F]/[0-9A-F]/ rwl, diff --git a/profiles/apparmor/profiles/extras/usr.lib.postfix.smtpd b/profiles/apparmor/profiles/extras/postfix.smtpd similarity index 93% rename from profiles/apparmor/profiles/extras/usr.lib.postfix.smtpd rename to profiles/apparmor/profiles/extras/postfix.smtpd index 4ec92c0d7..80bc39f58 100644 --- a/profiles/apparmor/profiles/extras/usr.lib.postfix.smtpd +++ b/profiles/apparmor/profiles/extras/postfix.smtpd @@ -1,6 +1,7 @@ # ------------------------------------------------------------------ # # Copyright (C) 2002-2006 Novell/SUSE +# Copyright (C) 2018 Canonical, Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -10,7 +11,7 @@ #include -/usr/lib/postfix/smtpd { +profile postfix-smtpd /usr/lib/postfix/{sbin/,}smtpd { #include #include #include @@ -21,7 +22,7 @@ capability setgid, capability setuid, - /usr/lib/postfix/smtpd rmix, + /usr/lib/postfix/{sbin/,}smtpd rmix, /usr/sbin/postdrop rPx, /dev/urandom r, diff --git a/profiles/apparmor/profiles/extras/usr.lib.postfix.verify b/profiles/apparmor/profiles/extras/postfix.spawn similarity index 79% rename from profiles/apparmor/profiles/extras/usr.lib.postfix.verify rename to profiles/apparmor/profiles/extras/postfix.spawn index fee11f417..475576c53 100644 --- a/profiles/apparmor/profiles/extras/usr.lib.postfix.verify +++ b/profiles/apparmor/profiles/extras/postfix.spawn @@ -1,6 +1,7 @@ # ------------------------------------------------------------------ # # Copyright (C) 2002-2006 Novell/SUSE +# Copyright (C) 2018 Canonical, Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -10,10 +11,10 @@ #include -/usr/lib/postfix/verify { +profile postfix-spawn /usr/lib/postfix/{sbin/,}spawn { #include #include #include - /usr/lib/postfix/verify rmix, + /usr/lib/postfix/{sbin/,}spawn rmix, } diff --git a/profiles/apparmor/profiles/extras/usr.lib.postfix.tlsmgr b/profiles/apparmor/profiles/extras/postfix.tlsmgr similarity index 83% rename from profiles/apparmor/profiles/extras/usr.lib.postfix.tlsmgr rename to profiles/apparmor/profiles/extras/postfix.tlsmgr index 30e37396d..8603f2b3c 100644 --- a/profiles/apparmor/profiles/extras/usr.lib.postfix.tlsmgr +++ b/profiles/apparmor/profiles/extras/postfix.tlsmgr @@ -1,6 +1,7 @@ # ------------------------------------------------------------------ # # Copyright (C) 2002-2005 Novell/SUSE +# Copyright (C) 2018 Canonical, Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -11,12 +12,12 @@ #include -/usr/lib/postfix/tlsmgr { +profile postfix-tlsmgr /usr/lib/postfix/{sbin/,}tlsmgr { #include #include #include - /usr/lib/postfix/tlsmgr rmix, + /usr/lib/postfix/{sbin/,}tlsmgr rmix, /etc/postfix/prng_exch rw, /{var/spool/postfix/,}private/tlsmgr r, diff --git a/profiles/apparmor/profiles/extras/usr.lib.postfix.trivial-rewrite b/profiles/apparmor/profiles/extras/postfix.trivial-rewrite similarity index 82% rename from profiles/apparmor/profiles/extras/usr.lib.postfix.trivial-rewrite rename to profiles/apparmor/profiles/extras/postfix.trivial-rewrite index f16a10820..01c780102 100644 --- a/profiles/apparmor/profiles/extras/usr.lib.postfix.trivial-rewrite +++ b/profiles/apparmor/profiles/extras/postfix.trivial-rewrite @@ -1,6 +1,7 @@ # ------------------------------------------------------------------ # # Copyright (C) 2002-2006 Novell/SUSE +# Copyright (C) 2018 Canonical, Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -10,12 +11,12 @@ #include -/usr/lib/postfix/trivial-rewrite { +profile postfix-trivial-rewrite /usr/lib/postfix/{sbin/,}trivial-rewrite { #include #include #include - /usr/lib/postfix/trivial-rewrite rmix, + /usr/lib/postfix/{sbin/,}trivial-rewrite rmix, /etc/postfix/relocated.db r, /etc/postfix/transport.db r, diff --git a/profiles/apparmor/profiles/extras/usr.lib.postfix.spawn b/profiles/apparmor/profiles/extras/postfix.verify similarity index 79% rename from profiles/apparmor/profiles/extras/usr.lib.postfix.spawn rename to profiles/apparmor/profiles/extras/postfix.verify index 3d03b3610..23caf8314 100644 --- a/profiles/apparmor/profiles/extras/usr.lib.postfix.spawn +++ b/profiles/apparmor/profiles/extras/postfix.verify @@ -1,6 +1,7 @@ # ------------------------------------------------------------------ # # Copyright (C) 2002-2006 Novell/SUSE +# Copyright (C) 2018 Canonical, Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -10,10 +11,10 @@ #include -/usr/lib/postfix/spawn { +profile postfix-verify /usr/lib/postfix/{sbin/,}verify { #include #include #include - /usr/lib/postfix/spawn rmix, + /usr/lib/postfix/{sbin/,}verify rmix, } diff --git a/profiles/apparmor/profiles/extras/usr.lib.postfix.virtual b/profiles/apparmor/profiles/extras/postfix.virtual similarity index 82% rename from profiles/apparmor/profiles/extras/usr.lib.postfix.virtual rename to profiles/apparmor/profiles/extras/postfix.virtual index 24c68e6c3..38728e845 100644 --- a/profiles/apparmor/profiles/extras/usr.lib.postfix.virtual +++ b/profiles/apparmor/profiles/extras/postfix.virtual @@ -1,6 +1,7 @@ # ------------------------------------------------------------------ # # Copyright (C) 2002-2006 Novell/SUSE +# Copyright (C) 2018 Canonical, Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -10,7 +11,7 @@ #include -/usr/lib/postfix/virtual { +profile postfix-virtual /usr/lib/postfix/{sbin/,}virtual { #include #include #include @@ -18,7 +19,8 @@ capability setgid, capability setuid, - /usr/lib/postfix/virtual rmix, + /usr/lib/postfix/{sbin/,}virtual rmix, + /var/spool/postfix/active/* rw, /var/spool/postfix/pid/unix.virtual rw, /var/spool/postfix/private/bounce w, From 35d84895fe15d989b885a38d4763a73ffc8ba49c Mon Sep 17 00:00:00 2001 From: Steve Beattie Date: Mon, 26 Mar 2018 11:39:45 -0700 Subject: [PATCH 27/46] profiles/postfix-master: grant signal+unix communication with children Grant the ability to communicate with the postfix named child profiles via signals and unix sockets. Include the path-based match names as a fallback on upgrades. Signed-off-by: Steve Beattie --- profiles/apparmor/profiles/extras/postfix.master | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/profiles/apparmor/profiles/extras/postfix.master b/profiles/apparmor/profiles/extras/postfix.master index 377e772fb..c447fba56 100644 --- a/profiles/apparmor/profiles/extras/postfix.master +++ b/profiles/apparmor/profiles/extras/postfix.master @@ -20,6 +20,13 @@ profile postfix-master /usr/lib/postfix/{sbin/,}master { capability kill, capability dac_override, + signal send peer=/usr/lib/postfix/*, + signal send peer=postfix-*, + signal peer=@{profile_name}, + + unix (send receive) type=stream peer=(label=/usr/lib/postfix/*), + unix (send receive) type=stream peer=(label=postfix-*), + /etc/postfix/master.cf r, /{var/spool/postfix/,}pid/master.pid rwk, /{var/spool/postfix/,}private/* wl, From 1c9459825a928a92c8ba563cdfb0d17a6cb10612 Mon Sep 17 00:00:00 2001 From: Steve Beattie Date: Mon, 26 Mar 2018 11:43:45 -0700 Subject: [PATCH 28/46] profiles: add a postfix postscreen profile Signed-off-by: Steve Beattie --- .../apparmor/profiles/extras/postfix.postscreen | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 profiles/apparmor/profiles/extras/postfix.postscreen diff --git a/profiles/apparmor/profiles/extras/postfix.postscreen b/profiles/apparmor/profiles/extras/postfix.postscreen new file mode 100644 index 000000000..6df91d7aa --- /dev/null +++ b/profiles/apparmor/profiles/extras/postfix.postscreen @@ -0,0 +1,17 @@ +# ------------------------------------------------------------------ +# +# Copyright (C) 2018 Canonical, Ltd. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of version 2 of the GNU General Public +# License published by the Free Software Foundation. +# +# ------------------------------------------------------------------ + +#include + +profile postfix-postscreen /usr/lib/postfix/{sbin/,}postscreen { + #include + + /usr/lib/postfix/{sbin/,}postscreen rmix, +} From 889503f6234863d6520bd5a209dfda8e195a6d80 Mon Sep 17 00:00:00 2001 From: Steve Beattie Date: Mon, 26 Mar 2018 16:23:07 -0700 Subject: [PATCH 29/46] profiles: add a postfix dnsblog profile Signed-off-by: Steve Beattie --- .../apparmor/profiles/extras/postfix.dnsblog | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 profiles/apparmor/profiles/extras/postfix.dnsblog diff --git a/profiles/apparmor/profiles/extras/postfix.dnsblog b/profiles/apparmor/profiles/extras/postfix.dnsblog new file mode 100644 index 000000000..902663a2c --- /dev/null +++ b/profiles/apparmor/profiles/extras/postfix.dnsblog @@ -0,0 +1,20 @@ +# ------------------------------------------------------------------ +# +# Copyright (C) 2018 Canonical, Ltd. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of version 2 of the GNU General Public +# License published by the Free Software Foundation. +# +# ------------------------------------------------------------------ +# vim:syntax=apparmor + +#include + +profile postfix-dnsblog /usr/lib/postfix/{sbin/,}dnsblog { + #include + + /usr/lib/postfix/{sbin/,}dnsblog rmix, + + /var/spool/postfix/private/dnsblog rw, +} From dd4903efc6a97a69c3e28ba09c2e67d25bf154c8 Mon Sep 17 00:00:00 2001 From: Steve Beattie Date: Mon, 26 Mar 2018 19:41:13 -0700 Subject: [PATCH 30/46] profiles/postfix: eliminate some redundant rules Remove rules covered by the postfix-common or other abstractions. Signed-off-by: Steve Beattie --- profiles/apparmor/profiles/extras/postfix.anvil | 4 ---- profiles/apparmor/profiles/extras/postfix.bounce | 6 ------ profiles/apparmor/profiles/extras/postfix.error | 1 - profiles/apparmor/profiles/extras/postfix.flush | 5 ----- profiles/apparmor/profiles/extras/postfix.nqmgr | 1 - profiles/apparmor/profiles/extras/postfix.proxymap | 6 ------ profiles/apparmor/profiles/extras/postfix.scache | 2 -- profiles/apparmor/profiles/extras/postfix.smtpd | 9 --------- profiles/apparmor/profiles/extras/postfix.virtual | 3 --- 9 files changed, 37 deletions(-) diff --git a/profiles/apparmor/profiles/extras/postfix.anvil b/profiles/apparmor/profiles/extras/postfix.anvil index 69c579c67..acbfd3269 100644 --- a/profiles/apparmor/profiles/extras/postfix.anvil +++ b/profiles/apparmor/profiles/extras/postfix.anvil @@ -16,13 +16,9 @@ profile postfix-anvil /usr/lib/postfix/{sbin/,}anvil { #include #include - capability setgid, - capability setuid, - /usr/lib/postfix/{sbin/,}anvil rmix, /etc/postfix/main.cf r, /{var/spool/postfix/,}private/anvil rw, /{var/spool/postfix/,}pid/unix.anvil rw, - @{PROC}/net/if_inet6 r, } diff --git a/profiles/apparmor/profiles/extras/postfix.bounce b/profiles/apparmor/profiles/extras/postfix.bounce index 094b1924a..a47b85bac 100644 --- a/profiles/apparmor/profiles/extras/postfix.bounce +++ b/profiles/apparmor/profiles/extras/postfix.bounce @@ -16,9 +16,6 @@ profile postfix-bounce /usr/lib/postfix/{sbin/,}bounce { #include #include - capability setgid, - capability setuid, - /usr/lib/postfix/{sbin/,}bounce rmix, /{var/spool/postfix/,}active/[0-9A-F]/[0-9A-F]/* rwl, @@ -40,7 +37,4 @@ profile postfix-bounce /usr/lib/postfix/{sbin/,}bounce { /{var/spool/postfix/,}pid/unix.bounce rw, /{var/spool/postfix/,}pid/unix.defer rw, /{var/spool/postfix/,}pid/unix.trace rw, - - /etc/postfix/main.cf r, - @{PROC}/net/if_inet6 r, } diff --git a/profiles/apparmor/profiles/extras/postfix.error b/profiles/apparmor/profiles/extras/postfix.error index 0f6370a35..641ffef67 100644 --- a/profiles/apparmor/profiles/extras/postfix.error +++ b/profiles/apparmor/profiles/extras/postfix.error @@ -19,7 +19,6 @@ profile postfix-error /usr/lib/postfix/{sbin/,}error { /usr/lib/postfix/{sbin/,}error rmix, - @{PROC}/sys/kernel/ngroups_max r, owner /var/spool/postfix/active/* rwk, /var/spool/postfix/pid/unix.error rwk, /var/spool/postfix/pid/unix.retry rwk, diff --git a/profiles/apparmor/profiles/extras/postfix.flush b/profiles/apparmor/profiles/extras/postfix.flush index ffbfb4798..32910646d 100644 --- a/profiles/apparmor/profiles/extras/postfix.flush +++ b/profiles/apparmor/profiles/extras/postfix.flush @@ -16,9 +16,6 @@ profile postfix-flush /usr/lib/postfix/{sbin/,}flush { #include #include - capability setgid, - capability setuid, - /usr/lib/postfix/{sbin/,}flush rmix, /{var/spool/postfix/,}deferred/ r, @@ -36,8 +33,6 @@ profile postfix-flush /usr/lib/postfix/{sbin/,}flush { /{var/spool/postfix/,}public/qmgr w, /{var/spool/postfix/,}pid/unix.flush rw, /etc/mtab r, - /etc/postfix/main.cf r, - /etc/postfix/virtual.db r, @{HOME}/.forward r, diff --git a/profiles/apparmor/profiles/extras/postfix.nqmgr b/profiles/apparmor/profiles/extras/postfix.nqmgr index 6ced80769..24249df03 100644 --- a/profiles/apparmor/profiles/extras/postfix.nqmgr +++ b/profiles/apparmor/profiles/extras/postfix.nqmgr @@ -43,5 +43,4 @@ profile postfix-nqmgr /usr/lib/postfix/{sbin/,}nqmgr { /{var/spool/postfix/,}private/local w, /{var/spool/postfix/,}public/flush w, /{var/spool/postfix/,}public/qmgr r, - /etc/postfix/main.cf r, } diff --git a/profiles/apparmor/profiles/extras/postfix.proxymap b/profiles/apparmor/profiles/extras/postfix.proxymap index b65221642..e50f707a3 100644 --- a/profiles/apparmor/profiles/extras/postfix.proxymap +++ b/profiles/apparmor/profiles/extras/postfix.proxymap @@ -16,11 +16,5 @@ profile postfix-proxymap /usr/lib/postfix/{sbin/,}proxymap { #include #include - capability setgid, - capability setuid, - /usr/lib/postfix/{sbin/,}proxymap rmix, - - /etc/postfix/main.cf r, - @{PROC}/net/if_inet6 r, } diff --git a/profiles/apparmor/profiles/extras/postfix.scache b/profiles/apparmor/profiles/extras/postfix.scache index b6aa9e2ee..ec5a8ccf3 100644 --- a/profiles/apparmor/profiles/extras/postfix.scache +++ b/profiles/apparmor/profiles/extras/postfix.scache @@ -19,6 +19,4 @@ profile postfix-scache /usr/lib/postfix/{sbin/,}scache { #include /usr/lib/postfix/{sbin/,}scache rmix, - - /{,var/}run/nscd/group r, } diff --git a/profiles/apparmor/profiles/extras/postfix.smtpd b/profiles/apparmor/profiles/extras/postfix.smtpd index 80bc39f58..25330f638 100644 --- a/profiles/apparmor/profiles/extras/postfix.smtpd +++ b/profiles/apparmor/profiles/extras/postfix.smtpd @@ -19,8 +19,6 @@ profile postfix-smtpd /usr/lib/postfix/{sbin/,}smtpd { capability dac_override, capability dac_read_search, - capability setgid, - capability setuid, /usr/lib/postfix/{sbin/,}smtpd rmix, /usr/sbin/postdrop rPx, @@ -38,11 +36,6 @@ profile postfix-smtpd /usr/lib/postfix/{sbin/,}smtpd { /etc/postfix/main.cf r, /etc/postfix/prng_exch rw, - /usr/lib64/sasl2/ mr, - /usr/lib64/sasl2/* mr, - /usr/lib/sasl2/ mr, - /usr/lib/sasl2/* mr, - /usr/share/ssl/certs/ca-bundle.crt r, /{var/spool/postfix/,}pid/inet.* rw, @@ -53,6 +46,4 @@ profile postfix-smtpd /usr/lib/postfix/{sbin/,}smtpd { /{var/spool/postfix/,}public/cleanup w, /{,var/}run/sasl2/mux w, - - @{PROC}/net/if_inet6 r, } diff --git a/profiles/apparmor/profiles/extras/postfix.virtual b/profiles/apparmor/profiles/extras/postfix.virtual index 38728e845..b6a39847f 100644 --- a/profiles/apparmor/profiles/extras/postfix.virtual +++ b/profiles/apparmor/profiles/extras/postfix.virtual @@ -16,9 +16,6 @@ profile postfix-virtual /usr/lib/postfix/{sbin/,}virtual { #include #include - capability setgid, - capability setuid, - /usr/lib/postfix/{sbin/,}virtual rmix, /var/spool/postfix/active/* rw, From 9943da2f528a0f5267dfb5bf4dd9f427f6a80104 Mon Sep 17 00:00:00 2001 From: Steve Beattie Date: Tue, 27 Mar 2018 21:34:24 -0700 Subject: [PATCH 31/46] profiles/postfix: add locking perm to pid files Signed-off-by: Steve Beattie --- profiles/apparmor/profiles/extras/postfix.anvil | 2 +- profiles/apparmor/profiles/extras/postfix.bounce | 7 ++++--- profiles/apparmor/profiles/extras/postfix.cleanup | 4 +++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/profiles/apparmor/profiles/extras/postfix.anvil b/profiles/apparmor/profiles/extras/postfix.anvil index acbfd3269..d22d81b15 100644 --- a/profiles/apparmor/profiles/extras/postfix.anvil +++ b/profiles/apparmor/profiles/extras/postfix.anvil @@ -20,5 +20,5 @@ profile postfix-anvil /usr/lib/postfix/{sbin/,}anvil { /etc/postfix/main.cf r, /{var/spool/postfix/,}private/anvil rw, - /{var/spool/postfix/,}pid/unix.anvil rw, + /{var/spool/postfix/,}pid/unix.anvil rwk, } diff --git a/profiles/apparmor/profiles/extras/postfix.bounce b/profiles/apparmor/profiles/extras/postfix.bounce index a47b85bac..91a25afb7 100644 --- a/profiles/apparmor/profiles/extras/postfix.bounce +++ b/profiles/apparmor/profiles/extras/postfix.bounce @@ -34,7 +34,8 @@ profile postfix-bounce /usr/lib/postfix/{sbin/,}bounce { /{var/spool/postfix/,}trace/[0-9A-F]/[0-9A-F]/ rwl, /{var/spool/postfix/,}trace/[0-9A-F]/ rwl, /{var/spool/postfix/,}public/cleanup w, - /{var/spool/postfix/,}pid/unix.bounce rw, - /{var/spool/postfix/,}pid/unix.defer rw, - /{var/spool/postfix/,}pid/unix.trace rw, + + /{var/spool/postfix/,}pid/unix.bounce rwk, + /{var/spool/postfix/,}pid/unix.defer rwk, + /{var/spool/postfix/,}pid/unix.trace rwk, } diff --git a/profiles/apparmor/profiles/extras/postfix.cleanup b/profiles/apparmor/profiles/extras/postfix.cleanup index 9f20836f6..b6dd6e3dc 100644 --- a/profiles/apparmor/profiles/extras/postfix.cleanup +++ b/profiles/apparmor/profiles/extras/postfix.cleanup @@ -27,7 +27,9 @@ profile postfix-cleanup /usr/lib/postfix/{sbin/,}cleanup { /{var/spool/postfix/,}private/{rewrite,bounce} w, /{var/spool/postfix/,}public/qmgr w, /{var/spool/postfix/,}hold/[0-9A-F]* w, - /{var/spool/postfix/,}pid/unix.cleanup rw, + + /{var/spool/postfix/,}pid/unix.cleanup rwk, + /etc/{m,fs}tab r, /etc/postfix/* r, } From cb468786445ff8a42549f52dde9392b99b1edc64 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 30 Nov 2018 13:52:24 +0100 Subject: [PATCH 32/46] Add /etc/letsencrypt stuff to ssl_keys/ssl_certs abstraction `/etc/letsencrypt/live/` contains symlinks to `/etc/letsencrypt/archive/` which contains the keys. Add the certs to ssl_certs and the private keys to ssl_keys. --- profiles/apparmor.d/abstractions/ssl_certs | 5 +++++ profiles/apparmor.d/abstractions/ssl_keys | 3 +++ 2 files changed, 8 insertions(+) diff --git a/profiles/apparmor.d/abstractions/ssl_certs b/profiles/apparmor.d/abstractions/ssl_certs index 50da52f7a..7234f061c 100644 --- a/profiles/apparmor.d/abstractions/ssl_certs +++ b/profiles/apparmor.d/abstractions/ssl_certs @@ -32,3 +32,8 @@ /etc/dehydrated/certs/*/cert-*.pem r, /etc/dehydrated/certs/*/chain-*.pem r, /etc/dehydrated/certs/*/fullchain-*.pem r, + + # certbot + /etc/letsencrypt/archive/*/cert*.pem r, + /etc/letsencrypt/archive/*/chain*.pem r, + /etc/letsencrypt/archive/*/fullchain*.pem r, diff --git a/profiles/apparmor.d/abstractions/ssl_keys b/profiles/apparmor.d/abstractions/ssl_keys index d629871ec..f53d54e0d 100644 --- a/profiles/apparmor.d/abstractions/ssl_keys +++ b/profiles/apparmor.d/abstractions/ssl_keys @@ -23,3 +23,6 @@ # dehydrated /etc/dehydrated/certs/*/privkey-*.pem r, + + # certbot / letsencrypt + /etc/letsencrypt/archive/*/privkey*.pem r, From f4bfd7816425cd09e75b77e92abd431fbc65f731 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 30 Nov 2018 14:22:58 +0100 Subject: [PATCH 33/46] postfix.master: Change path of child processes --- .../apparmor/profiles/extras/postfix.master | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/profiles/apparmor/profiles/extras/postfix.master b/profiles/apparmor/profiles/extras/postfix.master index c447fba56..5e16409b8 100644 --- a/profiles/apparmor/profiles/extras/postfix.master +++ b/profiles/apparmor/profiles/extras/postfix.master @@ -33,22 +33,21 @@ profile postfix-master /usr/lib/postfix/{sbin/,}master { /{var/spool/postfix/,}private/tlsmgr rwl, /{var/spool/postfix/,}public/{cleanup,flush,pickup,qmgr,showq,tlsmgr} rwl, - /usr/lib/postfix/anvil Px, - /usr/lib/postfix/bounce Px, - /usr/lib/postfix/cleanup Px, - /usr/lib/postfix/flush Px, - /usr/lib/postfix/local Px, + /usr/lib/postfix/{sbin/,}anvil Px, + /usr/lib/postfix/{sbin/,}bounce Px, + /usr/lib/postfix/{sbin/,}cleanup Px, + /usr/lib/postfix/{sbin/,}flush Px, + /usr/lib/postfix/{sbin/,}local Px, /usr/lib/postfix/{sbin/,}master rmix, - /usr/lib/postfix/nqmgr Px, - /usr/lib/postfix/proxymap Px, - /usr/lib/postfix/pickup Px, - /usr/lib/postfix/pipe Px, - /usr/lib/postfix/qmgr Px, - /usr/lib/postfix/scache Px, - /usr/lib/postfix/showq Px, - /usr/lib/postfix/smtp Px, - /usr/lib/postfix/smtpd Px, - /usr/lib/postfix/tlsmgr Px, - /usr/lib/postfix/trivial-rewrite Px, - /usr/lib/postfix/master rmix, + /usr/lib/postfix/{sbin/,}nqmgr Px, + /usr/lib/postfix/{sbin/,}proxymap Px, + /usr/lib/postfix/{sbin/,}pickup Px, + /usr/lib/postfix/{sbin/,}pipe Px, + /usr/lib/postfix/{sbin/,}qmgr Px, + /usr/lib/postfix/{sbin/,}scache Px, + /usr/lib/postfix/{sbin/,}showq Px, + /usr/lib/postfix/{sbin/,}smtp Px, + /usr/lib/postfix/{sbin/,}smtpd Px, + /usr/lib/postfix/{sbin/,}tlsmgr Px, + /usr/lib/postfix/{sbin/,}trivial-rewrite Px, } From e8841a09537959d1209613d55a10f8d14c1c7290 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 30 Nov 2018 14:23:34 +0100 Subject: [PATCH 34/46] postfix.tlsmgr: Connect to urandom and prng exchange --- profiles/apparmor/profiles/extras/postfix.tlsmgr | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/profiles/apparmor/profiles/extras/postfix.tlsmgr b/profiles/apparmor/profiles/extras/postfix.tlsmgr index 8603f2b3c..cb803d7e9 100644 --- a/profiles/apparmor/profiles/extras/postfix.tlsmgr +++ b/profiles/apparmor/profiles/extras/postfix.tlsmgr @@ -19,8 +19,11 @@ profile postfix-tlsmgr /usr/lib/postfix/{sbin/,}tlsmgr { /usr/lib/postfix/{sbin/,}tlsmgr rmix, - /etc/postfix/prng_exch rw, - /{var/spool/postfix/,}private/tlsmgr r, + /var/spool/postfix/dev/urandom r, + /{etc,var/lib}/postfix/prng_exch rwk, + /{var/spool/postfix/,}private/tlsmgr rw, /{,var/}run/__db.smtpd_tls_session_cache.db rw, /{,var/}run/smtpd_tls_session_cache.db rw, + /var/lib/postfix/smtpd_scache.db rwk, + /var/lib/postfix/smtp_scache.db rwk, } From 3d842ddb82fe244aa214322df8d8475b76089075 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 30 Nov 2018 14:23:56 +0100 Subject: [PATCH 35/46] postifx-common: Allow access to dynamicmaps, most seems to use it --- profiles/apparmor.d/abstractions/postfix-common | 2 ++ 1 file changed, 2 insertions(+) diff --git a/profiles/apparmor.d/abstractions/postfix-common b/profiles/apparmor.d/abstractions/postfix-common index ab5210504..d3550c41a 100644 --- a/profiles/apparmor.d/abstractions/postfix-common +++ b/profiles/apparmor.d/abstractions/postfix-common @@ -33,3 +33,5 @@ /var/spool/postfix/etc/* r, /var/spool/postfix/lib/lib*.so* mr, /var/spool/postfix/lib/@{multiarch}/lib*.so* mr, + + /etc/postfix/dynamicmaps.cf.d/ r, From 02528133d2b55a254d1bb8288601566e12ceccdf Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 30 Nov 2018 14:24:43 +0100 Subject: [PATCH 36/46] postfix.*: Adapt for new queue names, and extra locking and r/w communication This gets us to the local process now, which comes next. --- .../apparmor/profiles/extras/postfix.cleanup | 8 +++++--- profiles/apparmor/profiles/extras/postfix.master | 3 +-- .../apparmor/profiles/extras/postfix.proxymap | 3 ++- profiles/apparmor/profiles/extras/postfix.qmgr | 4 +++- profiles/apparmor/profiles/extras/postfix.smtpd | 16 ++++++++-------- .../profiles/extras/postfix.trivial-rewrite | 1 + 6 files changed, 20 insertions(+), 15 deletions(-) diff --git a/profiles/apparmor/profiles/extras/postfix.cleanup b/profiles/apparmor/profiles/extras/postfix.cleanup index b6dd6e3dc..f5ff794c8 100644 --- a/profiles/apparmor/profiles/extras/postfix.cleanup +++ b/profiles/apparmor/profiles/extras/postfix.cleanup @@ -24,10 +24,12 @@ profile postfix-cleanup /usr/lib/postfix/{sbin/,}cleanup { /{var/spool/postfix/,}incoming/[0-9A-F]/[0-9A-F]/* rwl, /{var/spool/postfix/,}incoming/[0-9A-F]/[0-9A-F]/ rwl, /{var/spool/postfix/,}incoming/[0-9A-F]/ rwl, - /{var/spool/postfix/,}private/{rewrite,bounce} w, - /{var/spool/postfix/,}public/qmgr w, + /{var/spool/postfix/,}incoming/[0-9A-F]* rw, + /{var/spool/postfix/,}private/bounce w, + /{var/spool/postfix/,}private/rewrite rw, + /{var/spool/postfix/,}public/qmgr rw, /{var/spool/postfix/,}hold/[0-9A-F]* w, - + /{var/spool/postfix/,}public/cleanup rw, /{var/spool/postfix/,}pid/unix.cleanup rwk, /etc/{m,fs}tab r, diff --git a/profiles/apparmor/profiles/extras/postfix.master b/profiles/apparmor/profiles/extras/postfix.master index 5e16409b8..c952f7ee9 100644 --- a/profiles/apparmor/profiles/extras/postfix.master +++ b/profiles/apparmor/profiles/extras/postfix.master @@ -19,12 +19,11 @@ profile postfix-master /usr/lib/postfix/{sbin/,}master { capability net_bind_service, capability kill, capability dac_override, + capability dac_read_search, - signal send peer=/usr/lib/postfix/*, signal send peer=postfix-*, signal peer=@{profile_name}, - unix (send receive) type=stream peer=(label=/usr/lib/postfix/*), unix (send receive) type=stream peer=(label=postfix-*), /etc/postfix/master.cf r, diff --git a/profiles/apparmor/profiles/extras/postfix.proxymap b/profiles/apparmor/profiles/extras/postfix.proxymap index e50f707a3..70066e15c 100644 --- a/profiles/apparmor/profiles/extras/postfix.proxymap +++ b/profiles/apparmor/profiles/extras/postfix.proxymap @@ -16,5 +16,6 @@ profile postfix-proxymap /usr/lib/postfix/{sbin/,}proxymap { #include #include - /usr/lib/postfix/{sbin/,}proxymap rmix, + /usr/lib/postfix/{sbin/,}proxymap rmix, + /{var/spool/postfix/,}private/proxymap rw, } diff --git a/profiles/apparmor/profiles/extras/postfix.qmgr b/profiles/apparmor/profiles/extras/postfix.qmgr index 7aa24016f..dbabb7903 100644 --- a/profiles/apparmor/profiles/extras/postfix.qmgr +++ b/profiles/apparmor/profiles/extras/postfix.qmgr @@ -22,6 +22,7 @@ profile postfix-qmgr /usr/lib/postfix/{sbin/,}qmgr { /{var/spool/postfix/,}active/[0-9A-F]/[0-9A-F]/* rwl, /{var/spool/postfix/,}active/[0-9A-F]/[0-9A-F]/ rwl, /{var/spool/postfix/,}active/[0-9A-F]/ rwl, + /{var/spool/postfix/,}active/[0-9A-F]* rwlk, /{var/spool/postfix/,}defer/ r, /{var/spool/postfix/,}defer/[0-9A-F]/[0-9A-F]/* rwl, /{var/spool/postfix/,}defer/[0-9A-F]/[0-9A-F]/ rwl, @@ -34,13 +35,14 @@ profile postfix-qmgr /usr/lib/postfix/{sbin/,}qmgr { /{var/spool/postfix/,}incoming/[0-9A-F]/[0-9A-F]/* rwl, /{var/spool/postfix/,}incoming/[0-9A-F]/[0-9A-F]/ rwl, /{var/spool/postfix/,}incoming/[0-9A-F]/ rwl, + /{var/spool/postfix/,}incoming/[0-9A-F]* rwl, /{var/spool/postfix/,}public/flush w, /{var/spool/postfix/,}public/qmgr r, /{var/spool/postfix/,}private/bounce w, /{var/spool/postfix/,}private/defer w, /{var/spool/postfix/,}private/local w, /{var/spool/postfix/,}private/relay w, - /{var/spool/postfix/,}private/rewrite w, + /{var/spool/postfix/,}private/rewrite rw, /{var/spool/postfix/,}private/smtp w, /{var/spool/postfix/,}private/trace w, /{var/spool/postfix/,}private/uucp w, diff --git a/profiles/apparmor/profiles/extras/postfix.smtpd b/profiles/apparmor/profiles/extras/postfix.smtpd index 25330f638..2f170a8bf 100644 --- a/profiles/apparmor/profiles/extras/postfix.smtpd +++ b/profiles/apparmor/profiles/extras/postfix.smtpd @@ -24,9 +24,9 @@ profile postfix-smtpd /usr/lib/postfix/{sbin/,}smtpd { /usr/sbin/postdrop rPx, /dev/urandom r, - /etc/aliases.db r, + /etc/aliases.db rk, # mailman on SuSE is configured to have its own alias db - /var/lib/mailman/data/aliases.db r, + /var/lib/mailman/data/aliases.db rk, /etc/mtab r, /etc/fstab r, /etc/postfix/*.db r, @@ -38,12 +38,12 @@ profile postfix-smtpd /usr/lib/postfix/{sbin/,}smtpd { /usr/share/ssl/certs/ca-bundle.crt r, - /{var/spool/postfix/,}pid/inet.* rw, - /{var/spool/postfix/,}private/anvil w, - /{var/spool/postfix/,}private/proxymap w, - /{var/spool/postfix/,}private/rewrite w, - /{var/spool/postfix/,}private/tlsmgr w, - /{var/spool/postfix/,}public/cleanup w, + /{var/spool/postfix/,}pid/inet.* rwk, + /{var/spool/postfix/,}private/anvil rw, + /{var/spool/postfix/,}private/proxymap rw, + /{var/spool/postfix/,}private/rewrite rw, + /{var/spool/postfix/,}private/tlsmgr rw, + /{var/spool/postfix/,}public/cleanup rw, /{,var/}run/sasl2/mux w, } diff --git a/profiles/apparmor/profiles/extras/postfix.trivial-rewrite b/profiles/apparmor/profiles/extras/postfix.trivial-rewrite index 01c780102..59dd4b9cc 100644 --- a/profiles/apparmor/profiles/extras/postfix.trivial-rewrite +++ b/profiles/apparmor/profiles/extras/postfix.trivial-rewrite @@ -23,4 +23,5 @@ profile postfix-trivial-rewrite /usr/lib/postfix/{sbin/,}trivial-rewrite { /etc/postfix/virtual.db r, /etc/{m,fs}tab r, /var/spool/postfix/pid/unix.rewrite rw, + /{var/spool/postfix/,}private/rewrite rw, } From 60d203b622c1e098b4e86eb409e319520e4d8b73 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 30 Nov 2018 14:27:47 +0100 Subject: [PATCH 37/46] postfix.local: Minor adjustments to make it work This connects queue manager to local. --- profiles/apparmor/profiles/extras/postfix.local | 12 ++++++++---- profiles/apparmor/profiles/extras/postfix.qmgr | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/profiles/apparmor/profiles/extras/postfix.local b/profiles/apparmor/profiles/extras/postfix.local index d4484b121..0798b2fc4 100644 --- a/profiles/apparmor/profiles/extras/postfix.local +++ b/profiles/apparmor/profiles/extras/postfix.local @@ -29,15 +29,19 @@ profile postfix-local /usr/lib/postfix/{sbin/,}local { /{usr/,}bin/date mixr, /dev/tty rw, - /etc/{postfix/,}aliases.db r, + /etc/{postfix/,}aliases.db rk, # mailman on SuSE is configed to have its own alias file - /var/lib/mailman/data/aliases.db r, + /var/lib/mailman/data/aliases.db rk, /{var/spool/postfix/,}active/[0-9A-F]/[0-9A-F]/* rw, /{var/spool/postfix/,}active/[0-9A-F]/[0-9A-F]/ rw, /{var/spool/postfix/,}active/[0-9A-F]/ rw, - /{var/spool/postfix/,}pid/unix.local rw, - /{var/spool/postfix/,}private/{bounce,defer,flush,lmtp,rewrite} rw, + /{var/spool/postfix/,}active/[0-9A-F]* rwk, + /{var/spool/postfix/,}pid/unix.local rwk, + /{var/spool/postfix/,}private/{bounce,defer,flush,lmtp,local,rewrite} rw, /{var/spool/postfix/,}public/{cleanup,flush} rw, /etc/postfix/virtual.db r, /etc/postfix/lists.db r, + + # deliver mail + /var/mail/* wk, } diff --git a/profiles/apparmor/profiles/extras/postfix.qmgr b/profiles/apparmor/profiles/extras/postfix.qmgr index dbabb7903..f2c044cab 100644 --- a/profiles/apparmor/profiles/extras/postfix.qmgr +++ b/profiles/apparmor/profiles/extras/postfix.qmgr @@ -40,7 +40,7 @@ profile postfix-qmgr /usr/lib/postfix/{sbin/,}qmgr { /{var/spool/postfix/,}public/qmgr r, /{var/spool/postfix/,}private/bounce w, /{var/spool/postfix/,}private/defer w, - /{var/spool/postfix/,}private/local w, + /{var/spool/postfix/,}private/local rw, /{var/spool/postfix/,}private/relay w, /{var/spool/postfix/,}private/rewrite rw, /{var/spool/postfix/,}private/smtp w, From d1ab0a021e1c4b505586091ebdfe3345ebd21030 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 30 Nov 2018 14:33:45 +0100 Subject: [PATCH 38/46] profiles/postfix-pickup: Allow reading from cleanup socket --- profiles/apparmor/profiles/extras/postfix.pickup | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/profiles/apparmor/profiles/extras/postfix.pickup b/profiles/apparmor/profiles/extras/postfix.pickup index b8d40662f..434423743 100644 --- a/profiles/apparmor/profiles/extras/postfix.pickup +++ b/profiles/apparmor/profiles/extras/postfix.pickup @@ -18,7 +18,7 @@ profile postfix-pickup /usr/lib/postfix/{sbin/,}pickup { /usr/lib/postfix/{sbin/,}pickup rmix, - /{var/spool/postfix/,}public/cleanup w, + /{var/spool/postfix/,}public/cleanup rw, /{var/spool/postfix/,}public/pickup r, /{var/spool/postfix/,}maildrop/ r, /{var/spool/postfix/,}maildrop/* rwl, From b858428dd1e7be7a0b571cad3a4bd74f74e1e72c Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 30 Nov 2018 14:38:57 +0100 Subject: [PATCH 39/46] profiles/postdrop: Allow reading from pickup socket --- profiles/apparmor/profiles/extras/usr.sbin.postdrop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/profiles/apparmor/profiles/extras/usr.sbin.postdrop b/profiles/apparmor/profiles/extras/usr.sbin.postdrop index 415ad7b2a..927e87b6b 100644 --- a/profiles/apparmor/profiles/extras/usr.sbin.postdrop +++ b/profiles/apparmor/profiles/extras/usr.sbin.postdrop @@ -30,5 +30,5 @@ /var/spool/postfix/maildrop r, /var/spool/postfix/maildrop/* rwl, /var/spool/postfix/pid r, - /var/spool/postfix/public/pickup w, + /var/spool/postfix/public/pickup rw, } From 4c85a7ec9ec2275d6061c2c819dff3bae0c3710a Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 30 Nov 2018 14:42:23 +0100 Subject: [PATCH 40/46] profiles/postfix-smtpd: Include ssl_certs, ssl_keys This is needed for serving TLS. --- profiles/apparmor/profiles/extras/postfix.smtpd | 2 ++ 1 file changed, 2 insertions(+) diff --git a/profiles/apparmor/profiles/extras/postfix.smtpd b/profiles/apparmor/profiles/extras/postfix.smtpd index 2f170a8bf..dd1d1feac 100644 --- a/profiles/apparmor/profiles/extras/postfix.smtpd +++ b/profiles/apparmor/profiles/extras/postfix.smtpd @@ -16,6 +16,8 @@ profile postfix-smtpd /usr/lib/postfix/{sbin/,}smtpd { #include #include #include + #include + #include capability dac_override, capability dac_read_search, From 40449fdd27d2af6979774facb265773c6e0e28ec Mon Sep 17 00:00:00 2001 From: Steve Beattie Date: Fri, 16 Nov 2018 14:50:38 -0800 Subject: [PATCH 41/46] Make coverity: do all compiles as one scan-build run In fed101920b6fbc7700aaa1175b6dbf88abbf920f, the coverity build process was modified to split out the build logs into separate files, instead of having one log file that gets overwritten repeatedly, making failures hard to debug. However, the coverity service gets upset if there is no file named with the expected build log name. Therefore, instead, we'll capture the python bits first, and then capture all the compilation bits in one cov-build command. PR: https://gitlab.com/apparmor/apparmor/merge_requests/273 Signed-off-by: Steve Beattie Acked-by: Christian Boltz --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index e58004882..4453500ec 100644 --- a/Makefile +++ b/Makefile @@ -54,12 +54,12 @@ snapshot: clean .PHONY: coverity coverity: snapshot cd $(SNAPSHOT_NAME)/libraries/libapparmor && ./configure --with-python - $(foreach dir, $(filter-out utils profiles tests, $(DIRS)), \ - cov-build --dir $(COVERITY_DIR) -- $(MAKE) -C $(SNAPSHOT_NAME)/$(dir); \ - mv $(COVERITY_DIR)/build-log.txt $(COVERITY_DIR)/build-log-$(subst /,.,$(dir)).txt ;) $(foreach dir, libraries/libapparmor utils, \ cov-build --dir $(COVERITY_DIR) --no-command --fs-capture-search $(SNAPSHOT_NAME)/$(dir); \ mv $(COVERITY_DIR)/build-log.txt $(COVERITY_DIR)/build-log-python-$(subst /,.,$(dir)).txt ;) + cov-build --dir $(COVERITY_DIR) -- sh -c \ + "$(foreach dir, $(filter-out utils profiles tests, $(DIRS)), \ + $(MAKE) -C $(SNAPSHOT_NAME)/$(dir);) " tar -cvzf $(SNAPSHOT_NAME)-$(COVERITY_DIR).tar.gz $(COVERITY_DIR) .PHONY: export_dir From fde015435af2978b3a356056d8b957fa0eaa2d49 Mon Sep 17 00:00:00 2001 From: Eric Chiang Date: Wed, 28 Nov 2018 11:04:49 -0800 Subject: [PATCH 42/46] utils: add support to tools for profiles with xattrs Signed-off-by: Eric Chiang --- utils/apparmor/aa.py | 13 +++- utils/apparmor/profile_storage.py | 1 + utils/apparmor/regex.py | 8 ++- utils/test/test-aa.py | 101 +++++++++++++++++++++++++++--- 4 files changed, 110 insertions(+), 13 deletions(-) diff --git a/utils/apparmor/aa.py b/utils/apparmor/aa.py index fd44c8092..ce5eff27a 100644 --- a/utils/apparmor/aa.py +++ b/utils/apparmor/aa.py @@ -683,6 +683,7 @@ def change_profile_flags(prof_filename, program, flag, set_flag): 'flags': newflags, 'profile_keyword': matches['profile_keyword'], 'header_comment': matches['comment'] or '', + 'xattrs': matches['xattrs'], } line = write_header(header_data, len(space)/2, profile, False, True) line = '%s\n' % line[0] @@ -2175,8 +2176,9 @@ def parse_profile_start(line, file, lineno, profile, hat): attachment = matches['attachment'] flags = matches['flags'] + xattrs = matches['xattrs'] - return (profile, hat, attachment, flags, in_contained_hat, pps_set_profile, pps_set_hat_external) + return (profile, hat, attachment, xattrs, flags, in_contained_hat, pps_set_profile, pps_set_hat_external) def parse_profile_data(data, file, do_include): profile_data = hasher() @@ -2204,7 +2206,7 @@ def parse_profile_data(data, file, do_include): lastline = None # Starting line of a profile if RE_PROFILE_START.search(line): - (profile, hat, attachment, flags, in_contained_hat, pps_set_profile, pps_set_hat_external) = parse_profile_start(line, file, lineno, profile, hat) + (profile, hat, attachment, xattrs, flags, in_contained_hat, pps_set_profile, pps_set_hat_external) = parse_profile_start(line, file, lineno, profile, hat) if profile_data[profile].get(hat, False): raise AppArmorException('Profile %(profile)s defined twice in %(file)s, last found in line %(line)s' % @@ -2224,6 +2226,7 @@ def parse_profile_data(data, file, do_include): profile_data[profile][hat]['filename'] = file filelist[file]['profiles'][profile][hat] = True + profile_data[profile][hat]['xattrs'] = xattrs profile_data[profile][hat]['flags'] = flags # Save the initial comment @@ -2634,11 +2637,15 @@ def write_header(prof_data, depth, name, embedded_hat, write_flags): if (not embedded_hat and re.search('^[^/]', unquoted_name)) or (embedded_hat and re.search('^[^^]', unquoted_name)) or prof_data['attachment'] or prof_data['profile_keyword']: name = 'profile %s%s' % (name, attachment) + xattrs = '' + if prof_data['xattrs']: + xattrs = ' xattrs=(%s)' % prof_data['xattrs'] + flags = '' if write_flags and prof_data['flags']: flags = ' flags=(%s)' % prof_data['flags'] - data.append('%s%s%s {%s' % (pre, name, flags, comment)) + data.append('%s%s%s%s {%s' % (pre, name, xattrs, flags, comment)) return data diff --git a/utils/apparmor/profile_storage.py b/utils/apparmor/profile_storage.py index 6ef4ca951..e715e7265 100644 --- a/utils/apparmor/profile_storage.py +++ b/utils/apparmor/profile_storage.py @@ -69,6 +69,7 @@ class ProfileStorage: data['filename'] = '' data['name'] = '' data['attachment'] = '' + data['xattrs'] = '' data['flags'] = '' data['external'] = False data['header_comment'] = '' # currently only set by change_profile_flags() diff --git a/utils/apparmor/regex.py b/utils/apparmor/regex.py index e3cdde365..6df66232d 100644 --- a/utils/apparmor/regex.py +++ b/utils/apparmor/regex.py @@ -30,6 +30,7 @@ RE_PATH = '/\S*|"/[^"]*"' # filename (starting with '/') withou RE_PROFILE_PATH = '(?P<%s>(' + RE_PATH + '))' # quoted or unquoted filename. %s is the match group name RE_PROFILE_PATH_OR_VAR = '(?P<%s>(' + RE_PATH + '|@{\S+}\S*|"@{\S+}[^"]*"))' # quoted or unquoted filename or variable. %s is the match group name RE_SAFE_OR_UNSAFE = '(?P(safe|unsafe))' +RE_XATTRS = '(\s+xattrs\s*=\s*\((?P([^)=]+=[^)=]+\s?)+)\)\s*)?' RE_PROFILE_END = re.compile('^\s*\}' + RE_EOL) RE_PROFILE_CAP = re.compile(RE_AUDIT_DENY + 'capability(?P(\s+\S+)+)?' + RE_COMMA_EOL) @@ -43,7 +44,7 @@ RE_PROFILE_CONDITIONAL_VARIABLE = re.compile('^\s*if\s+(not\s+)?defined\s+(@\{?\ RE_PROFILE_CONDITIONAL_BOOLEAN = re.compile('^\s*if\s+(not\s+)?defined\s+(\$\{?\w+\}?)\s*\{\s*(#.*)?$') RE_PROFILE_NETWORK = re.compile(RE_AUDIT_DENY + 'network(?P
\s+.*)?' + RE_COMMA_EOL) RE_PROFILE_CHANGE_HAT = re.compile('^\s*\^(\"??.+?\"??)' + RE_COMMA_EOL) -RE_PROFILE_HAT_DEF = re.compile('^(?P\s*)(?P\^|hat\s+)(?P\"??.+?\"??)\s+((flags=)?\((?P.+)\)\s+)*\{' + RE_EOL) +RE_PROFILE_HAT_DEF = re.compile('^(?P\s*)(?P\^|hat\s+)(?P\"??[^)]+?\"??)'+RE_XATTRS+'\s+((flags=)?\((?P[^)]+)\)\s+)*\{' + RE_EOL) RE_PROFILE_DBUS = re.compile(RE_AUDIT_DENY + '(dbus\s*,|dbus(?P
\s+[^#]*)\s*,)' + RE_EOL) RE_PROFILE_MOUNT = re.compile(RE_AUDIT_DENY + '((mount|remount|umount|unmount)(\s+[^#]*)?\s*,)' + RE_EOL) RE_PROFILE_SIGNAL = re.compile(RE_AUDIT_DENY + '(signal\s*,|signal(?P
\s+[^#]*)\s*,)' + RE_EOL) @@ -68,7 +69,8 @@ RE_PROFILE_START = re.compile( '|' + # or '(' + 'profile' + '\s+' + RE_PROFILE_NAME % 'namedprofile' + '(\s+' + RE_PROFILE_PATH_OR_VAR % 'attachment' + ')?' + ')' + # 'profile', profile name, optionally attachment ')' + - '\s+((flags\s*=\s*)?\((?P.+)\)\s*)?\{' + + RE_XATTRS + + '\s+((flags\s*=\s*)?\((?P[^)]+)\)\s*)?\{' + RE_EOL) @@ -110,7 +112,7 @@ def parse_profile_start_line(line, filename): result = {} - for section in [ 'leadingspace', 'plainprofile', 'namedprofile', 'attachment', 'flags', 'comment']: + for section in [ 'leadingspace', 'plainprofile', 'namedprofile', 'attachment', 'xattrs', 'flags', 'comment']: if matches.group(section): result[section] = matches.group(section) diff --git a/utils/test/test-aa.py b/utils/test/test-aa.py index 2bccae256..1efa01960 100644 --- a/utils/test/test-aa.py +++ b/utils/test/test-aa.py @@ -511,32 +511,42 @@ class AaTest_parse_profile_start(AATest): def test_parse_profile_start_01(self): result = self._parse('/foo {', None, None) - expected = ('/foo', '/foo', None, None, False, False, False) + expected = ('/foo', '/foo', None, None, None, False, False, False) self.assertEqual(result, expected) def test_parse_profile_start_02(self): result = self._parse('/foo (complain) {', None, None) - expected = ('/foo', '/foo', None, 'complain', False, False, False) + expected = ('/foo', '/foo', None, None, 'complain', False, False, False) self.assertEqual(result, expected) def test_parse_profile_start_03(self): result = self._parse('profile foo /foo {', None, None) # named profile - expected = ('foo', 'foo', '/foo', None, False, False, False) + expected = ('foo', 'foo', '/foo', None, None, False, False, False) self.assertEqual(result, expected) def test_parse_profile_start_04(self): result = self._parse('profile /foo {', '/bar', '/bar') # child profile - expected = ('/bar', '/foo', None, None, True, True, False) + expected = ('/bar', '/foo', None, None, None, True, True, False) self.assertEqual(result, expected) def test_parse_profile_start_05(self): result = self._parse('/foo//bar {', None, None) # external hat - expected = ('/foo', 'bar', None, None, False, False, True) + expected = ('/foo', 'bar', None, None, None, False, False, True) self.assertEqual(result, expected) def test_parse_profile_start_06(self): result = self._parse('profile "/foo" (complain) {', None, None) - expected = ('/foo', '/foo', None, 'complain', False, False, False) + expected = ('/foo', '/foo', None, None, 'complain', False, False, False) + self.assertEqual(result, expected) + + def test_parse_profile_start_07(self): + result = self._parse('profile "/foo" xattrs=(user.bar=bar) {', None, None) + expected = ('/foo', '/foo', None, 'user.bar=bar', None, False, False, False) + self.assertEqual(result, expected) + + def test_parse_profile_start_08(self): + result = self._parse('profile "/foo" xattrs=(user.bar=bar user.foo=*) {', None, None) + expected = ('/foo', '/foo', None, 'user.bar=bar user.foo=*', None, False, False, False) self.assertEqual(result, expected) def test_parse_profile_start_unsupported_01(self): @@ -566,6 +576,44 @@ class AaTest_parse_profile_data(AATest): # file contains two profiles with the same name parse_profile_data('profile /foo {\n}\nprofile /foo {\n}\n'.split(), 'somefile', False) + def test_parse_xattrs_01(self): + prof = parse_profile_data('/foo xattrs=(user.bar=bar) {\n}\n'.split(), 'somefile', False) + + self.assertEqual(list(prof.keys()), ['/foo']) + self.assertEqual(list(prof['/foo'].keys()), ['/foo']) + self.assertEqual(prof['/foo']['/foo']['name'], '/foo') + self.assertEqual(prof['/foo']['/foo']['filename'], 'somefile') + self.assertEqual(prof['/foo']['/foo']['flags'], None) + 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) + + self.assertEqual(list(prof.keys()), ['/foo']) + self.assertEqual(list(prof['/foo'].keys()), ['/foo']) + self.assertEqual(prof['/foo']['/foo']['name'], '/foo') + self.assertEqual(prof['/foo']['/foo']['filename'], 'somefile') + self.assertEqual(prof['/foo']['/foo']['flags'], None) + self.assertEqual(prof['/foo']['/foo']['xattrs'], 'user.bar=bar user.foo=*') + + def test_parse_xattrs_03(self): + d = '/foo xattrs=(user.bar=bar) flags=(complain) {\n}\n' + prof = parse_profile_data(d.split(), 'somefile', False) + + self.assertEqual(list(prof.keys()), ['/foo']) + self.assertEqual(list(prof['/foo'].keys()), ['/foo']) + self.assertEqual(prof['/foo']['/foo']['name'], '/foo') + self.assertEqual(prof['/foo']['/foo']['filename'], 'somefile') + self.assertEqual(prof['/foo']['/foo']['flags'], 'complain') + self.assertEqual(prof['/foo']['/foo']['xattrs'], 'user.bar=bar') + + def test_parse_xattrs_04(self): + with self.assertRaises(AppArmorException): + # flags before xattrs + d = '/foo flags=(complain) xattrs=(user.bar=bar) {\n}\n' + parse_profile_data(d.split(), 'somefile', False) + + class AaTest_separate_vars(AATest): tests = [ ('' , set() ), @@ -669,11 +717,50 @@ class AaTest_write_header(AATest): embedded_hat = params[1] write_flags = params[2] depth = params[3] - prof_data = { 'flags': params[4], 'attachment': params[5], 'profile_keyword': params[6], 'header_comment': params[7] } + prof_data = { 'flags': params[4], 'attachment': params[5], 'profile_keyword': params[6], 'header_comment': params[7], 'xattrs': '' } result = write_header(prof_data, depth, name, embedded_hat, write_flags) self.assertEqual(result, [expected]) +class AaTest_write_header_01(AATest): + tests = [ + ( + {'name': '/foo', 'write_flags': True, 'depth': 1, 'flags': 'complain'}, + ' /foo flags=(complain) {', + ), + ( + {'name': '/foo', 'write_flags': True, 'depth': 1, 'flags': 'complain', 'profile_keyword': 'profile'}, + ' profile /foo flags=(complain) {', + ), + ( + {'name': '/foo', 'write_flags': True, 'flags': 'complain'}, + '/foo flags=(complain) {', + ), + ( + {'name': '/foo', 'xattrs': 'user.foo=bar', 'write_flags': True, 'flags': 'complain'}, + '/foo xattrs=(user.foo=bar) flags=(complain) {', + ), + ( + {'name': '/foo', 'xattrs': 'user.foo=bar', 'embedded_hat': True}, + 'profile /foo xattrs=(user.foo=bar) {', + ), + ] + + def _run_test(self, params, expected): + name = params['name'] + embedded_hat = params.get('embedded_hat', False) + write_flags = params.get('write_flags', False) + depth = params.get('depth', 0) + prof_data = { + 'xattrs': params.get('xattrs', None), + 'flags': params.get('flags', None), + 'attachment': params.get('attachment', None), + 'profile_keyword': params.get('profile_keyword', None), + 'header_comment': params.get('header_comment', None), + } + result = write_header(prof_data, depth, name, embedded_hat, write_flags) + self.assertEqual(result, [expected]) + class AaTest_get_file_perms_1(AATest): tests = [ ('/usr/share/common-licenses/foo/bar', {'allow': {'all': set(), 'owner': {'w'} }, 'deny': {'all':set(), 'owner': set()}, 'paths': {'/usr/share/common-licenses/**'} }), From 2202a8a267111266b74a7c9fd4bbc89a5f334d6a Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Thu, 6 Dec 2018 18:12:25 +0100 Subject: [PATCH 43/46] dovecot: allow reading /proc/sys/fs/suid_dumpable This is needed if a dovecot child process segfaults - in this case, dovecot provides a helpful error message like dovecot[6179]: auth-worker: Fatal: master: service(auth-worker): child 8103 killed with signal 11 (core not dumped - https://dovecot.org/bugreport.html#coredumps - set /proc/sys/fs/suid_dumpable to 2) which involves reading the current value in suid_dumpable. --- profiles/apparmor.d/usr.sbin.dovecot | 1 + 1 file changed, 1 insertion(+) diff --git a/profiles/apparmor.d/usr.sbin.dovecot b/profiles/apparmor.d/usr.sbin.dovecot index 579b3100a..8eced4a64 100644 --- a/profiles/apparmor.d/usr.sbin.dovecot +++ b/profiles/apparmor.d/usr.sbin.dovecot @@ -38,6 +38,7 @@ profile dovecot /usr/{bin,sbin}/dovecot flags=(attach_disconnected) { /etc/lsb-release r, /etc/SuSE-release r, @{PROC}/@{pid}/mounts r, + @{PROC}/sys/fs/suid_dumpable r, /usr/bin/doveconf rix, /usr/lib/dovecot/anvil mrPx, /usr/lib/dovecot/auth mrPx, From 0d830fae31a8aa2f1397b1b654a4c73b5858e6fe Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Thu, 6 Dec 2018 21:56:33 +0100 Subject: [PATCH 44/46] Split out RE_FLAGS ... instead of having it duplicated in RE_PROFILE_HAT_DEF and RE_PROFILE_START. Note that the flags=... handling in RE_PROFILE_HAT_DEF was more/too strict (for example it didn't allow whitespace around the "="), so this change also qualifies as a little bugfix. --- utils/apparmor/regex.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/utils/apparmor/regex.py b/utils/apparmor/regex.py index 6df66232d..4d16fb8f9 100644 --- a/utils/apparmor/regex.py +++ b/utils/apparmor/regex.py @@ -31,6 +31,7 @@ RE_PROFILE_PATH = '(?P<%s>(' + RE_PATH + '))' # quoted or unquoted file RE_PROFILE_PATH_OR_VAR = '(?P<%s>(' + RE_PATH + '|@{\S+}\S*|"@{\S+}[^"]*"))' # quoted or unquoted filename or variable. %s is the match group name RE_SAFE_OR_UNSAFE = '(?P(safe|unsafe))' RE_XATTRS = '(\s+xattrs\s*=\s*\((?P([^)=]+=[^)=]+\s?)+)\)\s*)?' +RE_FLAGS = '(\s+(flags\s*=\s*)?\((?P[^)]+)\))?' RE_PROFILE_END = re.compile('^\s*\}' + RE_EOL) RE_PROFILE_CAP = re.compile(RE_AUDIT_DENY + 'capability(?P(\s+\S+)+)?' + RE_COMMA_EOL) @@ -44,7 +45,7 @@ RE_PROFILE_CONDITIONAL_VARIABLE = re.compile('^\s*if\s+(not\s+)?defined\s+(@\{?\ RE_PROFILE_CONDITIONAL_BOOLEAN = re.compile('^\s*if\s+(not\s+)?defined\s+(\$\{?\w+\}?)\s*\{\s*(#.*)?$') RE_PROFILE_NETWORK = re.compile(RE_AUDIT_DENY + 'network(?P
\s+.*)?' + RE_COMMA_EOL) RE_PROFILE_CHANGE_HAT = re.compile('^\s*\^(\"??.+?\"??)' + RE_COMMA_EOL) -RE_PROFILE_HAT_DEF = re.compile('^(?P\s*)(?P\^|hat\s+)(?P\"??[^)]+?\"??)'+RE_XATTRS+'\s+((flags=)?\((?P[^)]+)\)\s+)*\{' + RE_EOL) +RE_PROFILE_HAT_DEF = re.compile('^(?P\s*)(?P\^|hat\s+)(?P\"??[^)]+?\"??)' + RE_XATTRS + RE_FLAGS + '\s*\{' + RE_EOL) RE_PROFILE_DBUS = re.compile(RE_AUDIT_DENY + '(dbus\s*,|dbus(?P
\s+[^#]*)\s*,)' + RE_EOL) RE_PROFILE_MOUNT = re.compile(RE_AUDIT_DENY + '((mount|remount|umount|unmount)(\s+[^#]*)?\s*,)' + RE_EOL) RE_PROFILE_SIGNAL = re.compile(RE_AUDIT_DENY + '(signal\s*,|signal(?P
\s+[^#]*)\s*,)' + RE_EOL) @@ -70,7 +71,8 @@ RE_PROFILE_START = re.compile( '(' + 'profile' + '\s+' + RE_PROFILE_NAME % 'namedprofile' + '(\s+' + RE_PROFILE_PATH_OR_VAR % 'attachment' + ')?' + ')' + # 'profile', profile name, optionally attachment ')' + RE_XATTRS + - '\s+((flags\s*=\s*)?\((?P[^)]+)\)\s*)?\{' + + RE_FLAGS + + '\s*\{' + RE_EOL) From 3ef8df6ac05057e46720b2eba099bad3416f763b Mon Sep 17 00:00:00 2001 From: Petr Vorel Date: Fri, 7 Dec 2018 23:40:19 +0100 Subject: [PATCH 45/46] dnsmasq: Adjust pattern for log files to comply SELinux i.e. move '*' from beginning to before suffix. Commit 025c7dc6 ("dnsmasq: Add permission to open log files") added pattern, which is not compatible with SELinux. As this pattern has been in SELinux since 2011 (with recent change to accept '.log' suffix + logrotate patterns which are not relevant to AppArmor) IMHO it's better to adjust our profile. Fixes: 025c7dc6 ("dnsmasq: Add permission to open log files") Signed-off-by: Petr Vorel --- profiles/apparmor.d/usr.sbin.dnsmasq | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/profiles/apparmor.d/usr.sbin.dnsmasq b/profiles/apparmor.d/usr.sbin.dnsmasq index fba51259d..f14a370a2 100644 --- a/profiles/apparmor.d/usr.sbin.dnsmasq +++ b/profiles/apparmor.d/usr.sbin.dnsmasq @@ -45,7 +45,7 @@ profile dnsmasq /usr/{bin,sbin}/dnsmasq flags=(attach_disconnected) { /usr/{bin,sbin}/dnsmasq mr, - /var/log/*dnsmasq.log w, + /var/log/dnsmasq*.log w, /usr/share/dnsmasq/ r, /usr/share/dnsmasq/* r, From 49848b90817a923c9cf3f6ee534d02442bf0ff80 Mon Sep 17 00:00:00 2001 From: Petr Vorel Date: Fri, 7 Dec 2018 23:42:53 +0100 Subject: [PATCH 46/46] dnsmasq: Add pid file used by NetworkManager Signed-off-by: Petr Vorel --- profiles/apparmor.d/usr.sbin.dnsmasq | 1 + 1 file changed, 1 insertion(+) diff --git a/profiles/apparmor.d/usr.sbin.dnsmasq b/profiles/apparmor.d/usr.sbin.dnsmasq index f14a370a2..a308e3f71 100644 --- a/profiles/apparmor.d/usr.sbin.dnsmasq +++ b/profiles/apparmor.d/usr.sbin.dnsmasq @@ -96,6 +96,7 @@ profile dnsmasq /usr/{bin,sbin}/dnsmasq flags=(attach_disconnected) { /{,var/}run/sendsigs.omit.d/*dnsmasq.pid w, /{,var/}run/NetworkManager/dnsmasq.conf r, /{,var/}run/NetworkManager/dnsmasq.pid w, + /{,var/}run/NetworkManager/NetworkManager.pid w, profile libvirt_leaseshelper { #include