[release-branch.go1.9] cmd/go: accept more safe CFLAGS/LDFLAGS

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 cc6e568c818053ddc16b80b0406a87d19de7a120)
Reviewed-on: https://go-review.googlesource.com/115436
Reviewed-by: Andrew Bonventre <andybons@golang.org>
diff --git a/src/cmd/go/internal/work/security.go b/src/cmd/go/internal/work/security.go
index 5c67aa9..1b82af9 100644
--- a/src/cmd/go/internal/work/security.go
+++ b/src/cmd/go/internal/work/security.go
@@ -41,43 +41,57 @@
 
 var validCompilerFlags = []*regexp.Regexp{
 	re(`-D([A-Za-z_].*)`),
+	re(`-F([^@\-].*)`),
 	re(`-I([^@\-].*)`),
 	re(`-O`),
 	re(`-O([^@\-].*)`),
 	re(`-W`),
 	re(`-W([^@,]+)`), // -Wall but not -Wa,-foo.
 	re(`-Wa,-mbig-obj`),
+	re(`-Wp,-D([A-Za-z_].*)`),
 	re(`-ansi`),
+	re(`-f(no-)?asynchronous-unwind-tables`),
 	re(`-f(no-)?blocks`),
+	re(`-f(no-)builtin-[a-zA-Z0-9_]*`),
 	re(`-f(no-)?common`),
 	re(`-f(no-)?constant-cfstrings`),
 	re(`-fdiagnostics-show-note-include-stack`),
+	re(`-f(no-)?eliminate-unused-debug-types`),
 	re(`-f(no-)?exceptions`),
+	re(`-f(no-)?fast-math`),
 	re(`-f(no-)?inline-functions`),
 	re(`-finput-charset=([^@\-].*)`),
 	re(`-f(no-)?fat-lto-objects`),
+	re(`-f(no-)?keep-inline-dllexport`),
 	re(`-f(no-)?lto`),
 	re(`-fmacro-backtrace-limit=(.+)`),
 	re(`-fmessage-length=(.+)`),
 	re(`-f(no-)?modules`),
 	re(`-f(no-)?objc-arc`),
+	re(`-f(no-)?objc-nonfragile-abi`),
+	re(`-f(no-)?objc-legacy-dispatch`),
 	re(`-f(no-)?omit-frame-pointer`),
 	re(`-f(no-)?openmp(-simd)?`),
 	re(`-f(no-)?permissive`),
 	re(`-f(no-)?(pic|PIC|pie|PIE)`),
+	re(`-f(no-)?plt`),
 	re(`-f(no-)?rtti`),
 	re(`-f(no-)?split-stack`),
 	re(`-f(no-)?stack-(.+)`),
 	re(`-f(no-)?strict-aliasing`),
 	re(`-f(un)signed-char`),
 	re(`-f(no-)?use-linker-plugin`), // safe if -B is not used; we don't permit -B
+	re(`-f(no-)?visibility-inlines-hidden`),
 	re(`-fsanitize=(.+)`),
 	re(`-ftemplate-depth-(.+)`),
 	re(`-fvisibility=(.+)`),
 	re(`-g([^@\-].*)?`),
 	re(`-m32`),
 	re(`-m64`),
-	re(`-m(arch|cpu|fpu|tune)=([^@\-].*)`),
+	re(`-m(abi|arch|cpu|fpu|tune)=([^@\-].*)`),
+	re(`-marm`),
+	re(`-mfloat-abi=([^@\-].*)`),
+	re(`-mfpmath=[0-9a-z,+]*`),
 	re(`-m(no-)?avx[0-9a-z.]*`),
 	re(`-m(no-)?ms-bitfields`),
 	re(`-m(no-)?stack-(.+)`),
@@ -86,12 +100,16 @@
 	re(`-miphoneos-version-min=(.+)`),
 	re(`-mnop-fun-dllimport`),
 	re(`-m(no-)?sse[0-9.]*`),
+	re(`-mthumb(-interwork)?`),
+	re(`-mthreads`),
 	re(`-mwindows`),
+	re(`--param=ssp-buffer-size=[0-9]*`),
 	re(`-pedantic(-errors)?`),
 	re(`-pipe`),
 	re(`-pthread`),
 	re(`-?-std=([^@\-].*)`),
 	re(`-?-stdlib=([^@\-].*)`),
+	re(`--sysroot=([^@\-].*)`),
 	re(`-w`),
 	re(`-x([^@\-].*)`),
 }
@@ -115,15 +133,20 @@
 	re(`-O`),
 	re(`-O([^@\-].*)`),
 	re(`-f(no-)?(pic|PIC|pie|PIE)`),
