From d8e86fee75ff03c45abab9a90751eca54bf2d76d Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Sun, 6 Oct 2024 16:45:54 +0200 Subject: [PATCH] Add aa-complain tests for profile with hats and subprofiles So far, change_profile_flags() in aa.py is the only user of ProfileStorage's 'name'. Rewrite minitools test_cleanprof() so that most of its code can be reused, and add a test that runs 'aa-complain /usr/bin/a/simple/cleanprof/test/profile' on cleanprof.in to ensure aa-complain still works as expected on subprofiles and hats. Note: aa-complain $profilename will change the flags of hats, but not child profiles. This is a known issue, and doesn't change with this MR. --- utils/test/cleanprof_test.complain | 98 ++++++++++++++++++++++++++++++ utils/test/test-minitools.py | 34 ++++++++--- 2 files changed, 124 insertions(+), 8 deletions(-) create mode 100644 utils/test/cleanprof_test.complain diff --git a/utils/test/cleanprof_test.complain b/utils/test/cleanprof_test.complain new file mode 100644 index 000000000..ec9879302 --- /dev/null +++ b/utils/test/cleanprof_test.complain @@ -0,0 +1,98 @@ +# A simple test comment which will persist +#include + +#include if exists + + #include if exists + include if exists + + alias /foo -> /bar , + +@{xy} = y x + + abi , + + @{asdf} = foo "" + +$foo = false + + $bar = true + +/usr/bin/a/simple/cleanprof/test/profile flags=(complain) { + # Just for the heck of it, this comment won't see the day of light + #include + +#include if exists + #include if exists + include + + capability sys_admin, + audit capability, + + change_profile -> /bin/foo, + change_profile, + + network inet stream, + abi "abi/4.20" , + network stream, + + #Below rule comes from abstractions/base + allow /usr/share/X11/locale/** r, + allow /home/*/** r, + + ptrace tracedby peer=/bin/strace, + ptrace tracedby, + unix (receive) type=dgram, + + dbus send bus=session, + dbus send bus=session peer=(label=foo), + + profile test_child /foobar { + /etc/child rw, + } + + set rlimit nofile <= 256, + set rlimit nofile <= 64, + + signal set=(hup int quit ill trap abrt) + set=(bus,fpe,,,kill,usr1) + set=segv set=usr2 set=pipe set=alrm set=term set=stkflt set=chld, + signal set=(hup int quit), + + ^foo flags=(complain) { + /etc/fstab r, + capability dac_override, + } + + ^foo, # hat declarations are obsolete and will be removed when aa-cleanprof or aa-logprof writes the profile + + mount options=(rw,suid) /c -> /3, + + hat bar flags=(complain) { + /etc/passwd r, + capability sys_admin, + } + + pivot_root oldroot=/mnt/root/old/, + + deny owner link /some/thing -> /foo/bar , + unix shutdown addr=@HypotheticalServiceDaemon, # covered in abstractions/base, will be removed + + link subset /alpha/beta -> /tmp/**, + + allow /home/foo/bar r, + allow /home/foo/** w, +} + +/usr/bin/other/cleanprof/test/profile { + # This one shouldn't be affected by the processing + # However this comment will be wiped, need to change that + allow /home/*/** rw, + allow /home/foo/bar r, +} + +/what/ever/xattr xattrs=( foo=bar ) + flags=( complain + ) { + /what/ever r, + } diff --git a/utils/test/test-minitools.py b/utils/test/test-minitools.py index c6e8b0d24..b74bed8b1 100755 --- a/utils/test/test-minitools.py +++ b/utils/test/test-minitools.py @@ -199,26 +199,44 @@ class MinitoolsTest(AATest): self.assertIsNot(output_force, '', 'Failed to run aa-unconfined in paranoid mode') - def test_cleanprof(self): + def _test_with_cleanprof_profile(self, command, output_file, errormsg, delete_first_line): input_file = 'cleanprof_test.in' - output_file = 'cleanprof_test.out' + profile = '/usr/bin/a/simple/cleanprof/test/profile' # We position the local testfile shutil.copy('./' + input_file, self.profile_dir) - # Our silly test program whose profile we wish to clean - cleanprof_test = '/usr/bin/a/simple/cleanprof/test/profile' subprocess.check_output( - '{} ./../aa-cleanprof --no-reload -d {} -s {} --configdir ./'.format( - python_interpreter, self.profile_dir, cleanprof_test), + '{} ./../{} --no-reload -d {} {} --configdir ./'.format( + python_interpreter, command, self.profile_dir, profile), shell=True) # Strip off the first line (#modified line) - subprocess.check_output('sed -i 1d {}/{}'.format(self.profile_dir, input_file), shell=True) + if delete_first_line: + subprocess.check_output('sed -i 1d {}/{}'.format(self.profile_dir, input_file), shell=True) exp_content = read_file('./' + output_file) real_content = read_file('{}/{}'.format(self.profile_dir, input_file)) self.maxDiff = None - self.assertEqual(exp_content, real_content, 'Failed to cleanup profile properly') + self.assertEqual(exp_content, real_content, errormsg) + + def test_cleanprof(self): + ''' run aa-cleanprof on cleanprof.in and check if it matches cleanprof.out ''' + + command = 'aa-cleanprof -s' + output_file = 'cleanprof_test.out' + errormsg = 'Failed to cleanup profile properly' + + self._test_with_cleanprof_profile(command, output_file, errormsg, True) + + def test_complain_cleanprof(self): + ''' test if all child profiles in cleanprof_test.in get the complain flag added when switching the profile to complain mode ''' + # TODO: works for hats, but not for child profiles + + command = 'aa-complain' + output_file = 'cleanprof_test.complain' + errormsg = 'Failed to switch profile to complain mode' + + self._test_with_cleanprof_profile(command, output_file, errormsg, False) setup_aa(apparmor)