VYPR
Moderate severityNVD Advisory· Published Dec 2, 2025· Updated Dec 2, 2025

Apptainer ineffective application of selinux and apparmor --security options

CVE-2025-65105

Description

Apptainer is an open source container platform. In Apptainer versions less than 1.4.5, a container can disable two of the forms of the little used --security option, in particular the forms --security=apparmor: and --security=selinux: which otherwise put restrictions on operations that containers can do. The --security option has always been mentioned in Apptainer documentation as being a feature for the root user, although these forms do also work for unprivileged users on systems where the corresponding feature is enabled. Apparmor is enabled by default on Debian-based distributions and SElinux is enabled by default on RHEL-based distributions, but on SUSE it depends on the distribution version. This vulnerability is fixed in 1.4.5.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

In Apptainer versions before 1.4.5, a container can bypass --security=apparmor and --security=selinux restrictions, allowing unprivileged containers to escape AppArmor or SELinux confinement.

Vulnerability

Overview

In Apptainer versions prior to 1.4.5, a container can disable the --security=apparmor: and --security=selinux: options, which are intended to apply Linux Security Module (LSM) restrictions to container processes. The root cause is that Apptainer did not properly enforce the application of these security profiles—when the requested feature was unavailable or could not be applied, it only issued a warning instead of failing, allowing the container to continue without the intended restrictions [2][3].

Exploitation

An attacker running an unprivileged container on a system with AppArmor (default on Debian-based distributions) or SELinux (default on RHEL-based distributions) can exploit this by specifying one of the --security options but then circumventing its application. The exact mechanism likely involves manipulating the container environment to avoid loading the profile, as suggested by related container runtime vulnerabilities [1]. While the --security option is documented for root users, these forms also work for unprivileged users on systems with the respective feature enabled.

Impact

Successful exploitation allows a container to run without AppArmor or SELinux confinement, removing critical security restrictions. This could enable an attacker to perform actions normally prevented by LSM policies, such as accessing sensitive files, escalating privileges, or escaping the container to compromise the host system.

Mitigation

The vulnerability is fixed in Apptainer version 1.4.5. The commit changes the behavior from a warning to an error when the requested security profile cannot be applied, causing the container to fail to start [4]. Users should upgrade to 1.4.5 or later; no workaround is available.

AI Insight generated on May 19, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
github.com/apptainer/apptainerGo
< 1.4.51.4.5

Affected products

2

Patches

2
82f17900a0c3

fix: fail if --security options can't be applied

