From fe3a142521335e3ae593889ba7733713bcb29fcf Mon Sep 17 00:00:00 2001 From: Samuel Cobb Date: Sun, 21 Jun 2026 04:16:04 +0100 Subject: [PATCH] nixos/incus: remove named profile --- nixos/modules/virtualisation/incus.nix | 28 ++++++++++++++++---------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/nixos/modules/virtualisation/incus.nix b/nixos/modules/virtualisation/incus.nix index 83a5a731ccb7..466e359c3147 100644 --- a/nixos/modules/virtualisation/incus.nix +++ b/nixos/modules/virtualisation/incus.nix @@ -363,21 +363,27 @@ in include ${cfg.lxcPackage}/etc/apparmor.d/lxc-containers ''; "incusd".profile = '' - # This profile allows everything and only exists to give the - # application a name instead of having the label "unconfined" + # incusd is deliberatly left unconfined, with NO named profile attached to the binary. + # Incus checks its own confinement at startup by reading /proc/self/attr/current + # (https://github.com/lxc/incus/blob/92b0cbbc5728ed45578fdeeec634606af8826404/internal/server/sys/apparmor.go). + # Anything other than "unconfined" makes Incus believe that the host process is + # itself confined, which sends every container down the "reuse my own profile" branch in + # https://github.com/lxc/incus/blob/92b0cbbc5728ed45578fdeeec634606af8826404/internal/server/instance/drivers/driver_lxc.go + # instead of generating a "proper" per-container profile. Furthermore, + # that branch only strips " (enforce)" suffix before handing the string to lxc.apparmor.profile + # (https://github.com/lxc/incus/blob/92b0cbbc5728ed45578fdeeec634606af8826404/internal/server/instance/drivers/driver_lxc.go#L96), + # so the named profile with flags=(unconfined) produces a literal string + # "incusd (unconfined)", which the kernel rejects at change_profile() time + # with "label not found", failing every `incus start` when AppArmor is enabled. + # This was not caught before as AppArmor was stifled by bpf. + + # We keep this policy to pull in the per-container / + # per-archive profiles incusd generates at runtime so + # apparmor_parser loads them. abi , include - profile incusd ${lib.getExe' config.virtualisation.incus.package "incusd"} flags=(unconfined) { - userns, - - include "/var/lib/incus/security/apparmor/cache" - - # Site-specific additions and overrides. See local/README for details. - include if exists - } - include "/var/lib/incus/security/apparmor/profiles" ''; };