os/exec: os.Environ() is not appropriate default for passing to syscall.StartProcess if attr.Sys.Token != 0 on Windows #29534
Labels
FeatureRequest
FrozenDueToAge
NeedsInvestigation
Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
OS-Windows
Milestone
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.
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 env
OutputWhat 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 ifenv == nil
andattr.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 exampleHOMEPATH
,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 asHOMEPATH
,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
andenv == nil
, a call is made to CreateEnvironmentBlock, passing inattr.Sys.Token
forHANDLE 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.
The text was updated successfully, but these errors were encountered: