Skip to content

Commit 46e2e2e

Browse files
rscrolandshoemaker
authored andcommitted
cmd/go: pass resolved CC, GCCGO to cgo
This makes sure the go command and cgo agree about exactly which compiler is being used. This issue was reported by RyotaK. Fixes CVE-2021-3115 Fixes #43783 Change-Id: If171c5c8b2523efb5ea2d957e5ad1380a038149c Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/949416 Reviewed-by: Ian Lance Taylor <[email protected]> Reviewed-by: Jay Conrod <[email protected]> Reviewed-on: https://go-review.googlesource.com/c/go/+/284780 Run-TryBot: Roland Shoemaker <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> Trust: Roland Shoemaker <[email protected]>
1 parent 3d40895 commit 46e2e2e

File tree

2 files changed

+26
-7
lines changed

2 files changed

+26
-7
lines changed

src/cmd/go/internal/work/action.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ type Builder struct {
5757
id sync.Mutex
5858
toolIDCache map[string]string // tool name -> tool ID
5959
buildIDCache map[string]string // file name -> build ID
60+
61+
cgoEnvOnce sync.Once
62+
cgoEnvCache []string
6063
}
6164

6265
// NOTE: Much of Action would not need to be exported if not for test.

src/cmd/go/internal/work/exec.go

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,10 +1164,8 @@ func (b *Builder) vet(ctx context.Context, a *Action) error {
11641164
return err
11651165
}
11661166

1167-
env := b.cCompilerEnv()
1168-
if cfg.BuildToolchainName == "gccgo" {
1169-
env = append(env, "GCCGO="+BuildToolchain.compiler())
1170-
}
1167+
// TODO(rsc): Why do we pass $GCCGO to go vet?
1168+
env := b.cgoEnv()
11711169

11721170
p := a.Package
11731171
tool := VetTool
@@ -2110,6 +2108,24 @@ func (b *Builder) cCompilerEnv() []string {
21102108
return []string{"TERM=dumb"}
21112109
}
21122110

2111+
// cgoEnv returns environment variables to set when running cgo.
2112+
// Some of these pass through to cgo running the C compiler,
2113+
// so it includes cCompilerEnv.
2114+
func (b *Builder) cgoEnv() []string {
2115+
b.cgoEnvOnce.Do(func() {
2116+
cc, err := exec.LookPath(b.ccExe()[0])
2117+
if err != nil || filepath.Base(cc) == cc { // reject relative path
2118+
cc = "/missing-cc"
2119+
}
2120+
gccgo := GccgoBin
2121+
if filepath.Base(gccgo) == gccgo { // reject relative path
2122+
gccgo = "/missing-gccgo"
2123+
}
2124+
b.cgoEnvCache = append(b.cCompilerEnv(), "CC="+cc, "GCCGO="+gccgo)
2125+
})
2126+
return b.cgoEnvCache
2127+
}
2128+
21132129
// mkdir makes the named directory.
21142130
func (b *Builder) Mkdir(dir string) error {
21152131
// Make Mkdir(a.Objdir) a no-op instead of an error when a.Objdir == "".
@@ -2710,13 +2726,13 @@ func (b *Builder) cgo(a *Action, cgoExe, objdir string, pcCFLAGS, pcLDFLAGS, cgo
27102726
// along to the host linker. At this point in the code, cgoLDFLAGS
27112727
// consists of the original $CGO_LDFLAGS (unchecked) and all the
27122728
// flags put together from source code (checked).
2713-
cgoenv := b.cCompilerEnv()
2729+
cgoenv := b.cgoEnv()
27142730
if len(cgoLDFLAGS) > 0 {
27152731
flags := make([]string, len(cgoLDFLAGS))
27162732
for i, f := range cgoLDFLAGS {
27172733
flags[i] = strconv.Quote(f)
27182734
}
2719-
cgoenv = []string{"CGO_LDFLAGS=" + strings.Join(flags, " ")}
2735+
cgoenv = append(cgoenv, "CGO_LDFLAGS="+strings.Join(flags, " "))
27202736
}
27212737

27222738
if cfg.BuildToolchainName == "gccgo" {
@@ -2947,7 +2963,7 @@ func (b *Builder) dynimport(a *Action, p *load.Package, objdir, importGo, cgoExe
29472963
if p.Standard && p.ImportPath == "runtime/cgo" {
29482964
cgoflags = []string{"-dynlinker"} // record path to dynamic linker
29492965
}
2950-
return b.run(a, base.Cwd, p.ImportPath, b.cCompilerEnv(), cfg.BuildToolexec, cgoExe, "-dynpackage", p.Name, "-dynimport", dynobj, "-dynout", importGo, cgoflags)
2966+
return b.run(a, base.Cwd, p.ImportPath, b.cgoEnv(), cfg.BuildToolexec, cgoExe, "-dynpackage", p.Name, "-dynimport", dynobj, "-dynout", importGo, cgoflags)
29512967
}
29522968

29532969
// Run SWIG on all SWIG input files.

0 commit comments

Comments
 (0)