“Enabled” does not mean “Protected.” Recent kernel vulnerabilities, including cases like USN-8098-1, show that a service can stay active while the policies it enforces are quietly swapped underneath it.
This isn’t a bypass in the traditional sense. It’s profile manipulation at the kernel level. In certain scenarios, an unprivileged user can alter loaded rules without triggering alerts. Monitoring still reports “Enforcing,” but the kernel is no longer running the policy you have on disk.
That’s why checking status is no longer enough. You need to verify that what’s in memory still matches what you deployed.
Tools like aa-status or systemctl status apparmor report state, not integrity. They confirm the service is active, but they cannot tell you whether the active profile matches the one on disk.
To actually verify AppArmor is working, you need to compare what’s on disk with what the kernel is enforcing in memory. That means checking the active profiles directly, validating them against a known baseline, and watching for live profile replacement events.
|
Check |
What it tells you |
What you should be asking |
|
|
AppArmor is active |
Are these the original profiles? |
|
|
Service is running |
Have profiles been altered? |
|
Kernel profile list |
Profiles are loaded |
Are the rules intact? |
If a profile is modified through a kernel flaw, these checks can still return a healthy status while the system applies a different ruleset than what’s on disk.
AppArmor does not continuously re-validate /etc/apparmor.d/ against what the kernel is enforcing. Once a profile is loaded, the kernel treats it as the source of truth.
If that in-memory version is altered, enforcement continues cleanly, just with different rules. The profile name stays the same and still shows as enforced, but the rules behind it no longer match what was deployed.
What that looks like in practice:
Where this tends to surface:
If you’re stacking LSMs like SELinux or BPF-LSM, you may have partial coverage. Unless you’ve verified overlap at the rule level, assume the AppArmor layer is your primary control and treat compromise accordingly.
Containers isolate processes, not enforcement. AppArmor still operates at the kernel level, and every container on a host depends on that same decision layer.
If a profile is altered in memory, whether through a kernel flaw or misconfiguration, the change doesn’t stay contained. It applies everywhere that the profile is used.
Think of the kernel as the landlord and AppArmor as the locks on each door. The locks can still be in place, but if the landlord has been compromised, the rules behind those locks no longer mean much.
That shows up in places where isolation is assumed to hold:
From the outside, processes still show as confined. The difference is in what those profiles now allow. The enforcement boundary has already shifted. The kernel is still making decisions, just not the ones you expect.
Checking if AppArmor is running is just a heartbeat check. This is how you verify what it’s actually enforcing.
Start with processes that should never be unconfined:
ps -Z | grep unconfined
Focus on:
If any of these show as unconfined, something is already out of alignment. Also, watch for profiles running in complain mode, since that’s how restrictions get relaxed without breaking execution.

Compare what’s on disk versus what’s loaded:
ls /etc/apparmor.d/ | wc -l
aa-status
These numbers won’t match exactly, and they’re not supposed to. Profiles can expand, load dynamically, or originate from different paths.
What matters is consistency.
Capture a baseline from a known-good system, then monitor for:
If something feels off, reload profiles directly:
sudo apparmor_parser -r /etc/apparmor.d/*
This replaces whatever is currently in memory with what’s on disk.
To see what the kernel is enforcing right now:
cat /sys/kernel/security/apparmor/profiles
That’s your source of truth. Everything else is reporting around it.
Profile manipulation doesn’t raise alerts. It leaves traces in audit logs.
Focus on these events:
sudo grep 'apparmor="STATUS"' /var/log/audit/audit.log
sudo grep 'apparmor="REPLACED"' /var/log/audit/audit.log
That REPLACED event is the signal. It confirms that a profile changed without a restart, which lines up with how in-memory manipulation behaves.
These entries won't stop the system; they just record what happened. This log acts like a black box you come back to when something doesn't line up. If you want to see how these events are handled and what AppArmor actually logs in practice, the AppArmor project documentation covers how profile loads, replacements, and enforcement changes show up.
A green status is just a heartbeat. It says nothing about integrity.
If you’re not:
You’re relying on the assumption that memory and disk are still aligned. That assumption is exactly what these vulnerabilities exploit. Stop asking if AppArmor is running and start verifying what the kernel is actually enforcing.
Because in the end, your security posture doesn’t depend on the service being active. It depends on whether the rules in memory still match the rules you trust.