https://github.com/apptainer/apptainerDavid TrudgianNov 13, 2025via ghsa
2 files changed · +27 25
  • internal/pkg/security/security.go+4 4 modified
    @@ -2,7 +2,7 @@
     //   Apptainer a Series of LF Projects LLC.
     //   For website terms of use, trademark policy, privacy policy and other
     //   project policies see https://lfprojects.org/policies
    -// Copyright (c) 2018-2020, Sylabs Inc. All rights reserved.
    +// Copyright (c) 2018-2025, Sylabs Inc. All rights reserved.
     // This software is licensed under a 3-clause BSD license. Please consult the
     // LICENSE.md file distributed with the sources of this project regarding your
     // rights to use or distribute this software.
    @@ -32,15 +32,15 @@ func Configure(config *specs.Spec) error {
     					return err
     				}
     			} else {
    -				sylog.Warningf("selinux is not enabled or supported on this system")
    +				return fmt.Errorf("selinux requested, but is not enabled or supported on this system")
     			}
     		} else if config.Process.ApparmorProfile != "" {
     			if apparmor.Enabled() {
     				if err := apparmor.LoadProfile(config.Process.ApparmorProfile); err != nil {
     					return err
     				}
     			} else {
    -				sylog.Warningf("apparmor is not enabled or supported on this system")
    +				return fmt.Errorf("apparmor requested, but is not enabled or supported on this system")
     			}
     		}
     	}
    @@ -50,7 +50,7 @@ func Configure(config *specs.Spec) error {
     				return err
     			}
     		} else {
    -			sylog.Warningf("seccomp requested but not enabled, seccomp library is missing or too old")
    +			return fmt.Errorf("seccomp requested but not enabled, seccomp library is missing or too old")
     		}
     	}
     	return nil
    
  • internal/pkg/security/security_test.go+23 21 modified
    @@ -2,22 +2,20 @@
     //   Apptainer a Series of LF Projects LLC.
     //   For website terms of use, trademark policy, privacy policy and other
     //   project policies see https://lfprojects.org/policies
    -// Copyright (c) 2019, Sylabs Inc. All rights reserved.
    +// Copyright (c) 2019-2025, Sylabs Inc. All rights reserved.
     // This software is licensed under a 3-clause BSD license. Please consult the
     // LICENSE.md file distributed with the sources of this project regarding your
     // rights to use or distribute this software.
     
     package security
     
     import (
    -	"os"
     	"runtime"
     	"testing"
     
     	"github.com/apptainer/apptainer/internal/pkg/security/apparmor"
     	"github.com/apptainer/apptainer/internal/pkg/security/selinux"
     	"github.com/apptainer/apptainer/internal/pkg/test"
    -	"github.com/apptainer/apptainer/internal/pkg/util/mainthread"
     	"github.com/opencontainers/runtime-spec/specs-go"
     )
     
    @@ -93,6 +91,16 @@ func TestConfigure(t *testing.T) {
     			},
     			disabled: !selinux.Enabled(),
     		},
    +		{
    +			desc: "SELinux when not available",
    +			spec: specs.Spec{
    +				Process: &specs.Process{
    +					SelinuxLabel: "unconfined_u:unconfined_r:unconfined_t:s0",
    +				},
    +			},
    +			expectFailure: true,
    +			disabled:      selinux.Enabled(),
    +		},
     		{
     			desc: "with bad apparmor profile",
     			spec: specs.Spec{
    @@ -112,6 +120,15 @@ func TestConfigure(t *testing.T) {
     			},
     			disabled: !apparmor.Enabled(),
     		},
    +		{
    +			desc: "apparmor when not available",
    +			spec: specs.Spec{
    +				Process: &specs.Process{
    +					ApparmorProfile: "unconfined",
    +				},
    +			},
    +			disabled: apparmor.Enabled(),
    +		},
     	}
     
     	for _, s := range specs {
    @@ -122,9 +139,9 @@ func TestConfigure(t *testing.T) {
     
     			var err error
     
    -			mainthread.Execute(func() {
    -				err = Configure(&s.spec) //nolint:gosec
    -			})
    +			runtime.LockOSThread()
    +			defer runtime.UnlockOSThread()
    +			err = Configure(&s.spec)
     
     			if err != nil && !s.expectFailure {
     				t.Errorf("unexpected failure %s: %s", s.desc, err)
    @@ -134,18 +151,3 @@ func TestConfigure(t *testing.T) {
     		})
     	}
     }
    -
    -func init() {
    -	runtime.LockOSThread()
    -}
    -
    -func TestMain(m *testing.M) {
    -	go func() {
    -		os.Exit(m.Run())
    -	}()
    -
    -	// run functions requiring execution in main thread
    -	for f := range mainthread.FuncChannel {
    -		f()
    -	}
    -}
    
4313b42717e1

fix: use pathrs-lite/procfs when writing apparmor profile

https://github.com/apptainer/apptainerDavid TrudgianNov 13, 2025via ghsa
1 file changed · +22 2
  • internal/pkg/security/apparmor/apparmor_supported.go+22 2 modified
    @@ -2,7 +2,7 @@
     //   Apptainer a Series of LF Projects LLC.
     //   For website terms of use, trademark policy, privacy policy and other
     //   project policies see https://lfprojects.org/policies
    -// Copyright (c) 2018-2022, Sylabs Inc. All rights reserved.
    +// Copyright (c) 2018-2025, Sylabs Inc. All rights reserved.
     // This software is licensed under a 3-clause BSD license. Please consult the
     // LICENSE.md file distributed with the sources of this project regarding your
     // rights to use or distribute this software.
    @@ -14,6 +14,10 @@ package apparmor
     import (
     	"fmt"
     	"os"
    +
    +	"github.com/cyphar/filepath-securejoin/pathrs-lite"
    +	"github.com/cyphar/filepath-securejoin/pathrs-lite/procfs"
    +	"golang.org/x/sys/unix"
     )
     
     // Enabled returns whether AppArmor is enabled.
    @@ -27,7 +31,23 @@ func Enabled() bool {
     
     // LoadProfile loads the specified AppArmor profile.
     func LoadProfile(profile string) error {
    -	f, err := os.OpenFile("/proc/self/attr/exec", os.O_WRONLY, 0)
    +	// We must make sure we are actually opening and writing to a real attr/exec
    +	// in a real procfs so that the profile takes effect. Using
    +	// pathrs-lite/procfs as below accomplishes this.
    +	proc, err := procfs.OpenProcRoot()
    +	if err != nil {
    +		return err
    +	}
    +	defer proc.Close()
    +
    +	attrExec, closer, err := proc.OpenThreadSelf("attr/exec")
    +	if err != nil {
    +		return err
    +	}
    +	defer closer()
    +	defer attrExec.Close()
    +
    +	f, err := pathrs.Reopen(attrExec, unix.O_WRONLY|unix.O_CLOEXEC)
     	if err != nil {
     		return err
     	}
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

8

News mentions

0

No linked articles in our index yet.