summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorValentin Rothberg <vrothberg@suse.com>2018-07-22 17:45:36 +0200
committerAtomic Bot <atomic-devel@projectatomic.io>2018-07-23 18:11:09 +0000
commit8569ed03056ce39e0dc163747089ed4b60b1b9b1 (patch)
treed1ab8cbae6dfc8ef27158f0b8890d2bec275e30d
parent2c11e38b24942a18f43cb27d6c5145850a40be54 (diff)
downloadpodman-8569ed03056ce39e0dc163747089ed4b60b1b9b1.tar.gz
podman-8569ed03056ce39e0dc163747089ed4b60b1b9b1.tar.bz2
podman-8569ed03056ce39e0dc163747089ed4b60b1b9b1.zip
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
-rw-r--r--cmd/podman/create.go8
-rwxr-xr-xhack/apparmor_tag.sh5
-rw-r--r--pkg/apparmor/aaparser_test.go3
-rw-r--r--pkg/apparmor/apparmor_linux.go7
-rw-r--r--pkg/apparmor/apparmor_unsupported.go5
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor.go54
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_disabled.go20
7 files changed, 96 insertions, 6 deletions
diff --git a/cmd/podman/create.go b/cmd/podman/create.go
index 6a70e3f43..f147081d4 100644
--- a/cmd/podman/create.go
+++ b/cmd/podman/create.go
@@ -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 {
diff --git a/hack/apparmor_tag.sh b/hack/apparmor_tag.sh
index 6d4bec91b..0fd222210 100755
--- a/hack/apparmor_tag.sh
+++ b/hack/apparmor_tag.sh
@@ -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
diff --git a/pkg/apparmor/aaparser_test.go b/pkg/apparmor/aaparser_test.go
index 9d97969c7..296c101ed 100644
--- a/pkg/apparmor/aaparser_test.go
+++ b/pkg/apparmor/aaparser_test.go
@@ -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
diff --git a/pkg/apparmor/apparmor_linux.go b/pkg/apparmor/apparmor_linux.go
index 6e8b7f312..a09c5fc44 100644
--- a/pkg/apparmor/apparmor_linux.go
+++ b/pkg/apparmor/apparmor_linux.go
@@ -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.
diff --git a/pkg/apparmor/apparmor_unsupported.go b/pkg/apparmor/apparmor_unsupported.go
index 0f1ab9464..df1336b07 100644
--- a/pkg/apparmor/apparmor_unsupported.go
+++ b/pkg/apparmor/apparmor_unsupported.go
@@ -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 {
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor.go b/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor.go
new file mode 100644
index 000000000..7fff0627f
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor.go
@@ -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)
+}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_disabled.go b/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_disabled.go
new file mode 100644
index 000000000..d4110cf0b
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_disabled.go
@@ -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
+}