]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
setpriv: use AppArmor LSM-specific proc interface
authorKarel Zak <kzak@redhat.com>
Tue, 17 Feb 2026 11:33:58 +0000 (12:33 +0100)
committerKarel Zak <kzak@redhat.com>
Tue, 17 Feb 2026 11:33:58 +0000 (12:33 +0100)
Remove the check for /sys/kernel/security/apparmor (securityfs) before
writing to the proc attr interface. The securityfs check fails in
environments where AppArmor is enabled but securityfs is not mounted
(e.g., containers, WSL2, embedded systems).

Use the LSM-specific /proc/self/attr/apparmor/exec interface introduced
in Linux 5.8 (kernel commit 6413f852ce08) which is not affected by LSM
load ordering issues. Fall back to the legacy /proc/self/attr/exec for
older kernels.

Fixes: https://github.com/util-linux/util-linux/issues/4033
Signed-off-by: Karel Zak <kzak@redhat.com>
include/pathnames.h
sys-utils/setpriv.c

index 718c71b90d2b3e642c52d2f409b5abc99989ba9d..6dcfced222de85c676c20f5932db996e3ace4a37 100644 (file)
 
 #define _PATH_PROC_ATTR_CURRENT        "/proc/self/attr/current"
 #define _PATH_PROC_ATTR_EXEC   "/proc/self/attr/exec"
+#define _PATH_PROC_ATTR_APPARMOR_EXEC  "/proc/self/attr/apparmor/exec"
 #define _PATH_PROC_CAPLASTCAP  "/proc/sys/kernel/cap_last_cap"
 
 
index ea1838b3e9fda59744c4a7bcd177e993f2897a60..a6444a6f6ad4a79509ee0ad29027d5059d646fce 100644 (file)
@@ -663,20 +663,29 @@ static void do_selinux_label(const char *label)
 static void do_apparmor_profile(const char *label)
 {
        FILE *f;
+       const char *path;
 
-       if (access(_PATH_SYS_APPARMOR, F_OK) != 0)
-               errx(SETPRIV_EXIT_PRIVERR, _("AppArmor is not running"));
-
-       f = fopen(_PATH_PROC_ATTR_EXEC, "r+");
+       /* Since Linux 5.8 (commit 6413f852ce08), AppArmor has an LSM-specific
+        * proc interface that is not affected by the LSM load ordering. Fall
+        * back to the legacy shared interface for older kernels.
+        *
+        * See https://github.com/torvalds/linux/blob/master/Documentation/userspace-api/lsm.rst
+        */
+       path = _PATH_PROC_ATTR_APPARMOR_EXEC;
+       f = fopen(path, "r+");
+       if (!f) {
+               path = _PATH_PROC_ATTR_EXEC;
+               f = fopen(path, "r+");
+       }
        if (!f)
                err(SETPRIV_EXIT_PRIVERR,
-                   _("cannot open %s"), _PATH_PROC_ATTR_EXEC);
+                   _("cannot open %s"), path);
 
        fprintf(f, "exec %s", label);
 
        if (close_stream(f) != 0)
                err(SETPRIV_EXIT_PRIVERR,
-                   _("write failed: %s"), _PATH_PROC_ATTR_EXEC);
+                   _("write failed: %s"), path);
 }
 
 static void do_seccomp_filter(const char *file)