summaryrefslogtreecommitdiff
path: root/pkg/apparmor/apparmor_linux.go
diff options
context:
space:
mode:
authorOpenShift Merge Robot <openshift-merge-robot@users.noreply.github.com>2019-01-10 03:34:54 -0800
committerGitHub <noreply@github.com>2019-01-10 03:34:54 -0800
commit64627d910b2113fa2de6b949d846af379e75e305 (patch)
treed555591919d240a25827eb3737446260c04496e0 /pkg/apparmor/apparmor_linux.go
parent0f6535cf6b4bfac265983c2fdd3482310ab4f39b (diff)
parentedb285d17675061832aceaf72021b87aba149438 (diff)
downloadpodman-64627d910b2113fa2de6b949d846af379e75e305.tar.gz
podman-64627d910b2113fa2de6b949d846af379e75e305.tar.bz2
podman-64627d910b2113fa2de6b949d846af379e75e305.zip
Merge pull request #2114 from vrothberg/issue-2107
apparmor: apply default profile at container initialization
Diffstat (limited to 'pkg/apparmor/apparmor_linux.go')
-rw-r--r--pkg/apparmor/apparmor_linux.go66
1 files changed, 66 insertions, 0 deletions
diff --git a/pkg/apparmor/apparmor_linux.go b/pkg/apparmor/apparmor_linux.go
index b0e3ca0fd..0787b3fa5 100644
--- a/pkg/apparmor/apparmor_linux.go
+++ b/pkg/apparmor/apparmor_linux.go
@@ -13,7 +13,10 @@ import (
"strings"
"text/template"
+ "github.com/containers/libpod/pkg/rootless"
runcaa "github.com/opencontainers/runc/libcontainer/apparmor"
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
// profileDirectory is the file store for apparmor profiles and macros.
@@ -21,6 +24,9 @@ var profileDirectory = "/etc/apparmor.d"
// IsEnabled returns true if AppArmor is enabled on the host.
func IsEnabled() bool {
+ if rootless.IsRootless() {
+ return false
+ }
return runcaa.IsEnabled()
}
@@ -71,6 +77,10 @@ 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 rootless.IsRootless() {
+ return ErrApparmorRootless
+ }
+
p := profileData{
Name: name,
}
@@ -97,6 +107,10 @@ func InstallDefault(name string) error {
// IsLoaded checks if a profile with the given name has been loaded into the
// kernel.
func IsLoaded(name string) (bool, error) {
+ if name != "" && rootless.IsRootless() {
+ return false, errors.Wrapf(ErrApparmorRootless, "cannot load AppArmor profile %q", name)
+ }
+
file, err := os.Open("/sys/kernel/security/apparmor/profiles")
if err != nil {
if os.IsNotExist(err) {
@@ -188,3 +202,55 @@ func parseAAParserVersion(output string) (int, error) {
return numericVersion, nil
}
+
+// 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.
+func CheckProfileAndLoadDefault(name string) (string, error) {
+ if name == "unconfined" {
+ return name, nil
+ }
+
+ if name != "" && rootless.IsRootless() {
+ return "", errors.Wrapf(ErrApparmorRootless, "cannot load AppArmor profile %q", name)
+ }
+
+ if name != "" && !runcaa.IsEnabled() {
+ return "", fmt.Errorf("profile %q specified but AppArmor is disabled on the host", name)
+ }
+
+ // If the specified name is not empty or is not a default libpod one,
+ // ignore it and return the name.
+ if name != "" && !strings.HasPrefix(name, DefaultLipodProfilePrefix) {
+ isLoaded, err := IsLoaded(name)
+ if err != nil {
+ return "", err
+ }
+ if !isLoaded {
+ return "", fmt.Errorf("AppArmor profile %q specified but not loaded")
+ }
+ return name, nil
+ }
+
+ name = DefaultLibpodProfile
+ // To avoid expensive redundant loads on each invocation, check
+ // if it's loaded before installing it.
+ isLoaded, err := IsLoaded(name)
+ if err != nil {
+ return "", err
+ }
+ if !isLoaded {
+ err = InstallDefault(name)
+ if err != nil {
+ return "", err
+ }
+ logrus.Infof("successfully loaded AppAmor profile %q", name)
+ } else {
+ logrus.Infof("AppAmor profile %q is already loaded", name)
+ }
+
+ return name, nil
+}