Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/go: arbitrary code execution during “go get” #23672

Closed
rsc opened this issue Feb 2, 2018 · 12 comments
Closed

cmd/go: arbitrary code execution during “go get” #23672

rsc opened this issue Feb 2, 2018 · 12 comments

Comments

@rsc
Copy link
Contributor

rsc commented Feb 2, 2018

Go get downloads and builds source code. It is not meant to execute arbitrary code.

When cgo is enabled, the build step during “go get” invokes the host C compiler, gcc or clang, adding compiler flags specified in the Go source files. Both gcc and clang support a plugin mechanism in which a shared-library plugin is loaded into the compiler, as directed by compiler flags. This means that a Go package repository can contain an attack.so file along with a Go source file that says (for example) // #cgo CFLAGS: -fplugin=attack.so, causing the attack plugin to be loaded into the host C compiler during the build. Gcc and clang plugins are completely unrestricted in their access to the host system.

Thanks to Christopher Brown of Mattermost for reporting this problem.

This issue is CVE-2018-6574.

Fixed in Go 1.8.7 by commit 44821583bc16.
Fixed in Go 1.9.4 by commit 867fb18b6d5b.
Fixed in Go 1.10rc2 by commit 1dcb5836ad2c.

The fix changes “go build” (used during “go get” and “go install”) to limit the flags that can appear in Go source file #cgo directives to a list of allowed compiler flags; -fplugin= and other variants are not on the allowed list. The same restrictions are applied to compiler flags obtained from pkg-config. Flags obtained from the environment variables $CGO_CFLAGS and so on are not restricted, since those variables can only be set by the user running the build. To change the set of allowed compiler flags, new environment variables $CGO_CFLAGS_ALLOW and $CGO_CFLAGS_DISALLOW can set to regular expressions matching additional allowed and disallowed flags. Run “go doc cgo” for details.

Code that passes a flag and argument pair to the linker must now use one -Wl flag instead of two: use #cgo LDFLAGS: -Wl,-rpath,$ORIGIN, not #cgo LDFLAGS: -Wl,-rpath -Wl,$ORIGIN.

Also, //go:cgo... directives, including //go:cgo_ldflag, are now disallowed except in cgo-generated source code and some special cases in the standard library. Packages outside the standard library that attempt to use these directives will no longer build.

@rsc rsc added this to the Go1.10 milestone Feb 2, 2018
@rsc rsc self-assigned this Feb 2, 2018
gopherbot pushed a commit that referenced this issue Feb 7, 2018
Both gcc and clang accept an option -fplugin=code.so to load
a plugin from the ELF shared object file code.so.
Obviously that plugin can then do anything it wants
during the build. This is contrary to the goal of "go get"
never running untrusted code during the build.
(What happens if you choose to run the result of
the build is your responsibility.)

