spiegel_podman/cmd/podman/exec.go
Giuseppe Scrivano 720eb85ba5 rootless: fix exec
We cannot re-exec into a new user namespace to gain privileges and
access an existing as the new namespace is not the owner of the
existing container.

"unshare" is used to join the user namespace of the target container.

The current implementation assumes that the main process of the
container didn't create a new user namespace.

Since in the setup phase we are not running with euid=0, we must skip
the setup for containers/storage.

Closes: https://github.com/containers/libpod/issues/1329

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>

Closes: #1331
Approved by: rhatdan
2018-08-26 07:22:42 +00:00

107 lines
2.6 KiB
Go

package main
import (
"fmt"
"strings"
"github.com/containers/libpod/cmd/podman/libpodruntime"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/rootless"
"github.com/pkg/errors"
"github.com/urfave/cli"
)
var (
execFlags = []cli.Flag{
cli.StringSliceFlag{
Name: "env, e",
Usage: "Set environment variables",
},
cli.BoolFlag{
Name: "privileged",
Usage: "Give the process extended Linux capabilities inside the container. The default is false",
},
cli.BoolFlag{
Name: "interactive, i",
Usage: "Not supported. All exec commands are interactive by default.",
},
cli.BoolFlag{
Name: "tty, t",
Usage: "Allocate a pseudo-TTY. The default is false",
},
cli.StringFlag{
Name: "user, u",
Usage: "Sets the username or UID used and optionally the groupname or GID for the specified command",
},
LatestFlag,
}
execDescription = `
podman exec
Run a command in a running container
`
execCommand = cli.Command{
Name: "exec",
Usage: "Run a process in a running container",
Description: execDescription,
Flags: execFlags,
Action: execCmd,
ArgsUsage: "CONTAINER-NAME",
SkipArgReorder: true,
UseShortOptionHandling: true,
}
)
func execCmd(c *cli.Context) error {
args := c.Args()
var ctr *libpod.Container
var err error
argStart := 1
if len(args) < 1 && !c.Bool("latest") {
return errors.Errorf("you must provide one container name or id")
}
if len(args) < 2 && !c.Bool("latest") {
return errors.Errorf("you must provide a command to exec")
}
if c.Bool("latest") {
argStart = 0
}
rootless.SetSkipStorageSetup(true)
cmd := args[argStart:]
runtime, err := libpodruntime.GetRuntime(c)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
defer runtime.Shutdown(false)
if c.Bool("latest") {
ctr, err = runtime.GetLatestContainer()
} else {
ctr, err = runtime.LookupContainer(args[0])
}
if err != nil {
return errors.Wrapf(err, "unable to exec into %s", args[0])
}
// ENVIRONMENT VARIABLES
env := defaultEnvVariables
for _, e := range c.StringSlice("env") {
split := strings.SplitN(e, "=", 2)
if len(split) > 1 {
env[split[0]] = split[1]
} else {
env[split[0]] = ""
}
}
if err := readKVStrings(env, []string{}, c.StringSlice("env")); err != nil {
return errors.Wrapf(err, "unable to process environment variables")
}
envs := []string{}
for k, v := range env {
envs = append(envs, fmt.Sprintf("%s=%s", k, v))
}
return ctr.Exec(c.Bool("tty"), c.Bool("privileged"), envs, cmd, c.String("user"))
}