From d4eca12cc12734f2b578e1b1967d69889c21c487 Mon Sep 17 00:00:00 2001 From: Valentin Rothberg Date: Fri, 5 Oct 2018 14:36:27 +0200 Subject: runlabel: execute /proc/self/exe and avoid recursion Execute /proc/self/exe instead of podman. This makes the runlabel command more portable as it works for binaries outside the path as well as for local builds. Also, avoid redundantly executing the runlabel command by setting the PODMAN_RUNLABEL_NESTED environment variable to "1". Podman now checks for this variable before executing the runlabel command and will throw an error in case the variable is set. Signed-off-by: Valentin Rothberg --- cmd/podman/runlabel.go | 9 +++++++++ cmd/podman/shared/funcs.go | 5 ++--- cmd/podman/shared/funcs_test.go | 10 +++++----- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/cmd/podman/runlabel.go b/cmd/podman/runlabel.go index c5dd98ee6..34e6b9093 100644 --- a/cmd/podman/runlabel.go +++ b/cmd/podman/runlabel.go @@ -94,6 +94,14 @@ func runlabelCmd(c *cli.Context) error { newImage *image.Image ) + // Evil images could trick into recursively executing the runlabel + // command. Avoid this by setting the "PODMAN_RUNLABEL_NESTED" env + // variable when executing a label first. + nested := os.Getenv("PODMAN_RUNLABEL_NESTED") + if nested == "1" { + return fmt.Errorf("nested runlabel calls: runlabels cannot execute the runlabel command") + } + opts := make(map[string]string) runtime, err := libpodruntime.GetRuntime(c) if err != nil { @@ -177,6 +185,7 @@ func runlabelCmd(c *cli.Context) error { cmd := shared.GenerateCommand(runLabel, imageName, c.String("name")) env := shared.GenerateRunEnvironment(c.String("name"), imageName, opts) + env = append(env, "PODMAN_RUNLABEL_NESTED=1") if !c.Bool("quiet") { fmt.Printf("Command: %s\n", strings.Join(cmd, " ")) diff --git a/cmd/podman/shared/funcs.go b/cmd/podman/shared/funcs.go index 5c401634c..21e7fe10d 100644 --- a/cmd/podman/shared/funcs.go +++ b/cmd/podman/shared/funcs.go @@ -15,9 +15,8 @@ func GenerateCommand(command, imageName, name string) []string { name = imageName } cmd := strings.Split(command, " ") - // Replace the first position of cmd with podman whether - // it is docker, /usr/bin/docker, or podman - newCommand = append(newCommand, "podman") + // Replace the first element of cmd with "/proc/self/exe" + newCommand = append(newCommand, "/proc/self/exe") for _, arg := range cmd[1:] { var newArg string switch arg { diff --git a/cmd/podman/shared/funcs_test.go b/cmd/podman/shared/funcs_test.go index 3d0ac005f..612be480b 100644 --- a/cmd/podman/shared/funcs_test.go +++ b/cmd/podman/shared/funcs_test.go @@ -15,35 +15,35 @@ var ( func TestGenerateCommand(t *testing.T) { inputCommand := "docker run -it --name NAME -e NAME=NAME -e IMAGE=IMAGE IMAGE echo install" - correctCommand := "podman run -it --name bar -e NAME=bar -e IMAGE=foo foo echo install" + correctCommand := "/proc/self/exe run -it --name bar -e NAME=bar -e IMAGE=foo foo echo install" newCommand := GenerateCommand(inputCommand, "foo", "bar") assert.Equal(t, correctCommand, strings.Join(newCommand, " ")) } func TestGenerateCommandPath(t *testing.T) { inputCommand := "/usr/bin/docker run -it --name NAME -e NAME=NAME -e IMAGE=IMAGE IMAGE echo install" - correctCommand := "podman run -it --name bar -e NAME=bar -e IMAGE=foo foo echo install" + correctCommand := "/proc/self/exe run -it --name bar -e NAME=bar -e IMAGE=foo foo echo install" newCommand := GenerateCommand(inputCommand, "foo", "bar") assert.Equal(t, correctCommand, strings.Join(newCommand, " ")) } func TestGenerateCommandNoSetName(t *testing.T) { inputCommand := "docker run -it --name NAME -e NAME=NAME -e IMAGE=IMAGE IMAGE echo install" - correctCommand := "podman run -it --name foo -e NAME=foo -e IMAGE=foo foo echo install" + correctCommand := "/proc/self/exe run -it --name foo -e NAME=foo -e IMAGE=foo foo echo install" newCommand := GenerateCommand(inputCommand, "foo", "") assert.Equal(t, correctCommand, strings.Join(newCommand, " ")) } func TestGenerateCommandNoName(t *testing.T) { inputCommand := "docker run -it -e IMAGE=IMAGE IMAGE echo install" - correctCommand := "podman run -it -e IMAGE=foo foo echo install" + correctCommand := "/proc/self/exe run -it -e IMAGE=foo foo echo install" newCommand := GenerateCommand(inputCommand, "foo", "") assert.Equal(t, correctCommand, strings.Join(newCommand, " ")) } func TestGenerateCommandAlreadyPodman(t *testing.T) { inputCommand := "podman run -it --name NAME -e NAME=NAME -e IMAGE=IMAGE IMAGE echo install" - correctCommand := "podman run -it --name bar -e NAME=bar -e IMAGE=foo foo echo install" + correctCommand := "/proc/self/exe run -it --name bar -e NAME=bar -e IMAGE=foo foo echo install" newCommand := GenerateCommand(inputCommand, "foo", "bar") assert.Equal(t, correctCommand, strings.Join(newCommand, " ")) } -- cgit v1.2.3-54-g00ecf