Skip to content

Commit

Permalink
Merge pull request #1572 from kernelmethod/rootless_apparmor
Browse files Browse the repository at this point in the history
Allow rootless AppArmor
  • Loading branch information
openshift-merge-robot authored Aug 16, 2023
2 parents 519ed7f + 5c25c1c commit f2437f3
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 39 deletions.
13 changes: 7 additions & 6 deletions pkg/apparmor/apparmor.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,22 @@ package apparmor

import (
"errors"

"github.com/containers/common/version"
)

const (
// ProfilePrefix is used for version-independent presence checks.
ProfilePrefix = "containers-default-"

// Profile default name
Profile = ProfilePrefix + version.Version
// Default AppArmor profile used by containers; by default this is set to unconfined.
// To override this, distros should supply their own profile and specify it in a default
// containers.conf.
// See the following issues for more information:
// - https://github.com/containers/common/issues/958
// - https://github.com/containers/podman/issues/15874
Profile = "unconfined"
)

var (

Check failure on line 20 in pkg/apparmor/apparmor.go

View workflow job for this annotation

GitHub Actions / lint

File is not `gofumpt`-ed (gofumpt)
// ErrApparmorUnsupported indicates that AppArmor support is not supported.
ErrApparmorUnsupported = errors.New("AppArmor is not supported")
// ErrApparmorRootless indicates that AppArmor support is not supported in rootless mode.
ErrApparmorRootless = errors.New("AppArmor is not supported in rootless mode")
)
34 changes: 4 additions & 30 deletions pkg/apparmor/apparmor_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import (
"text/template"

"github.com/containers/common/pkg/apparmor/internal/supported"
"github.com/containers/storage/pkg/unshare"
runcaa "github.com/opencontainers/runc/libcontainer/apparmor"
"github.com/sirupsen/logrus"
)
Expand Down Expand Up @@ -83,10 +82,6 @@ func macroExists(m string) bool {
// InstallDefault generates a default profile and loads it into the kernel
// using 'apparmor_parser'.
func InstallDefault(name string) error {
if unshare.IsRootless() {
return ErrApparmorRootless
}

p := profileData{
Name: name,
}
Expand Down Expand Up @@ -147,12 +142,9 @@ func DefaultContent(name string) ([]byte, error) {
}

// IsLoaded checks if a profile with the given name has been loaded into the
// kernel.
// kernel. This function checks for the existence of a profile by reading
// /sys/kernel/security/apparmor/profiles, and hence requires root permissions.
func IsLoaded(name string) (bool, error) {
if name != "" && unshare.IsRootless() {
return false, fmt.Errorf("cannot load AppArmor profile %q: %w", name, ErrApparmorRootless)
}

file, err := os.Open("/sys/kernel/security/apparmor/profiles")
if err != nil {
if errors.Is(err, os.ErrNotExist) {
Expand Down Expand Up @@ -247,24 +239,13 @@ func parseAAParserVersion(output string) (int, error) {
// CheckProfileAndLoadDefault checks if the specified profile is loaded and
// loads the DefaultLibpodProfile if the specified on is prefixed by
// DefaultLipodProfilePrefix. This allows to always load and apply the latest
// default AppArmor profile. Note that AppArmor requires root. If it's a
// default profile, return DefaultLipodProfilePrefix, otherwise the specified
// one.
// default AppArmor profile. If it's a default profile, return
// DefaultLipodProfilePrefix, otherwise the specified one.
func CheckProfileAndLoadDefault(name string) (string, error) {
if name == "unconfined" {
return name, nil
}

// AppArmor is not supported in rootless mode as it requires root
// privileges. Return an error in case a specific profile is specified.
if unshare.IsRootless() {
if name != "" {
return "", fmt.Errorf("cannot load AppArmor profile %q: %w", name, ErrApparmorRootless)
}
logrus.Debug("Skipping loading default AppArmor profile (rootless mode)")
return "", nil
}

// Check if AppArmor is disabled and error out if a profile is to be set.
if !runcaa.IsEnabled() {
if name == "" {
Expand All @@ -278,13 +259,6 @@ func CheckProfileAndLoadDefault(name string) (string, error) {
} else if !strings.HasPrefix(name, ProfilePrefix) {
// If the specified name is not a default one, ignore it and return the
// name.
isLoaded, err := IsLoaded(name)
if err != nil {
return "", fmt.Errorf("verify if profile %s is loaded: %w", name, err)
}
if !isLoaded {
return "", fmt.Errorf("AppArmor profile %q specified but not loaded", name)
}
return name, nil
}

Expand Down
3 changes: 0 additions & 3 deletions pkg/apparmor/internal/supported/supported.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,6 @@ func NewAppArmorVerifier() *ApparmorVerifier {
// - AppArmor is disabled by the host system
// - the `apparmor_parser` binary is not discoverable
func (a *ApparmorVerifier) IsSupported() error {
if a.impl.UnshareIsRootless() {
return errors.New("AppAmor is not supported on rootless containers")
}
if !a.impl.RuncIsEnabled() {
return errors.New("AppArmor not supported by the host system")
}
Expand Down

0 comments on commit f2437f3

Please sign in to comment.