Disallow this behavior by only allowing a small set of
known command-line flags in #cgo CFLAGS directives
(and #cgo LDFLAGS, etc).

The new restrictions can be adjusted by the environment
variables CGO_CFLAGS_ALLOW, CGO_CFLAGS_DISALLOW,
and so on. See the documentation.

In addition to excluding cgo-defined flags, we also have to
make sure that when we pass file names on the command
line, they don't look like flags. So we now refuse to build
packages containing suspicious file names like -x.go.

A wrinkle in all this is that GNU binutils uniformly accept
@foo on the command line to mean "if the file foo exists,
then substitute its contents for @foo in the command line".
So we must also reject @x.go, flags and flag arguments
beginning with @, and so on.

Fixes #23672, CVE-2018-6574.

Change-Id: I59e7c1355155c335a5c5ae0d2cf8fa7aa313940a
Reviewed-on: https://team-review.git.corp.google.com/209949
Reviewed-by: Ian Lance Taylor <iant@google.com>
@rsc rsc changed the title security: issue [Go 1.10rc1] cmd/go: arbitrary code execution during “go get” Feb 7, 2018
ilovezfs added a commit to ilovezfs/homebrew-core that referenced this issue Feb 8, 2018
ilovezfs added a commit to ilovezfs/homebrew-core that referenced this issue Feb 8, 2018
mistydemeo pushed a commit to Homebrew/homebrew-core that referenced this issue Feb 8, 2018
mistydemeo pushed a commit to Homebrew/homebrew-core that referenced this issue Feb 8, 2018
CVE-2018-6574
golang/go#23672

Closes #23807.

Signed-off-by: Misty De Meo <mistydemeo@github.com>
@anacrolix
Copy link
Contributor

Consider these compiler flags:

-fno-exceptions
-fno-rtti
-fpermissive

And also -framework as a linker option:

-Wl,-framework

See go-libutp and go-gtk.

@mattn
Copy link
Member

mattn commented Feb 8, 2018

In the case of go-gtk, these flags are provided from pkg-config. Fortunately, I could build go-gtk on Windows. I still not confirm Linux.

@dmitris
Copy link
Contributor

dmitris commented Feb 8, 2018

miekg/pkcs11#63 - go1.9.4 breaks building github.com/miekg/pkcs11 on Linux as it does not allow -Wl,--no-as-needed - could that flag be added, please? Otherwise users would have to run install and test as CGO_LDFLAGS_ALLOW='-Wl,--no-as-needed' go install and it will break lots of CI builds.

@ianlancetaylor
Copy link
Contributor

I've opened #23749 as a place to collect options that should be added to the whitelists.

flx42 added a commit to NVIDIA/k8s-device-plugin that referenced this issue Feb 9, 2018
gopherbot pushed a commit that referenced this issue Feb 16, 2018
…where

It's used on Solaris to import symbols from shared libraries, e.g., in
golang.org/x/sys/unix and golang.org/x/net/internal/socket.
We could use a different directive but that would require build tags
in all the places that use it.

Updates #23672
Updates #23749

Change-Id: I47fcf72a6d2862e304204705979c2056c2f78ec5
Reviewed-on: https://go-review.googlesource.com/94018
Run-TryBot: Andrew Bonventre <andybons@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
(cherry picked from commit 4a54ff21c25f1b5d7a4f73fd33214e1f8c83a9b9)
Reviewed-on: https://go-review.googlesource.com/94675
Reviewed-by: Andrew Bonventre <andybons@golang.org>
DarthSim pushed a commit to imgproxy/imgproxy that referenced this issue Feb 22, 2018
This golang/go#23672 security fix breaks
CGO compilation in go version 1.9.4 by disallowing LDFLAGS in
process.go:5
dtzWill pushed a commit to llvm-mirror/llvm that referenced this issue Feb 23, 2018
…e restricted to prevent arbitrary code execution.

golang/go#23672

By this change, building a Go code with LLVM Go bindings causes a compilation error as follows.

  go build llvm.org/llvm/bindings/go/llvm: invalid flag in #cgo LDFLAGS: -Wl,-headerpad_max_install_names

llvm-go tool generates cgo LDFLAGS directive from `llvm-config --ldflags` and it contains -Wl,option options. But -Wl,option is banned by default. To avoid this problem, we need to set $CGO_LDFLAGS_ALLOW environment variable to notify a compiler that the flags should be allowed.

  $ export CGO_LDFLAGS_ALLOW='-Wl,(-search_paths_first|-headerpad_max_install_names)'

By default for go 1.10 and go 1.9.5 these options should appear in the accepted set of options, however, if you're running into the error it's useful to have this documented.

Patch by Ryuichi Hayashida

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@325946 91177308-0d34-0410-b5e6-96231b3b80d8
earl pushed a commit to earl/llvm-mirror that referenced this issue Feb 23, 2018
…e restricted to prevent arbitrary code execution.

golang/go#23672

By this change, building a Go code with LLVM Go bindings causes a compilation error as follows.

  go build llvm.org/llvm/bindings/go/llvm: invalid flag in #cgo LDFLAGS: -Wl,-headerpad_max_install_names

llvm-go tool generates cgo LDFLAGS directive from `llvm-config --ldflags` and it contains -Wl,option options. But -Wl,option is banned by default. To avoid this problem, we need to set $CGO_LDFLAGS_ALLOW environment variable to notify a compiler that the flags should be allowed.

  $ export CGO_LDFLAGS_ALLOW='-Wl,(-search_paths_first|-headerpad_max_install_names)'

By default for go 1.10 and go 1.9.5 these options should appear in the accepted set of options, however, if you're running into the error it's useful to have this documented.

Patch by Ryuichi Hayashida

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@325946 91177308-0d34-0410-b5e6-96231b3b80d8
jyknight pushed a commit to jyknight/llvm-monorepo that referenced this issue Mar 1, 2018
------------------------------------------------------------------------
r325946 | echristo | 2018-02-23 21:12:24 +0100 (Fri, 23 Feb 2018) | 15 lines

Because of CVE-2018-6574, some compiler options and linker options are restricted to prevent arbitrary code execution.

golang/go#23672

By this change, building a Go code with LLVM Go bindings causes a compilation error as follows.

  go build llvm.org/llvm/bindings/go/llvm: invalid flag in #cgo LDFLAGS: -Wl,-headerpad_max_install_names

llvm-go tool generates cgo LDFLAGS directive from `llvm-config --ldflags` and it contains -Wl,option options. But -Wl,option is banned by default. To avoid this problem, we need to set $CGO_LDFLAGS_ALLOW environment variable to notify a compiler that the flags should be allowed.

  $ export CGO_LDFLAGS_ALLOW='-Wl,(-search_paths_first|-headerpad_max_install_names)'

By default for go 1.10 and go 1.9.5 these options should appear in the accepted set of options, however, if you're running into the error it's useful to have this documented.

Patch by Ryuichi Hayashida
------------------------------------------------------------------------

llvm-svn=326076
jyknight pushed a commit to jyknight/llvm-monorepo that referenced this issue Mar 1, 2018
…e restricted to prevent arbitrary code execution.

golang/go#23672

By this change, building a Go code with LLVM Go bindings causes a compilation error as follows.

  go build llvm.org/llvm/bindings/go/llvm: invalid flag in #cgo LDFLAGS: -Wl,-headerpad_max_install_names

llvm-go tool generates cgo LDFLAGS directive from `llvm-config --ldflags` and it contains -Wl,option options. But -Wl,option is banned by default. To avoid this problem, we need to set $CGO_LDFLAGS_ALLOW environment variable to notify a compiler that the flags should be allowed.

  $ export CGO_LDFLAGS_ALLOW='-Wl,(-search_paths_first|-headerpad_max_install_names)'

By default for go 1.10 and go 1.9.5 these options should appear in the accepted set of options, however, if you're running into the error it's useful to have this documented.

Patch by Ryuichi Hayashida

llvm-svn=325946
krig added a commit to ClusterLabs/go-pacemaker that referenced this issue Mar 8, 2018
krig added a commit to ClusterLabs/hawk-apiserver that referenced this issue Mar 8, 2018
* github.com/krig/go-pacemaker b3f1806...efe89cc (1):
  > Drop LDFLAGS usage as this is now disallowed (see golang/go#23672)
rn added a commit to rn/linuxkit that referenced this issue Mar 24, 2018
Go commit golang/go#23672 introduced a
whitelist ofr flags passed into gcc to prevent arbitrary code
execution (CVE-2018-6574). The x86 rngd code uses two CFLAGS
not on the whitelist. Add them to 'CGO_CFLAGS_ALLOW'.

Signed-off-by: Rolf Neugebauer <rolf.neugebauer@gmail.com>
@ghost ghost mentioned this issue Apr 23, 2018
llvm-git-migration pushed a commit to llvm-git-prototype/llvm that referenced this issue Nov 6, 2018
------------------------------------------------------------------------
r325946 | echristo | 2018-02-23 21:12:24 +0100 (Fri, 23 Feb 2018) | 15 lines

Because of CVE-2018-6574, some compiler options and linker options are restricted to prevent arbitrary code execution.

golang/go#23672

By this change, building a Go code with LLVM Go bindings causes a compilation error as follows.

  go build llvm.org/llvm/bindings/go/llvm: invalid flag in #cgo LDFLAGS: -Wl,-headerpad_max_install_names

llvm-go tool generates cgo LDFLAGS directive from `llvm-config --ldflags` and it contains -Wl,option options. But -Wl,option is banned by default. To avoid this problem, we need to set $CGO_LDFLAGS_ALLOW environment variable to notify a compiler that the flags should be allowed.

  $ export CGO_LDFLAGS_ALLOW='-Wl,(-search_paths_first|-headerpad_max_install_names)'

By default for go 1.10 and go 1.9.5 these options should appear in the accepted set of options, however, if you're running into the error it's useful to have this documented.

Patch by Ryuichi Hayashida
------------------------------------------------------------------------

llvm-svn=326076
llvm-git-migration pushed a commit to llvm-git-prototype/llvm that referenced this issue Jan 4, 2019
------------------------------------------------------------------------
r325946 | echristo | 2018-02-23 21:12:24 +0100 (Fri, 23 Feb 2018) | 15 lines

Because of CVE-2018-6574, some compiler options and linker options are restricted to prevent arbitrary code execution.

golang/go#23672

By this change, building a Go code with LLVM Go bindings causes a compilation error as follows.

  go build llvm.org/llvm/bindings/go/llvm: invalid flag in #cgo LDFLAGS: -Wl,-headerpad_max_install_names

llvm-go tool generates cgo LDFLAGS directive from `llvm-config --ldflags` and it contains -Wl,option options. But -Wl,option is banned by default. To avoid this problem, we need to set $CGO_LDFLAGS_ALLOW environment variable to notify a compiler that the flags should be allowed.

  $ export CGO_LDFLAGS_ALLOW='-Wl,(-search_paths_first|-headerpad_max_install_names)'

By default for go 1.10 and go 1.9.5 these options should appear in the accepted set of options, however, if you're running into the error it's useful to have this documented.

Patch by Ryuichi Hayashida
------------------------------------------------------------------------

llvm-svn: 326076
@golang golang locked and limited conversation to collaborators Feb 16, 2019
@rsc rsc removed their assignment Jun 23, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

10 participants