profiles/apparmor: add basic unit-test for IsLoaded

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn
2025-04-12 13:25:56 +02:00
parent 0dd5959eeb
commit b23d267cb5
2 changed files with 170 additions and 1 deletions

View File

@@ -93,7 +93,11 @@ func InstallDefault(name string) error {
// IsLoaded checks if a profile with the given name has been loaded into the
// kernel.
func IsLoaded(name string) (bool, error) {
file, err := os.Open("/sys/kernel/security/apparmor/profiles")
return isLoaded(name, "/sys/kernel/security/apparmor/profiles")
}
func isLoaded(name string, fileName string) (bool, error) {
file, err := os.Open(fileName)
if err != nil {
return false, err
}

View File

@@ -0,0 +1,165 @@
package apparmor
import (
"errors"
"os"
"path"
"testing"
)
// testAppArmorProfiles fixture "/sys/kernel/security/apparmor/profiles"
// from an Ubuntu 24.10 host.
const testAppArmorProfiles = `wpcom (unconfined)
wike (unconfined)
vpnns (unconfined)
vivaldi-bin (unconfined)
virtiofsd (unconfined)
vdens (unconfined)
uwsgi-core (unconfined)
rsyslogd (enforce)
/usr/lib/snapd/snap-confine (enforce)
/usr/lib/snapd/snap-confine//mount-namespace-capture-helper (enforce)
tcpdump (enforce)
man_groff (enforce)
man_filter (enforce)
/usr/bin/man (enforce)
userbindmount (unconfined)
unprivileged_userns (enforce)
unix-chkpwd (enforce)
ubuntu_pro_esm_cache_systemd_detect_virt (enforce)
ubuntu_pro_esm_cache_systemctl (enforce)
ubuntu_pro_esm_cache (enforce)
ubuntu_pro_esm_cache//ubuntu_distro_info (enforce)
ubuntu_pro_esm_cache//ps (enforce)
ubuntu_pro_esm_cache//dpkg (enforce)
ubuntu_pro_esm_cache//cloud_id (enforce)
ubuntu_pro_esm_cache//apt_methods_gpgv (enforce)
ubuntu_pro_esm_cache//apt_methods (enforce)
ubuntu_pro_apt_news (enforce)
tuxedo-control-center (unconfined)
tup (unconfined)
trinity (unconfined)
transmission-qt (complain)
transmission-gtk (complain)
transmission-daemon (complain)
transmission-cli (complain)
toybox (unconfined)
thunderbird (unconfined)
systemd-coredump (unconfined)
surfshark (unconfined)
stress-ng (unconfined)
steam (unconfined)
slirp4netns (unconfined)
slack (unconfined)
signal-desktop (unconfined)
scide (unconfined)
sbuild-upgrade (unconfined)
sbuild-update (unconfined)
sbuild-unhold (unconfined)
sbuild-shell (unconfined)
sbuild-hold (unconfined)
sbuild-distupgrade (unconfined)
sbuild-destroychroot (unconfined)
sbuild-createchroot (unconfined)
sbuild-clean (unconfined)
sbuild-checkpackages (unconfined)
sbuild-apt (unconfined)
sbuild-adduser (unconfined)
sbuild-abort (unconfined)
sbuild (unconfined)
runc (unconfined)
rssguard (unconfined)
rpm (unconfined)
rootlesskit (unconfined)
qutebrowser (unconfined)
qmapshack (unconfined)
qcam (unconfined)
privacybrowser (unconfined)
polypane (unconfined)
podman (unconfined)
plasmashell (enforce)
plasmashell//QtWebEngineProcess (enforce)
pageedit (unconfined)
opera (unconfined)
opam (unconfined)
obsidian (unconfined)
nvidia_modprobe (enforce)
nvidia_modprobe//kmod (enforce)
notepadqq (unconfined)
nautilus (unconfined)
msedge (unconfined)
mmdebstrap (unconfined)
lxc-usernsexec (unconfined)
lxc-unshare (unconfined)
lxc-stop (unconfined)
lxc-execute (unconfined)
lxc-destroy (unconfined)
lxc-create (unconfined)
lxc-attach (unconfined)
lsb_release (enforce)
loupe (unconfined)
linux-sandbox (unconfined)
libcamerify (unconfined)
lc-compliance (unconfined)
keybase (unconfined)
kchmviewer (unconfined)
ipa_verify (unconfined)
goldendict (unconfined)
github-desktop (unconfined)
geary (unconfined)
foliate (unconfined)
flatpak (unconfined)
firefox (unconfined)
evolution (unconfined)
epiphany (unconfined)
element-desktop (unconfined)
devhelp (unconfined)
crun (unconfined)
vscode (unconfined)
chromium (unconfined)
chrome (unconfined)
ch-run (unconfined)
ch-checkns (unconfined)
cam (unconfined)
busybox (unconfined)
buildah (unconfined)
brave (unconfined)
balena-etcher (unconfined)
Xorg (complain)
QtWebEngineProcess (unconfined)
MongoDB Compass (unconfined)
Discord (unconfined)
1password (unconfined)
`
func TestIsLoaded(t *testing.T) {
tmpDir := t.TempDir()
profiles := path.Join(tmpDir, "apparmor_profiles")
if err := os.WriteFile(profiles, []byte(testAppArmorProfiles), 0o644); err != nil {
t.Fatal(err)
}
t.Run("loaded", func(t *testing.T) {
found, err := isLoaded("busybox", profiles)
if err != nil {
t.Fatal(err)
}
if !found {
t.Fatal("expected profile to be loaded")
}
})
t.Run("not loaded", func(t *testing.T) {
found, err := isLoaded("no-such-profile", profiles)
if err != nil {
t.Fatal(err)
}
if found {
t.Fatal("expected profile to not be loaded")
}
})
t.Run("error", func(t *testing.T) {
_, err := isLoaded("anything", path.Join(tmpDir, "no_such_file"))
if err == nil || !errors.Is(err, os.ErrNotExist) {
t.Fatalf("expected error to be os.ErrNotExist, got %v", err)
}
})
}