diff --git a/libraries/libapparmor/testsuite/test_multi/testcase_changeprofile_02.err b/libraries/libapparmor/testsuite/test_multi/testcase_changeprofile_02.err new file mode 100644 index 000000000..e69de29bb diff --git a/libraries/libapparmor/testsuite/test_multi/testcase_changeprofile_02.in b/libraries/libapparmor/testsuite/test_multi/testcase_changeprofile_02.in new file mode 100644 index 000000000..6d4b73835 --- /dev/null +++ b/libraries/libapparmor/testsuite/test_multi/testcase_changeprofile_02.in @@ -0,0 +1 @@ +type=AVC msg=audit(1598805776.452:88586): apparmor="DENIED" operation="change_profile" profile="php-fpm" name="php-fpm//webapp" pid=825 comm="php-fpm" target="php-fpm//webapp" diff --git a/libraries/libapparmor/testsuite/test_multi/testcase_changeprofile_02.out b/libraries/libapparmor/testsuite/test_multi/testcase_changeprofile_02.out new file mode 100644 index 000000000..df781659c --- /dev/null +++ b/libraries/libapparmor/testsuite/test_multi/testcase_changeprofile_02.out @@ -0,0 +1,12 @@ +START +File: testcase_changeprofile_02.in +Event type: AA_RECORD_DENIED +Audit ID: 1598805776.452:88586 +Operation: change_profile +Profile: php-fpm +Name: php-fpm//webapp +Command: php-fpm +Name2: php-fpm//webapp +PID: 825 +Epoch: 1598805776 +Audit subid: 88586 diff --git a/libraries/libapparmor/testsuite/test_multi/testcase_changeprofile_02.profile b/libraries/libapparmor/testsuite/test_multi/testcase_changeprofile_02.profile new file mode 100644 index 000000000..0e5c17290 --- /dev/null +++ b/libraries/libapparmor/testsuite/test_multi/testcase_changeprofile_02.profile @@ -0,0 +1,4 @@ +profile php-fpm { + change_profile -> php-fpm//webapp, + +} diff --git a/utils/apparmor/aa.py b/utils/apparmor/aa.py index 10ca78251..39fc9a70e 100644 --- a/utils/apparmor/aa.py +++ b/utils/apparmor/aa.py @@ -1611,6 +1611,11 @@ def collapse_log(hashlog, ignore_null_profiles=True): if not hat_exists or not is_known_rule(aa[profile][hat], 'capability', cap_event): log_dict[aamode][profile][hat]['capability'].add(cap_event) + for cp in hashlog[aamode][full_profile]['change_profile'].keys(): + cp_event = ChangeProfileRule(None, ChangeProfileRule.ALL, cp, log_event=True) + if not hat_exists or not is_known_rule(aa[profile][hat], 'change_profile', cp_event): + log_dict[aamode][profile][hat]['change_profile'].add(cp_event) + dbus = hashlog[aamode][full_profile]['dbus'] for access in dbus: for bus in dbus[access]: diff --git a/utils/apparmor/logparser.py b/utils/apparmor/logparser.py index 041dff4f7..a64b64b10 100644 --- a/utils/apparmor/logparser.py +++ b/utils/apparmor/logparser.py @@ -49,6 +49,7 @@ class ReadLog: 'final_name': profile, # might be changed for null-* profiles based on exec decisions 'capability': {}, # flat, no hasher needed 'change_hat': {}, # flat, no hasher needed + 'change_profile': {}, # flat, no hasher needed (at least in logparser which doesn't support EXEC MODE and EXEC COND) 'dbus': hasher(), 'exec': hasher(), 'network': hasher(), @@ -230,6 +231,10 @@ class ReadLog: self.hashlog[aamode][full_profile]['change_hat'][e['name2']] = True return None + elif e['operation'] == 'change_profile': + self.hashlog[aamode][full_profile]['change_profile'][e['name2']] = True + return None + elif e['operation'] == 'ptrace': if not e['peer']: self.debug_logger.debug('ignored garbage ptrace event with empty peer') diff --git a/utils/test/test-libapparmor-test_multi.py b/utils/test/test-libapparmor-test_multi.py index 60dbef40f..1c61eef9e 100644 --- a/utils/test/test-libapparmor-test_multi.py +++ b/utils/test/test-libapparmor-test_multi.py @@ -151,9 +151,6 @@ log_to_skip = [ # tests that do not produce the expected profile (checked with assertNotEqual) log_to_profile_known_failures = [ - 'testcase_dmesg_changeprofile_01', # change_profile not yet supported in logparser - 'testcase_changeprofile_01', # change_profile not yet supported in logparser - 'testcase_mount_01', # mount rules not yet supported in logparser 'testcase_pivotroot_01', # pivot_rot not yet supported in logparser @@ -178,12 +175,10 @@ log_to_profile_skip = [ # tests that cause an empty log log_to_profile_known_empty_log = [ 'change_onexec_lp1648143', # change_onexec not supported in logparser.py yet (and the log is about "no new privs" error) - 'testcase_changeprofile_01', # change_profile not supported in logparser.py yet 'testcase_mount_01', # mount rules not supported in logparser 'testcase_pivotroot_01', # pivotroot not yet supported in logparser 'ptrace_garbage_lp1689667_1', # no denied= in log 'ptrace_no_denied_mask', # no denied= in log - 'testcase_dmesg_changeprofile_01', # change_profile not yet supported in logparser 'unconfined-change_hat', # unconfined trying to change_hat, which isn't allowed ]