-
Notifications
You must be signed in to change notification settings - Fork 18.7k
Description
What version of Go are you using (go version)?
I use a Mac, but cross-compile to Windows. This is my darwin env, but it isn't really relevant.
go version go1.11.2 darwin/amd64
Does this issue reproduce with the latest release?
Yes.
What operating system and processor architecture are you using (go env)?
Again, this isn't really relevant for this issue - but here is my env in any case.
go envOutput
$ go env GOARCH="amd64" GOBIN="" GOCACHE="/Users/pmoore/Library/Caches/go-build" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="darwin" GOOS="darwin" GOPATH="/Users/pmoore/go" GOPROXY="" GORACE="" GOROOT="/usr/local/Cellar/go/1.11.2/libexec" GOTMPDIR="" GOTOOLDIR="/usr/local/Cellar/go/1.11.2/libexec/pkg/tool/darwin_amd64" GCCGO="gccgo" CC="clang" CXX="clang++" 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 -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/v9/mll6p_rj5h94dt_m5m8j0f9c0000gn/T/go-build797508603=/tmp/go-build -gno-record-gcc-switches -fno-common"
What did you do?
I looked at https://github.com/golang/go/blob/go1.11.4/src/os/exec_posix.go#L39-L41
What did you expect to see?
I expected that on Windows os.Environ() would not be used as default value if env == nil and attr.Sys.Token != 0.
If attr.Sys.Token is nonzero, it indicates that the process is to be executed by a different user than the parent process was executed by. It is dangerous to use the environment of one user for a process running as a different user, since many environment variables are required by Windows subsystems, and are user-specific. For example HOMEPATH, LOCALAPPDATA, USERNAME are all user-specific, and often required by programs. A much better behaviour if no env is specified but an auth token is, would be to call CreateEnvironmentBlock with the given auth token, to create a new environment block that is appropriate for that user.
What did you see instead?
os.Environ() is used, even though the env vars (such as HOMEPATH, LOCALAPPDATA, USERNAME, ....) will undoubtedly cause problems for the process being created.
Proposed solution
I believe the best approach here is to introduce a behaviour change, and update both the docs and the implementation.
Doc update
State that if nil is passed for the environment, that the parent process environment will be used if no authentication token is specified ((exec.Command).SysProcAttr.Token == 0) otherwise the default environment for the given authentication token will be used.
Code change
If running on Windows, and (exec.Command).SysProcAttr.Token != 0 and env == nil, a call is made to CreateEnvironmentBlock, passing in attr.Sys.Token for HANDLE hToken, to retrieve a usable environment block. Note, a cleanup call to DestroyEnvironmentBlock is also needed after copying the environment block.
I'm happy to make a PR for this, if the proposed approach is deemed acceptable. The syscalls look something like this. When implementing the syscalls, I would of course plug into the existing code generation in the standard library to do this.