diff options
Diffstat (limited to 'cmd/podman')
-rw-r--r-- | cmd/podman/create.go | 122 |
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 |