mirror of
https://github.com/containers/podman.git
synced 2025-07-03 17:27:18 +08:00
AppArmor: runtime check if it's enabled on the host
Check at runtime if AppArmor is enabled on the host. Signed-off-by: Valentin Rothberg <vrothberg@suse.com> Closes: #1128 Approved by: mheon
This commit is contained in:

committed by
Atomic Bot

parent
2c11e38b24
commit
8569ed0305
@ -196,7 +196,7 @@ func parseSecurityOpt(config *cc.CreateConfig, securityOpts []string) error {
|
||||
}
|
||||
}
|
||||
|
||||
if config.ApparmorProfile == "" {
|
||||
if config.ApparmorProfile == "" && apparmor.IsEnabled() {
|
||||
// Unless specified otherwise, make sure that the default AppArmor
|
||||
// profile is installed. To avoid redundantly loading the profile
|
||||
// on each invocation, check if it's loaded before installing it.
|
||||
@ -231,7 +231,11 @@ func parseSecurityOpt(config *cc.CreateConfig, securityOpts []string) error {
|
||||
logrus.Infof("Sucessfully loaded AppAmor profile '%s'", profile)
|
||||
config.ApparmorProfile = profile
|
||||
}
|
||||
} else {
|
||||
} else if config.ApparmorProfile != "" {
|
||||
if !apparmor.IsEnabled() {
|
||||
return fmt.Errorf("profile specified but AppArmor is disabled on the host")
|
||||
}
|
||||
|
||||
isLoaded, err := apparmor.IsLoaded(config.ApparmorProfile)
|
||||
if err != nil {
|
||||
switch err {
|
||||
|
@ -1,7 +1,4 @@
|
||||
#!/bin/bash
|
||||
if pkg-config libapparmor 2> /dev/null ; then
|
||||
# Travis CI does not support AppArmor, so we cannot run tests there.
|
||||
if [ -z "$TRAVIS" ]; then
|
||||
echo apparmor
|
||||
fi
|
||||
echo apparmor
|
||||
fi
|
||||
|
@ -12,6 +12,9 @@ type versionExpected struct {
|
||||
}
|
||||
|
||||
func TestParseVersion(t *testing.T) {
|
||||
if !IsEnabled() {
|
||||
t.Skip("AppArmor disabled: skipping tests")
|
||||
}
|
||||
versions := []versionExpected{
|
||||
{
|
||||
output: `AppArmor parser version 2.10
|
||||
|
@ -10,8 +10,15 @@ import (
|
||||
"path"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
runcaa "github.com/opencontainers/runc/libcontainer/apparmor"
|
||||
)
|
||||
|
||||
// IsEnabled returns true if AppArmor is enabled on the host.
|
||||
func IsEnabled() bool {
|
||||
return runcaa.IsEnabled()
|
||||
}
|
||||
|
||||
// profileData holds information about the given profile for generation.
|
||||
type profileData struct {
|
||||
// Name is profile name.
|
||||
|
@ -2,6 +2,11 @@
|
||||
|
||||
package apparmor
|
||||
|
||||
// IsEnabled returns true if AppArmor is enabled on the host.
|
||||
func IsEnabled() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// InstallDefault generates a default profile in a temp directory determined by
|
||||
// os.TempDir(), then loads the profile into the kernel using 'apparmor_parser'.
|
||||
func InstallDefault(name string) error {
|
||||
|
54
vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor.go
generated
vendored
Normal file
54
vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor.go
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
// +build apparmor,linux
|
||||
|
||||
package apparmor
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
)
|
||||
|
||||
// IsEnabled returns true if apparmor is enabled for the host.
|
||||
func IsEnabled() bool {
|
||||
if _, err := os.Stat("/sys/kernel/security/apparmor"); err == nil && os.Getenv("container") == "" {
|
||||
if _, err = os.Stat("/sbin/apparmor_parser"); err == nil {
|
||||
buf, err := ioutil.ReadFile("/sys/module/apparmor/parameters/enabled")
|
||||
return err == nil && len(buf) > 1 && buf[0] == 'Y'
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func setprocattr(attr, value string) error {
|
||||
// Under AppArmor you can only change your own attr, so use /proc/self/
|
||||
// instead of /proc/<tid>/ like libapparmor does
|
||||
path := fmt.Sprintf("/proc/self/attr/%s", attr)
|
||||
|
||||
f, err := os.OpenFile(path, os.O_WRONLY, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
_, err = fmt.Fprintf(f, "%s", value)
|
||||
return err
|
||||
}
|
||||
|
||||
// changeOnExec reimplements aa_change_onexec from libapparmor in Go
|
||||
func changeOnExec(name string) error {
|
||||
value := "exec " + name
|
||||
if err := setprocattr("exec", value); err != nil {
|
||||
return fmt.Errorf("apparmor failed to apply profile: %s", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ApplyProfile will apply the profile with the specified name to the process after
|
||||
// the next exec.
|
||||
func ApplyProfile(name string) error {
|
||||
if name == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
return changeOnExec(name)
|
||||
}
|
20
vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_disabled.go
generated
vendored
Normal file
20
vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_disabled.go
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
// +build !apparmor !linux
|
||||
|
||||
package apparmor
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
var ErrApparmorNotEnabled = errors.New("apparmor: config provided but apparmor not supported")
|
||||
|
||||
func IsEnabled() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func ApplyProfile(name string) error {
|
||||
if name != "" {
|
||||
return ErrApparmorNotEnabled
|
||||
}
|
||||
return nil
|
||||
}
|
Reference in New Issue
Block a user