summaryrefslogtreecommitdiff
path: root/cmd/podman
diff options
context:
space:
mode:
authorMarco Vedovati <mvedovati@suse.com>2018-08-09 13:09:59 +0200
committerAtomic Bot <atomic-devel@projectatomic.io>2018-08-24 17:08:11 +0000
commit72e41c81aaa2c5ea39f7b5bd1c0654937703a346 (patch)
tree779314912b63eed2e4d97d872982386745ee54fe /cmd/podman
parentaf9f83f11c9b92ea806b33b75337de7e5d93592d (diff)
downloadpodman-72e41c81aaa2c5ea39f7b5bd1c0654937703a346.tar.gz
podman-72e41c81aaa2c5ea39f7b5bd1c0654937703a346.tar.bz2
podman-72e41c81aaa2c5ea39f7b5bd1c0654937703a346.zip
Do not try to enable AppArmor in rootless mode
When in rootless mode it's not possible to load profiles or check which profiles are loaded. Added a few baseline tests to check all possible cases. Signed-off-by: Marco Vedovati <mvedovati@suse.com> Closes: #1250 Approved by: mheon
Diffstat (limited to 'cmd/podman')
-rw-r--r--cmd/podman/create.go122
1 files changed, 73 insertions, 49 deletions
diff --git a/cmd/podman/create.go b/cmd/podman/create.go
index 3429c4d97..95b7a8bed 100644
--- a/cmd/podman/create.go
+++ b/cmd/podman/create.go
@@ -15,6 +15,7 @@ import (
ann "github.com/containers/libpod/pkg/annotations"
"github.com/containers/libpod/pkg/apparmor"
"github.com/containers/libpod/pkg/inspect"
+ "github.com/containers/libpod/pkg/rootless"
cc "github.com/containers/libpod/pkg/spec"
"github.com/containers/libpod/pkg/util"
libpodVersion "github.com/containers/libpod/version"
@@ -148,52 +149,20 @@ func createCmd(c *cli.Context) error {
return nil
}
-func parseSecurityOpt(config *cc.CreateConfig, securityOpts []string) error {
- var (
- labelOpts []string
- err error
- )
-
- if config.PidMode.IsHost() {
- labelOpts = append(labelOpts, label.DisableSecOpt()...)
- } else if config.PidMode.IsContainer() {
- ctr, err := config.Runtime.LookupContainer(config.PidMode.Container())
- if err != nil {
- return errors.Wrapf(err, "container %q not found", config.PidMode.Container())
- }
- labelOpts = append(labelOpts, label.DupSecOpt(ctr.ProcessLabel())...)
- }
-
- if config.IpcMode.IsHost() {
- labelOpts = append(labelOpts, label.DisableSecOpt()...)
- } else if config.IpcMode.IsContainer() {
- ctr, err := config.Runtime.LookupContainer(config.IpcMode.Container())
- if err != nil {
- return errors.Wrapf(err, "container %q not found", config.IpcMode.Container())
- }
- labelOpts = append(labelOpts, label.DupSecOpt(ctr.ProcessLabel())...)
- }
-
- for _, opt := range securityOpts {
- if opt == "no-new-privileges" {
- config.NoNewPrivs = true
- } else {
- con := strings.SplitN(opt, "=", 2)
- if len(con) != 2 {
- return fmt.Errorf("Invalid --security-opt 1: %q", opt)
- }
-
- switch con[0] {
- case "label":
- labelOpts = append(labelOpts, con[1])
- case "apparmor":
- config.ApparmorProfile = con[1]
- case "seccomp":
- config.SeccompProfilePath = con[1]
- default:
- return fmt.Errorf("Invalid --security-opt 2: %q", opt)
- }
+// Checks if a user-specified AppArmor profile is loaded, or loads the default profile if
+// AppArmor is enabled.
+// Any interaction with AppArmor requires root permissions.
+func loadAppArmor(config *cc.CreateConfig) error {
+ if rootless.IsRootless() {
+ noAAMsg := "AppArmor security is not available in rootless mode"
+ switch config.ApparmorProfile {
+ case "":
+ logrus.Warn(noAAMsg)
+ case "unconfined":
+ default:
+ return fmt.Errorf(noAAMsg)
}
+ return nil
}
if config.ApparmorProfile == "" && apparmor.IsEnabled() {
@@ -233,23 +202,78 @@ func parseSecurityOpt(config *cc.CreateConfig, securityOpts []string) error {
}
} else if config.ApparmorProfile != "" && config.ApparmorProfile != "unconfined" {
if !apparmor.IsEnabled() {
- return fmt.Errorf("profile specified but AppArmor is disabled on the host")
+ return fmt.Errorf("Profile specified but AppArmor is disabled on the host")
}
isLoaded, err := apparmor.IsLoaded(config.ApparmorProfile)
if err != nil {
switch err {
case apparmor.ErrApparmorUnsupported:
- return fmt.Errorf("profile specified but AppArmor is not supported")
+ return fmt.Errorf("Profile specified but AppArmor is not supported")
default:
- return fmt.Errorf("error checking if AppArmor profile is loaded: %v", err)
+ return fmt.Errorf("Error checking if AppArmor profile is loaded: %v", err)
}
}
if !isLoaded {
- return fmt.Errorf("specified AppArmor profile '%s' is not loaded", config.ApparmorProfile)
+ return fmt.Errorf("The specified AppArmor profile '%s' is not loaded", config.ApparmorProfile)
}
}
+ return nil
+}
+
+func parseSecurityOpt(config *cc.CreateConfig, securityOpts []string) error {
+ var (
+ labelOpts []string
+ err error
+ )
+
+ if config.PidMode.IsHost() {
+ labelOpts = append(labelOpts, label.DisableSecOpt()...)
+ } else if config.PidMode.IsContainer() {
+ ctr, err := config.Runtime.LookupContainer(config.PidMode.Container())
+ if err != nil {
+ return errors.Wrapf(err, "container %q not found", config.PidMode.Container())
+ }
+ labelOpts = append(labelOpts, label.DupSecOpt(ctr.ProcessLabel())...)
+ }
+
+ if config.IpcMode.IsHost() {
+ labelOpts = append(labelOpts, label.DisableSecOpt()...)
+ } else if config.IpcMode.IsContainer() {
+ ctr, err := config.Runtime.LookupContainer(config.IpcMode.Container())
+ if err != nil {
+ return errors.Wrapf(err, "container %q not found", config.IpcMode.Container())
+ }
+ labelOpts = append(labelOpts, label.DupSecOpt(ctr.ProcessLabel())...)
+ }
+
+ for _, opt := range securityOpts {
+ if opt == "no-new-privileges" {
+ config.NoNewPrivs = true
+ } else {
+ con := strings.SplitN(opt, "=", 2)
+ if len(con) != 2 {
+ return fmt.Errorf("Invalid --security-opt 1: %q", opt)
+ }
+
+ switch con[0] {
+ case "label":
+ labelOpts = append(labelOpts, con[1])
+ case "apparmor":
+ config.ApparmorProfile = con[1]
+ case "seccomp":
+ config.SeccompProfilePath = con[1]
+ default:
+ return fmt.Errorf("Invalid --security-opt 2: %q", opt)
+ }
+ }
+ }
+
+ if err := loadAppArmor(config); err != nil {
+ return err
+ }
+
if config.SeccompProfilePath == "" {
if _, err := os.Stat(libpod.SeccompOverridePath); err == nil {
config.SeccompProfilePath = libpod.SeccompOverridePath