For a little over a year, AppArmor has been broken on some distributions because of a two line bug that can be found here.
On a default Ubuntu 24.04.1 LTS installation, trying to run aa-enforce /etc/apparmor.d/*
to enable apparmor profiles fails with:
Traceback (most recent call last): File "/usr/sbin/aa-enforce", line 33,
in tool.cmd_enforce()
File "/usr/lib/python3/dist-packages/apparmor/tools.py", line 134,
in cmd_enforce for (program, prof_filename, output_name) in
self.get_next_for_modechange():
File "/usr/lib/python3/dist-packages/apparmor/tools.py", line 97,
in get_next_for_modechange aaui.UI_Info(_('Profile for %s
not found, skipping') % output_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: 'NoneType' object is not callable
An unexpected error occurred!
The bug has been fixed in AppArmor but the patch hasn't been pushed upstream to Ubuntu yet. If we pull down the raw corrected file, we can diff and patch and get AppArmor running again. The raw fixed file can be found on Gitlab here.
Let's make a copy of our old tools.py file, just in case. We'll save it to tools.py_backup
and then download the new updated version. And finally, diff, patch, and test the new file:
$ cp /usr/lib/python3/dist-packages/apparmor/tools.py /usr/lib/python3/dist-packages/apparmor/tools.py_backup
$ wget https://gitlab.com/apparmor/apparmor/-/raw/6f9e841e74f04cac78da71fd2e8af3f973af94fc/utils/apparmor/tools.py -O /tmp/tools.py
$ diff /usr/lib/python3/dist-packages/apparmor/tools.py /tmp/tools.py
93c93
< for (program, _, prof_filename) in self.get_next_to_profile():
---
> for (program, _ignored, prof_filename) in self.get_next_to_profile():
165c165
< for (program, _, prof_filename) in self.get_next_to_profile():
---
> for (program, _ignored, prof_filename) in self.get_next_to_profile():
Nice, we can clearly see the same changes in the AppArmor github repo at commit 6f9e841e.
Diff, Patch, Repeat
If we wanted to create a patch file, we could do so by just saving the diff to an output file, like so:
$ diff -u /usr/lib/python3/dist-packages/apparmor/tools.py /tmp/tools.py > /tmp/fix.diff
$ cat /tmp/fix.diff
--- /usr/lib/python3/dist-packages/apparmor/tools.py 2024-11-29 20:48:05.365220486 -0500
+++ /tmp/tools.py 2025-02-18 09:39:34.016987110 -0500
@@ -90,7 +90,7 @@
def get_next_for_modechange(self):
"""common code for mode/flags changes"""
- for (program, _, prof_filename) in self.get_next_to_profile():
+ for (program, _ignored, prof_filename) in self.get_next_to_profile():
output_name = prof_filename if program is None else program
if not os.path.isfile(prof_filename) or is_skippable_file(prof_filename):
@@ -162,7 +162,7 @@
def cmd_autodep(self):
apparmor.loadincludes()
- for (program, _, prof_filename) in self.get_next_to_profile():
+ for (program, _ignored, prof_filename) in self.get_next_to_profile():
if not program:
aaui.UI_Info(_('Please pass an application to generate a profile for, not a profile itself - skipping %s.') % prof_filename)
continue
Afterward, we could patch the file like so:
$ patch /usr/lib/python3/dist-packages/apparmor/tools.py /tmp/fix.diff
Or, simply:
$ patch < /tmp/fix.diff
Similarly, we could also reverse the patch with the -R
flag and the diff file:
$ patch -R /usr/lib/python3/dist-packages/apparmor/tools.py /tmp/fix.diff
After applying the AppArmor patch, we can enable apparmor-profiles
successfully again with the aa-enforce
tool:
$ sudo aa-enforce /etc/apparmor.d/*
Setting /etc/apparmor.d/1password to enforce mode.
Profile for /etc/apparmor.d/abi not found, skipping
Profile for /etc/apparmor.d/abstractions not found, skipping
Profile for /etc/apparmor.d/apache2.d not found, skipping
Setting /etc/apparmor.d/balena-etcher to enforce mode.
Setting /etc/apparmor.d/bin.ping to enforce mode.
...
No comments:
Post a Comment