From: Karel Zak Date: Tue, 17 Feb 2026 11:33:58 +0000 (+0100) Subject: setpriv: use AppArmor LSM-specific proc interface X-Git-Tag: v2.43-devel~65^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9d4385e63e941b470fdc674edd1c36161379034b;p=thirdparty%2Futil-linux.git setpriv: use AppArmor LSM-specific proc interface 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 --- diff --git a/include/pathnames.h b/include/pathnames.h index 718c71b90..6dcfced22 100644 --- a/include/pathnames.h +++ b/include/pathnames.h @@ -110,6 +110,7 @@ #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" diff --git a/sys-utils/setpriv.c b/sys-utils/setpriv.c index ea1838b3e..a6444a6f6 100644 --- a/sys-utils/setpriv.c +++ b/sys-utils/setpriv.c @@ -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)