Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

os/exec: LookPath() doesn't consider chroot #39341

Open
sdclarke opened this issue Jun 1, 2020 · 5 comments
Open

os/exec: LookPath() doesn't consider chroot #39341

sdclarke opened this issue Jun 1, 2020 · 5 comments
Labels
help wanted NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@sdclarke
Copy link

sdclarke commented Jun 1, 2020

What version of Go are you using (go version)?

$ go version
go version go1.14.3 linux/amd64

Does this issue reproduce with the latest release?

yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/scottclarke/.cache/go-build"
GOENV="/home/scottclarke/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/scottclarke/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build189733440=/tmp/go-build -gno-record-gcc-switches"

What did you do?

package main

import (
	"log"
	"os"
	"os/exec"
	"syscall"
)

func main() {
	cmd := exec.Command("hello")
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.Dir = "/"
	cmd.Env = []string{"PATH=/bin"}
	cmd.SysProcAttr = &syscall.SysProcAttr{Chroot: "/home/scottclarke/chroot"}
	if err := cmd.Start(); err != nil {
		log.Fatalf("%#v", err.Error())
	}
	cmd.Wait()
}

Where /home/scottclarke/chroot contains a chroot which has an executable file /bin/hello, and there is no executable hello in the PATH of the system prior to the chroot.

What did you expect to see?

The hello executable being run, producing the output hello world.

What did you see instead?

The following error:
2020/06/01 11:36:32 "exec: \"hello\": executable file not found in $PATH"

This happens because the exec.Command() function calls LookPath() and sets the lookPathErr if it fails, which is checked in Start() and causes a failure. However this doesn't take into account the fact that the command will be run in a chroot.

@ianlancetaylor ianlancetaylor added help wanted NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Jun 1, 2020
@ianlancetaylor ianlancetaylor added this to the Backlog milestone Jun 1, 2020
@Sunnycheey
Copy link

Hello, I want to help to solve the problem. Is it suitable to check whether file path exists in the cmd.Start function?

@ianlancetaylor
Copy link
Contributor

Perhaps cmd.Start should ignore an earlier lookPathErr if Chroot is set. I don't think we can simply move the LookPath call, as that would change code that calls exec.Command and then looks at Path.

@Sunnycheey
Copy link

Sunnycheey commented Jun 6, 2020

I have found some bug in my code, so I close the original PR. The problem is more complex than I thought, because I also need to deal with Dir and Env variable, and the most difficult thing is I cannot figure out how to debug, since I must use the compiled Go binary to compile the new source. But I have tried to make some changes in this repo .

@gopherbot
Copy link

Change https://golang.org/cl/236780 mentions this issue: os/exec: deal with chroot invalid in start a cmd fix #39341

Sunnycheey added a commit to Sunnycheey/go that referenced this issue Jun 6, 2020
@EdSchouten
Copy link

EdSchouten commented Jun 15, 2020

One thing to be careful for when fixing this is that chrooting will also affect the targets of symlinks. For example, a root directory containing a symlink pointing to /bin/foo may eventually expand to a different location depending on whether symlink expansion happens inside or outside the chroot.

One workaround we're using in bb-remote-execution is that we prepend /usr/bin/env -- to the command, so that it's not Go, but /usr/bin/env that does the $PATH lookup. This is of course suboptimal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

5 participants