aa-unconfined fails when AppArmor is not the first major LSM module.
Note: Suggested trivial fix below.
Traceback (most recent call last): File "/usr/bin/aa-unconfined", line 132, in <module> attr = read_proc_current("/proc/%s/attr/current" % pid) File "/usr/bin/aa-unconfined", line 107, in read_proc_current for line in current: File "/usr/lib/python3.9/codecs.py", line 714, in __next__ return next(self.reader) File "/usr/lib/python3.9/codecs.py", line 645, in __next__ line = self.readline() File "/usr/lib/python3.9/codecs.py", line 558, in readline data = self.read(readsize, firstline=True) File "/usr/lib/python3.9/codecs.py", line 498, in read newdata = self.stream.read(size) OSError: [Errno 22] Invalid argument
I decided to debug this myself and figured out that the following happens:
aa-unconfined fails as it tries to read /proc/<PID>/attr/current
instead of /proc/<PID>/attr/apparmor/current
. This appears to be a fallback path that is incorrectly fallen back to. AppArmor was not set as the first major LSM module:
% cat /sys/kernel/security/lsm
capability,landlock,lockdown,yama,bpf,apparmor
Thus, attr/current (as opposed to attr/apparmor/current) didn't actually. AppArmor itself appears to be fully functional though (though I will change the LSM order after this).
Still, since this is a fallback instead of attr/apparmor/current fails, it seemed strange. Attached with ipython pdb debugger I got this when manually executing the non-fallback command:
ipdb> interact
*interactive*
In : type(read_proc_current("/proc/%s/attr/apparmor/current" % pid))
<class 'NoneType'>
This is for pid=1. Yet if I check this file manually it works perfectly:
# cat /proc/1/attr/apparmor/current
unconfined
The problem seems to lie in the logic in read_proc_current:
if line.endswith(' (complain)', 1) or line.endswith(' (enforce)', 1) or line.endswith(' (kill)', 1)
Due to this condition, "unconfined" will be treated the same as a failure to read the file. Because of this, and that the bpf LSM results in attr/current being non-readable, aa-unconfined fails.
Suggested fix: The first should be quite easy, simply modify the if statement in read_proc_current() in aa-unconfined to handle unconfined properly. To address the issue in the comment about not wanting confusing "(unconfined)" another option would be to catch exceptions, or to add separate return values for unconfined vs errors.
System info
- Distro: Arch Linux (rolling release distro, so no version)
# pacman -Qi apparmor
Name : apparmor
Version : 3.0.3-1