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: options missing from cgo whitelists #23749

Closed
ianlancetaylor opened this issue Feb 8, 2018 · 138 comments
Closed

cmd/go: options missing from cgo whitelists #23749

ianlancetaylor opened this issue Feb 8, 2018 · 138 comments

Comments

@ianlancetaylor
Copy link
Contributor

The recent security patches for cmd/go (#23672) added a whitelist of options permitted for use with cgo. Several different people have reported packages that fail to build by default because they use options that are not on the whitelists. This issue is intended to collect a list of all the missing options, so that we can add them in a single CL.

@ianlancetaylor ianlancetaylor added this to the Go1.10 milestone Feb 8, 2018
@ianlancetaylor
Copy link
Contributor Author

#23737 reports that flags generated by pkg-config -libs are being checked against the compiler whitelist, and CGO_CFLAGS_ALLOW, when they should instead by checked against the linker whitelist and CGO_LDFLAGS_ALLOW. There is a CL to fix this: https://golang.org/cl/92755.

@ianlancetaylor
Copy link
Contributor Author

ianlancetaylor commented Feb 8, 2018

The linker whitelist should accept .a files as it already accepts .o, .so, etc., files. There is a CL to fix this: https://golang.org/cl/92855. This is #23739.

@ianlancetaylor
Copy link
Contributor Author

Comments on #23672 list these compiler options:

-fno-exceptions
-fno-rtti
-fpermissive

and these linker options:

-Wl,-framework
-Wl,--no-as-needed

@ianlancetaylor
Copy link
Contributor Author

#23742 suggests adding the compiler option -fmodules. The clang compiler supports a number of -fmodules options, but it's not clear that they are all safe. In particular -fmodules-cache-path and -fmodules-user-build-path would seem to permit specifying a path that clang will use to read modules, which could perhaps change the compilation mode in various ways.

@ianlancetaylor
Copy link
Contributor Author

#23743 suggests adding the linker option -Wl,--no-as-needed. There is a CL for this: https://golang.org/cl/92795.

@ianlancetaylor
Copy link
Contributor Author

#23744 suggests adding these compiler options:

-finput-charset=UTF-8
--std=c99
-pedantic-errors

@ianlancetaylor
Copy link
Contributor Author

There are many compiler and linker options that may be used with either a single dash or a double dash. We should be similarly lax in the whitelists.

@andlabs
Copy link
Contributor

andlabs commented Feb 8, 2018

For orthogonality: I forget if the option to add a directory to -framework's search path is already covered or not. I also forget what option that is. (The typical use case that I can think of is /Library/Frameworks, which is where Apple puts app-specific frameworks, and is not searched by default.)

@ianlancetaylor ianlancetaylor added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Feb 8, 2018
@andlabs
Copy link
Contributor

andlabs commented Feb 8, 2018

Also is -as-needed safe to use with cgo in the first place? This blog post (which is the first result I can find for "gcc as-needed") says that it's a positional argument, but I'm not sure if cgo guarantees anything about where your flags go on the resultant command lines.

@ianlancetaylor
Copy link
Contributor Author

@andlabs It's fine to write

#cgo LDFLAGS: -Wl,--as-needed -loptlib -WL,--no-as-needed

In any case, the topic for this issue should be whether options are safe to use from go get.

@rgburke
Copy link

rgburke commented Feb 8, 2018

When using:

#cgo !windows pkg-config: --static ${SRCDIR}/vendor/libgit2/build/libgit2.pc

compilation fails with the following message:

invalid pkg-config package name: --static

Looking over the code (for go 1.9.4) it appears there aren't any enviroment variables that can be used to whiteslist pkg-config arguments.

@ianlancetaylor
Copy link
Contributor Author

@rgburke pkg-config output goes through the same FLAGS_ALLOW variables as other outputs.

However, it appears that pkg-config -libs checks CGO_CFLAGS_ALLOW when it ought to check CGO_LDFLAGS_ALLOW.

@mirtchovski
Copy link
Contributor

mirtchovski commented Feb 8, 2018

We link a large number of C libraries statically in a closed-source project. Up until now we have been doing the following:

#cgo LDFLAGS:/path/to/one/liblibrary1.a
#cgo LDFLAGS:/path/to/two/liblibrary2.a
etc.

This is of course disallowed now. A workaround:

#cgo LDFLAGS:-L/path/to/one -llibrary1
#cgo LDFLAGS:-L/path/to/two -llibrary2

However some of these directories contain dynamic libraries too, which confuses the linker. Another option is to add '/' to the list of allowed "names" in https://go-review.googlesource.com/c/go/+/92855 In particular change on line 91 is:

re(`[a-zA-Z0-9_\/].*\.(o|obj|dll|dylib|so|a)`), // direct linker inputs: x.o or libfoo.so (but not -foo.o or @foo.o)

the latter option fixes our issue but I can't speak to its impact on security.

@andlabs
Copy link
Contributor

andlabs commented Feb 8, 2018

@mirtchovski there's a patch for that (the issue is that .a was not whitelisted, but other object file formats were)

@mirtchovski
Copy link
Contributor

mirtchovski commented Feb 8, 2018

.a is now whitelisted (after that patch) so 'libsomething.a' will work, but '/path/to/libsomething.a' will not work.

@jeddenlea
Copy link
Contributor

jeddenlea commented Feb 8, 2018

@ianlancetaylor @rgburke I actually ran into the very same problem with --static which lead me down the hole to #23737. --static is rejected because it doesn't appear to be a valid package name before attempting to execute pkg-config, here

if !load.SafeArg(pkg) {
return nil, nil, fmt.Errorf("invalid pkg-config package name: %s", pkg)
.

Our quick fix internally was to point PKG_CONFIG to a script which simply executed pkg-config --static "$@".

@rgburke
Copy link

rgburke commented Feb 8, 2018

@jeddenlea - Thank you very much! I was trying to find a workaround but didn't think of that.

@bobrik
Copy link

bobrik commented Feb 9, 2018

We hit this with -msse and -msse4.2.

@minux
Copy link
Member

minux commented Feb 9, 2018 via email

@peterebden
Copy link

We've hit this with --std=c99

@zcm211
Copy link

zcm211 commented May 7, 2018

@PassKit Did you solve this problem?

@AlexRouSg
Copy link
Contributor

@zcm211 If you're talking about https://github.com/miekg/pkcs11 they removed the -I... linker flag in feb. If you're using a package that uses it then you have to set the environmental variable CGO_LDFLAGS_ALLOW="-I.*"

@glycerine
Copy link

darwin 64-bit, go1.10.2, I thought .o files were whitelisted for LDFLAGs, but I'm getting:

jaten@jatens-MacBook-Pro ~/go/src/github.com/go-interpreter/chezgo (master) $ make run                           
cd chez_scheme_9.5.1/c; make                                                                                     
make[1]: Nothing to be done for `doit'.                                                                          
go build && ./chezgo                                                                                             
go build github.com/go-interpreter/chezgo: invalid flag in #cgo LDFLAGS: ./chez_scheme_9.5.1/boot/a6osx/kernel.o 
make: *** [run] Error 1                                                                                          
jaten@jatens-MacBook-Pro ~/go/src/github.com/go-interpreter/chezgo (master) $ go version                         
go version go1.10.2 darwin/amd64                                                                                 
jaten@jatens-MacBook-Pro ~/go/src/github.com/go-interpreter/chezgo (master) $  

due to the cgo preamble in https://github.com/go-interpreter/chezgo/blob/master/embed.go#L10

#cgo LDFLAGS:  -liconv -lm -lncurses -L/usr/local/lib ./chez_scheme_9.5.1/boot/a6osx/kernel.o

@AlexRouSg
Copy link
Contributor

@glycerine According to https://go-review.googlesource.com/c/go/+/94676 they are. Maybe try a full path instead of a relative one?

@glycerine
Copy link

glycerine commented May 8, 2018

Good catch @AlexRouSg, the accept regex is buggy as you point out;

re(`[a-zA-Z0-9_/].*\.(a|o|obj|dll|dylib|so)`), // direct linker inputs: x.o or libfoo.so (but not -foo.o or @foo.o)

src/cmd/go/internal/work/security.go#121 should allow .o files to start with a . to support relative paths.

After all, I can't predict the users' GOPATH, or how nested the location of that file will become, so setting an absolute path isn't practical.

@andlabs
Copy link
Contributor

andlabs commented May 8, 2018

Is the .o file in the source directory? If so, referring to the source directory is what ${SRCDIR} was provided for. (I forget specifically why this was introduced, but it was not because of this issue.)

@glycerine
Copy link

@andlabs Even if there are klunky workarounds, relative paths should be linkable, and that is clearly a bug.

@andlabs
Copy link
Contributor

andlabs commented May 8, 2018

It is, except IIRC there is no guarantee that the link would be relative TO the source directory (it could very well be in $WORK, and then your relative path breaks again)... Again, I've forgotten the history; someone else will need to explain.

@reusee
Copy link

reusee commented May 11, 2018

gtk4 uses -mfpmath=sse

@AlexRouSg
Copy link
Contributor

@ianlancetaylor Instead of having separate whitelists for cflags and ldflags, should there just be one list? gcc/llvm doesn't seem to care that you mix ldflags into cflags and vice versa. And it seems sometimes C devs do that causing issues like #25493 or #23749 (comment)

@jmhodges
Copy link
Contributor

Ah, I see we have a ticket already, so let me mention "-D_THREAD_SAFE" from protobuf as documented in #25493

@gopherbot
Copy link

Change https://golang.org/cl/115415 mentions this issue: cmd/go: accept more safe CFLAGS/LDFLAGS

@gopherbot
Copy link

Change https://golang.org/cl/115435 mentions this issue: [release-branch.go1.10] cmd/go: accept more safe CFLAGS/LDFLAGS

@gopherbot
Copy link

Change https://golang.org/cl/115436 mentions this issue: [release-branch.go1.9] cmd/go: accept more safe CFLAGS/LDFLAGS

gopherbot pushed a commit that referenced this issue May 31, 2018
Fixes #23749
Fixes #24703
Fixes #24858

Change-Id: Ib32d8efee294004c70fdd602087df2da0867f099
Reviewed-on: https://go-review.googlesource.com/115415
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
(cherry picked from commit 886d5601a63bef0271e705cfa6b6ac6f5134ee60)
Reviewed-on: https://go-review.googlesource.com/115435
Reviewed-by: Andrew Bonventre <andybons@golang.org>
gopherbot pushed a commit that referenced this issue May 31, 2018
Fixes #23749
Fixes #24703
Fixes #24858

Change-Id: Ib32d8efee294004c70fdd602087df2da0867f099
Reviewed-on: https://go-review.googlesource.com/115415
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
(cherry picked from commit cc6e568)
Reviewed-on: https://go-review.googlesource.com/115436
Reviewed-by: Andrew Bonventre <andybons@golang.org>
@tssajo
Copy link

tssajo commented Sep 4, 2018

Hey Guys,
Why is this issue closed when we still cannot build bimg with the latest version of Go as of 9/4/2018 ?
Please see issue: h2non/bimg#230
We cannot build anything that imports bimg since Go 1.10 and the problem still persist in Go 1.11
The error message we get is this:

# go build
go build gopkg.in/h2non/bimg.v1: invalid flag in pkg-config --libs: -Wl,--export-dynamic

Any advise?

EDIT:
I created a new issue: #27496

@alexflint
Copy link

I believe this whitelist is responsible for the following: alexflint/gallium#63

@AlexRouSg
Copy link
Contributor

@alexflint This issue is closed, please create a new one

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