Skip to content

Commit e6f15fa

Browse files
KatelynHaworthianlancetaylor
authored andcommitted
[release-branch.go1.14] os/exec: use environment variables for user token when present
Builds upon the changes from #32000 which supported sourcing environment variables for a new process from the environment of a Windows user token when supplied. But due to the logic of os/exec, the Env field of a process was always non-nil when it reached that change. This change moves the logic up to os/exec, specifically when os.ProcAttr is being built for the os.StartProcess call, this ensures that if a user token has been supplied and no Env slice has been provided on the command it will be sourced from the user's environment. If no token is provided, or the program is compiled for any other platform than Windows, the default environment will be sourced from syscall.Environ(). For #35314 Fixes #37471 Change-Id: I4c1722e90b91945eb6980d5c5928183269b50487 GitHub-Last-Rev: 32216b7 GitHub-Pull-Request: #37402 Reviewed-on: https://go-review.googlesource.com/c/go/+/220587 Run-TryBot: Ian Lance Taylor <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> (cherry picked from commit e0c3ded) Reviewed-on: https://go-review.googlesource.com/c/go/+/226281
1 parent 9d7dad1 commit e6f15fa

File tree

6 files changed

+48
-25
lines changed

6 files changed

+48
-25
lines changed

src/go/build/deps_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ var pkgDeps = map[string][]string{
153153
"internal/syscall/unix": {"L0", "syscall"},
154154
"internal/syscall/windows": {"L0", "syscall", "internal/syscall/windows/sysdll", "unicode/utf16"},
155155
"internal/syscall/windows/registry": {"L0", "syscall", "internal/syscall/windows/sysdll", "unicode/utf16"},
156+
"internal/syscall/execenv": {"L0", "syscall", "internal/syscall/windows", "unicode/utf16"},
156157
"time": {
157158
// "L0" without the "io" package:
158159
"errors",
@@ -170,10 +171,10 @@ var pkgDeps = map[string][]string{
170171
"internal/cfg": {"L0"},
171172
"internal/poll": {"L0", "internal/oserror", "internal/race", "syscall", "time", "unicode/utf16", "unicode/utf8", "internal/syscall/windows", "internal/syscall/unix"},
172173
"internal/testlog": {"L0"},
173-
"os": {"L1", "os", "syscall", "time", "internal/oserror", "internal/poll", "internal/syscall/windows", "internal/syscall/unix", "internal/testlog"},
174+
"os": {"L1", "os", "syscall", "time", "internal/oserror", "internal/poll", "internal/syscall/windows", "internal/syscall/unix", "internal/syscall/execenv", "internal/testlog"},
174175
"path/filepath": {"L2", "os", "syscall", "internal/syscall/windows"},
175176
"io/ioutil": {"L2", "os", "path/filepath", "time"},
176-
"os/exec": {"L2", "os", "context", "path/filepath", "syscall"},
177+
"os/exec": {"L2", "os", "context", "path/filepath", "syscall", "internal/syscall/execenv"},
177178
"os/signal": {"L2", "os", "syscall"},
178179

179180
// OS enables basic operating system functionality,
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright 2020 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
// +build !windows
6+
7+
package execenv
8+
9+
import "syscall"
10+
11+
// Default will return the default environment
12+
// variables based on the process attributes
13+
// provided.
14+
//
15+
// Defaults to syscall.Environ() on all platforms
16+
// other than Windows.
17+
func Default(sys *syscall.SysProcAttr) ([]string, error) {
18+
return syscall.Environ(), nil
19+
}

src/os/env_windows.go renamed to src/internal/syscall/execenv/execenv_windows.go

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
// Copyright 2019 The Go Authors. All rights reserved.
1+
// Copyright 2020 The Go Authors. All rights reserved.
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5-
package os
5+
// +build windows
6+
7+
package execenv
68

79
import (
810
"internal/syscall/windows"
@@ -11,9 +13,17 @@ import (
1113
"unsafe"
1214
)
1315

14-
func environForSysProcAttr(sys *syscall.SysProcAttr) (env []string, err error) {
16+
// Default will return the default environment
17+
// variables based on the process attributes
18+
// provided.
19+
//
20+
// If the process attributes contain a token, then
21+
// the environment variables will be sourced from
22+
// the defaults for that user token, otherwise they
23+
// will be sourced from syscall.Environ().
24+
func Default(sys *syscall.SysProcAttr) (env []string, err error) {
1525
if sys == nil || sys.Token == 0 {
16-
return Environ(), nil
26+
return syscall.Environ(), nil
1727
}
1828
var block *uint16
1929
err = windows.CreateEnvironmentBlock(&block, sys.Token, false)

src/os/env_default.go

Lines changed: 0 additions & 13 deletions
This file was deleted.

src/os/exec/exec.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"bytes"
2525
"context"
2626
"errors"
27+
"internal/syscall/execenv"
2728
"io"
2829
"os"
2930
"path/filepath"
@@ -222,11 +223,11 @@ func interfaceEqual(a, b interface{}) bool {
222223
return a == b
223224
}
224225

225-
func (c *Cmd) envv() []string {
226+
func (c *Cmd) envv() ([]string, error) {
226227
if c.Env != nil {
227-
return c.Env
228+
return c.Env, nil
228229
}
229-
return os.Environ()
230+
return execenv.Default(c.SysProcAttr)
230231
}
231232

232233
func (c *Cmd) argv() []string {
@@ -413,11 +414,15 @@ func (c *Cmd) Start() error {
413414
}
414415
c.childFiles = append(c.childFiles, c.ExtraFiles...)
415416

416-
var err error
417+
envv, err := c.envv()
418+
if err != nil {
419+
return err
420+
}
421+
417422
c.Process, err = os.StartProcess(c.Path, c.argv(), &os.ProcAttr{
418423
Dir: c.Dir,
419424
Files: c.childFiles,
420-
Env: addCriticalEnv(dedupEnv(c.envv())),
425+
Env: addCriticalEnv(dedupEnv(envv)),
421426
Sys: c.SysProcAttr,
422427
})
423428
if err != nil {

src/os/exec_posix.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
package os
88

99
import (
10+
"internal/syscall/execenv"
1011
"runtime"
1112
"syscall"
1213
)
@@ -39,7 +40,7 @@ func startProcess(name string, argv []string, attr *ProcAttr) (p *Process, err e
3940
Sys: attr.Sys,
4041
}
4142
if sysattr.Env == nil {
42-
sysattr.Env, err = environForSysProcAttr(sysattr.Sys)
43+
sysattr.Env, err = execenv.Default(sysattr.Sys)
4344
if err != nil {
4445
return nil, err
4546
}

0 commit comments

Comments
 (0)