]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.14] os/exec: use environment variables for user token when present
authorLiam 'Auzzie' Haworth <liam@haworth.id.au>
Tue, 25 Feb 2020 00:11:28 +0000 (00:11 +0000)
committerIan Lance Taylor <iant@golang.org>
Sun, 29 Mar 2020 17:15:56 +0000 (17:15 +0000)
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: 32216b7291418f9285147a93ed6d0ba028f94ef2
GitHub-Pull-Request: golang/go#37402
Reviewed-on: https://go-review.googlesource.com/c/go/+/220587
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
(cherry picked from commit e0c3ded337e95ded40eb401e7d9e74716e3a445f)
Reviewed-on: https://go-review.googlesource.com/c/go/+/226281

src/go/build/deps_test.go
src/internal/syscall/execenv/execenv_default.go [new file with mode: 0644]
src/internal/syscall/execenv/execenv_windows.go [moved from src/os/env_windows.go with 64% similarity]
src/os/env_default.go [deleted file]
src/os/exec/exec.go
src/os/exec_posix.go

index a64c2b32419cdd769d7eef7ff576c8a7f081aee5..8eed6260a2b4438308ec75f696c1112f424b027e 100644 (file)
@@ -153,6 +153,7 @@ var pkgDeps = map[string][]string{
        "internal/syscall/unix":             {"L0", "syscall"},
        "internal/syscall/windows":          {"L0", "syscall", "internal/syscall/windows/sysdll", "unicode/utf16"},
        "internal/syscall/windows/registry": {"L0", "syscall", "internal/syscall/windows/sysdll", "unicode/utf16"},
+       "internal/syscall/execenv":          {"L0", "syscall", "internal/syscall/windows", "unicode/utf16"},
        "time": {
                // "L0" without the "io" package:
                "errors",
@@ -170,10 +171,10 @@ var pkgDeps = map[string][]string{
        "internal/cfg":     {"L0"},
        "internal/poll":    {"L0", "internal/oserror", "internal/race", "syscall", "time", "unicode/utf16", "unicode/utf8", "internal/syscall/windows", "internal/syscall/unix"},
        "internal/testlog": {"L0"},
-       "os":               {"L1", "os", "syscall", "time", "internal/oserror", "internal/poll", "internal/syscall/windows", "internal/syscall/unix", "internal/testlog"},
+       "os":               {"L1", "os", "syscall", "time", "internal/oserror", "internal/poll", "internal/syscall/windows", "internal/syscall/unix", "internal/syscall/execenv", "internal/testlog"},
        "path/filepath":    {"L2", "os", "syscall", "internal/syscall/windows"},
        "io/ioutil":        {"L2", "os", "path/filepath", "time"},
-       "os/exec":          {"L2", "os", "context", "path/filepath", "syscall"},
+       "os/exec":          {"L2", "os", "context", "path/filepath", "syscall", "internal/syscall/execenv"},
        "os/signal":        {"L2", "os", "syscall"},
 
        // OS enables basic operating system functionality,
diff --git a/src/internal/syscall/execenv/execenv_default.go b/src/internal/syscall/execenv/execenv_default.go
new file mode 100644 (file)
index 0000000..4bdbb55
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !windows
+
+package execenv
+
+import "syscall"
+
+// Default will return the default environment
+// variables based on the process attributes
+// provided.
+//
+// Defaults to syscall.Environ() on all platforms
+// other than Windows.
+func Default(sys *syscall.SysProcAttr) ([]string, error) {
+       return syscall.Environ(), nil
+}
similarity index 64%
rename from src/os/env_windows.go
rename to src/internal/syscall/execenv/execenv_windows.go
index b1b1ee4b3e67530a28d60b80644f09111390db08..b50029c19839bf9dc034487369121d5faf1edebe 100644 (file)
@@ -1,8 +1,10 @@
-// Copyright 2019 The Go Authors. All rights reserved.
+// Copyright 2020 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package os
+// +build windows
+
+package execenv
 
 import (
        "internal/syscall/windows"
@@ -11,9 +13,17 @@ import (
        "unsafe"
 )
 
-func environForSysProcAttr(sys *syscall.SysProcAttr) (env []string, err error) {
+// Default will return the default environment
+// variables based on the process attributes
+// provided.
+//
+// If the process attributes contain a token, then
+// the environment variables will be sourced from
+// the defaults for that user token, otherwise they
+// will be sourced from syscall.Environ().
+func Default(sys *syscall.SysProcAttr) (env []string, err error) {
        if sys == nil || sys.Token == 0 {
-               return Environ(), nil
+               return syscall.Environ(), nil
        }
        var block *uint16
        err = windows.CreateEnvironmentBlock(&block, sys.Token, false)
diff --git a/src/os/env_default.go b/src/os/env_default.go
deleted file mode 100644 (file)
index c11ccce..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !windows
-
-package os
-
-import "syscall"
-
-func environForSysProcAttr(sys *syscall.SysProcAttr) ([]string, error) {
-       return Environ(), nil
-}
index 3474ae0ca497e91369b32e05c7b458b81e1a3254..0c495755116f5254030d45284ea31515cadb8487 100644 (file)
@@ -24,6 +24,7 @@ import (
        "bytes"
        "context"
        "errors"
+       "internal/syscall/execenv"
        "io"
        "os"
        "path/filepath"
@@ -222,11 +223,11 @@ func interfaceEqual(a, b interface{}) bool {
        return a == b
 }
 
-func (c *Cmd) envv() []string {
+func (c *Cmd) envv() ([]string, error) {
        if c.Env != nil {
-               return c.Env
+               return c.Env, nil
        }
-       return os.Environ()
+       return execenv.Default(c.SysProcAttr)
 }
 
 func (c *Cmd) argv() []string {
@@ -413,11 +414,15 @@ func (c *Cmd) Start() error {
        }
        c.childFiles = append(c.childFiles, c.ExtraFiles...)
 
-       var err error
+       envv, err := c.envv()
+       if err != nil {
+               return err
+       }
+
        c.Process, err = os.StartProcess(c.Path, c.argv(), &os.ProcAttr{
                Dir:   c.Dir,
                Files: c.childFiles,
-               Env:   addCriticalEnv(dedupEnv(c.envv())),
+               Env:   addCriticalEnv(dedupEnv(envv)),
                Sys:   c.SysProcAttr,
        })
        if err != nil {
index 95ccc246a82110d5f835f6657c46c9cc80242a89..45b47a542d6a9bf886c41dfd0e7eb4d87dfbe2ae 100644 (file)
@@ -7,6 +7,7 @@
 package os
 
 import (
+       "internal/syscall/execenv"
        "runtime"
        "syscall"
 )
@@ -39,7 +40,7 @@ func startProcess(name string, argv []string, attr *ProcAttr) (p *Process, err e
                Sys: attr.Sys,
        }
        if sysattr.Env == nil {
-               sysattr.Env, err = environForSysProcAttr(sysattr.Sys)
+               sysattr.Env, err = execenv.Default(sysattr.Sys)
                if err != nil {
                        return nil, err
                }