mirror of
https://github.com/containers/podman.git
synced 2025-09-24 23:35:27 +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
|
// Unless specified otherwise, make sure that the default AppArmor
|
||||||
// profile is installed. To avoid redundantly loading the profile
|
// profile is installed. To avoid redundantly loading the profile
|
||||||
// on each invocation, check if it's loaded before installing it.
|
// 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)
|
logrus.Infof("Sucessfully loaded AppAmor profile '%s'", profile)
|
||||||
config.ApparmorProfile = 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)
|
isLoaded, err := apparmor.IsLoaded(config.ApparmorProfile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
switch err {
|
switch err {
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
if pkg-config libapparmor 2> /dev/null ; then
|
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
|
echo apparmor
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
|
@ -12,6 +12,9 @@ type versionExpected struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestParseVersion(t *testing.T) {
|
func TestParseVersion(t *testing.T) {
|
||||||
|
if !IsEnabled() {
|
||||||
|
t.Skip("AppArmor disabled: skipping tests")
|
||||||
|
}
|
||||||
versions := []versionExpected{
|
versions := []versionExpected{
|
||||||
{
|
{
|
||||||
output: `AppArmor parser version 2.10
|
output: `AppArmor parser version 2.10
|
||||||
|
@ -10,8 +10,15 @@ import (
|
|||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"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.
|
// profileData holds information about the given profile for generation.
|
||||||
type profileData struct {
|
type profileData struct {
|
||||||
// Name is profile name.
|
// Name is profile name.
|
||||||
|
@ -2,6 +2,11 @@
|
|||||||
|
|
||||||
package apparmor
|
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
|
// InstallDefault generates a default profile in a temp directory determined by
|
||||||
// os.TempDir(), then loads the profile into the kernel using 'apparmor_parser'.
|
// os.TempDir(), then loads the profile into the kernel using 'apparmor_parser'.
|
||||||
func InstallDefault(name string) error {
|
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