+	re(`-f(no-)?openmp(-simd)?`),
 	re(`-fsanitize=([^@\-].*)`),
 	re(`-g([^@\-].*)?`),
-	re(`-m(arch|cpu|fpu|tune)=([^@\-].*)`),
+	re(`-headerpad_max_install_names`),
+	re(`-m(abi|arch|cpu|fpu|tune)=([^@\-].*)`),
+	re(`-mfloat-abi=([^@\-].*)`),
 	re(`-mmacosx-(.+)`),
 	re(`-mios-simulator-version-min=(.+)`),
 	re(`-miphoneos-version-min=(.+)`),
+	re(`-mthreads`),
 	re(`-mwindows`),
 	re(`-(pic|PIC|pie|PIE)`),
 	re(`-pthread`),
+	re(`-rdynamic`),
 	re(`-shared`),
 	re(`-?-static([-a-z0-9+]*)`),
 	re(`-?-stdlib=([^@\-].*)`),
@@ -134,22 +157,27 @@
 	// in a wildcard would allow tunnelling arbitrary additional
 	// linker arguments through one of these.
 	re(`-Wl,--(no-)?allow-multiple-definition`),
+	re(`-Wl,--(no-)?allow-shlib-undefined`),
 	re(`-Wl,--(no-)?as-needed`),
 	re(`-Wl,-Bdynamic`),
 	re(`-Wl,-Bstatic`),
+	re(`-WL,-O([^@,\-][^,]*)?`),
 	re(`-Wl,-d[ny]`),
 	re(`-Wl,--disable-new-dtags`),
+	re(`-Wl,-e[=,][a-zA-Z0-9]*`),
 	re(`-Wl,--enable-new-dtags`),
 	re(`-Wl,--end-group`),
 	re(`-Wl,-framework,[^,@\-][^,]+`),
 	re(`-Wl,-headerpad_max_install_names`),
 	re(`-Wl,--no-undefined`),
-	re(`-Wl,-rpath[=,]([^,@\-][^,]+)`),
+	re(`-Wl,-rpath(-link)?[=,]([^,@\-][^,]+)`),
+	re(`-Wl,-s`),
 	re(`-Wl,-search_paths_first`),
 	re(`-Wl,-sectcreate,([^,@\-][^,]+),([^,@\-][^,]+),([^,@\-][^,]+)`),
 	re(`-Wl,--start-group`),
 	re(`-Wl,-?-static`),
-	re(`-Wl,--subsystem,(native|windows|console|posix|xbox)`),
+	re(`-Wl,-?-subsystem,(native|windows|console|posix|xbox)`),
+	re(`-Wl,-syslibroot[=,]([^,@\-][^,]+)`),
 	re(`-Wl,-undefined[=,]([^,@\-][^,]+)`),
 	re(`-Wl,-?-unresolved-symbols=[^,]+`),
 	re(`-Wl,--(no-)?warn-([^,]+)`),
@@ -157,6 +185,7 @@
 	re(`-Wl,-z,relro`),
 
 	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)
+	re(`\./.*\.(a|o|obj|dll|dylib|so)`),
 }
 
 var validLinkerFlagsWithNextArg = []string{
diff --git a/src/cmd/go/internal/work/security_test.go b/src/cmd/go/internal/work/security_test.go
index bd898c9..c3a61b8 100644
--- a/src/cmd/go/internal/work/security_test.go
+++ b/src/cmd/go/internal/work/security_test.go
@@ -12,6 +12,7 @@
 var goodCompilerFlags = [][]string{
 	{"-DFOO"},
 	{"-Dfoo=bar"},
+	{"-F/Qt"},
 	{"-I/"},
 	{"-I/etc/passwd"},
 	{"-I."},
@@ -62,6 +63,8 @@
 var badCompilerFlags = [][]string{
 	{"-D@X"},
 	{"-D-X"},
+	{"-F@dir"},
+	{"-F-dir"},
 	{"-I@dir"},
 	{"-I-dir"},
 	{"-O@1"},
@@ -125,6 +128,7 @@
 	{"-Wl,--no-warn-error"},
 	{"foo.so"},
 	{"_世界.dll"},
+	{"./x.o"},
 	{"libcgosotest.dylib"},
 	{"-F", "framework"},
 	{"-l", "."},
@@ -191,6 +195,7 @@
 	{"-x", "--c"},
 	{"-x", "@obj"},
 	{"-Wl,-rpath,@foo"},
+	{"../x.o"},
 }
 
 func TestCheckLinkerFlags(t *testing.T) {