Skip to content

Commit f7c2a71

Browse files
cmd/go: add options to security whitelist
Also permit passing flags to pkg-config, as we used to. Also change the error message to refer to https://golang.org/s/invalidflag. Fixes #23749 Change-Id: I3fbeb4c346610e6fd55e8720e720b0a40e352ab5 Reviewed-on: https://go-review.googlesource.com/93836 Run-TryBot: Ian Lance Taylor <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]>
1 parent 229a8ce commit f7c2a71

File tree

3 files changed

+63
-9
lines changed

3 files changed

+63
-9
lines changed

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -935,15 +935,20 @@ func splitPkgConfigOutput(out []byte) []string {
935935
// Calls pkg-config if needed and returns the cflags/ldflags needed to build the package.
936936
func (b *Builder) getPkgConfigFlags(p *load.Package) (cflags, ldflags []string, err error) {
937937
if pkgs := p.CgoPkgConfig; len(pkgs) > 0 {
938+
var pcflags []string
939+
for len(pkgs) > 0 && strings.HasPrefix(pkgs[0], "--") {
940+
pcflags = append(pcflags, pkgs[0])
941+
pkgs = pkgs[1:]
942+
}
938943
for _, pkg := range pkgs {
939944
if !load.SafeArg(pkg) {
940945
return nil, nil, fmt.Errorf("invalid pkg-config package name: %s", pkg)
941946
}
942947
}
943948
var out []byte
944-
out, err = b.runOut(p.Dir, p.ImportPath, nil, b.PkgconfigCmd(), "--cflags", "--", pkgs)
949+
out, err = b.runOut(p.Dir, p.ImportPath, nil, b.PkgconfigCmd(), "--cflags", pcflags, "--", pkgs)
945950
if err != nil {
946-
b.showOutput(nil, p.Dir, b.PkgconfigCmd()+" --cflags "+strings.Join(pkgs, " "), string(out))
951+
b.showOutput(nil, p.Dir, b.PkgconfigCmd()+" --cflags "+strings.Join(pcflags, " ")+strings.Join(pkgs, " "), string(out))
947952
b.Print(err.Error() + "\n")
948953
return nil, nil, errPrintedOutput
949954
}
@@ -953,15 +958,15 @@ func (b *Builder) getPkgConfigFlags(p *load.Package) (cflags, ldflags []string,
953958
return nil, nil, err
954959
}
955960
}
956-
out, err = b.runOut(p.Dir, p.ImportPath, nil, b.PkgconfigCmd(), "--libs", "--", pkgs)
961+
out, err = b.runOut(p.Dir, p.ImportPath, nil, b.PkgconfigCmd(), "--libs", pcflags, "--", pkgs)
957962
if err != nil {
958-
b.showOutput(nil, p.Dir, b.PkgconfigCmd()+" --libs "+strings.Join(pkgs, " "), string(out))
963+
b.showOutput(nil, p.Dir, b.PkgconfigCmd()+" --libs "+strings.Join(pcflags, " ")+strings.Join(pkgs, " "), string(out))
959964
b.Print(err.Error() + "\n")
960965
return nil, nil, errPrintedOutput
961966
}
962967
if len(out) > 0 {
963968
ldflags = strings.Fields(string(out))
964-
if err := checkLinkerFlags("CFLAGS", "pkg-config --cflags", ldflags); err != nil {
969+
if err := checkLinkerFlags("LDFLAGS", "pkg-config --libs", ldflags); err != nil {
965970
return nil, nil, err
966971
}
967972
}

src/cmd/go/internal/work/security.go

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import (
3434
"fmt"
3535
"os"
3636
"regexp"
37+
"strings"
3738
)
3839

3940
var re = regexp.MustCompile
@@ -45,26 +46,42 @@ var validCompilerFlags = []*regexp.Regexp{
4546
re(`-O([^@\-].*)`),
4647
re(`-W`),
4748
re(`-W([^@,]+)`), // -Wall but not -Wa,-foo.
49+
re(`-f(no-)?blocks`),
50+
re(`-f(no-)?common`),
51+
re(`-f(no-)?constant-cfstrings`),
52+
re(`-f(no-)?exceptions`),
53+
re(`-finput-charset=([^@\-].*)`),
54+
re(`-f(no-)?lto`),
55+
re(`-f(no-)?modules`),
4856
re(`-f(no-)?objc-arc`),
4957
re(`-f(no-)?omit-frame-pointer`),
58+
re(`-f(no-)?openmp(-simd)?`),
59+
re(`-f(no-)?permissive`),
5060
re(`-f(no-)?(pic|PIC|pie|PIE)`),
61+
re(`-f(no-)?rtti`),
5162
re(`-f(no-)?split-stack`),
5263
re(`-f(no-)?stack-(.+)`),
5364
re(`-f(no-)?strict-aliasing`),
5465
re(`-fsanitize=(.+)`),
5566
re(`-g([^@\-].*)?`),
5667
re(`-m(arch|cpu|fpu|tune)=([^@\-].*)`),
68+
re(`-m(no-)?avx[0-9a-z.]*`),
69+
re(`-m(no-)?ms-bitfields`),
5770
re(`-m(no-)?stack-(.+)`),
5871
re(`-mmacosx-(.+)`),
5972
re(`-mnop-fun-dllimport`),
73+
re(`-m(no-)?sse[0-9.]*`),
74+
re(`-pedantic(-errors)?`),
75+
re(`-pipe`),
6076
re(`-pthread`),
61-
re(`-std=([^@\-].*)`),
77+
re(`-?-std=([^@\-].*)`),
6278
re(`-x([^@\-].*)`),
6379
}
6480

6581
var validCompilerFlagsWithNextArg = []string{
6682
"-D",
6783
"-I",
84+
"-isystem",
6885
"-framework",
6986
"-x",
7087
}
@@ -79,23 +96,37 @@ var validLinkerFlags = []*regexp.Regexp{
7996
re(`-m(arch|cpu|fpu|tune)=([^@\-].*)`),
8097
re(`-(pic|PIC|pie|PIE)`),
8198
re(`-pthread`),
99+
re(`-?-static([-a-z0-9+]*)`),
82100

83101
// Note that any wildcards in -Wl need to exclude comma,
84102
// since -Wl splits its argument at commas and passes
85103
// them all to the linker uninterpreted. Allowing comma
86104
// in a wildcard would allow tunnelling arbitrary additional
87105
// linker arguments through one of these.
106+
re(`-Wl,--(no-)?as-needed`),
107+
re(`-Wl,-Bdynamic`),
108+
re(`-Wl,-Bstatic`),
109+
re(`-Wl,--disable-new-dtags`),
110+
re(`-Wl,--enable-new-dtags`),
111+
re(`-Wl,--end-group`),
112+
re(`-Wl,-framework,[^,@\-][^,]+`),
113+
re(`-Wl,-headerpad_max_install_names`),
114+
re(`-Wl,--no-undefined`),
88115
re(`-Wl,-rpath,([^,@\-][^,]+)`),
116+
re(`-Wl,-search_paths_first`),
117+
re(`-Wl,--start-group`),
118+
re(`-Wl,-?-unresolved-symbols=[^,]+`),
89119
re(`-Wl,--(no-)?warn-([^,]+)`),
90120

91-
re(`[a-zA-Z0-9_].*\.(o|obj|dll|dylib|so)`), // direct linker inputs: x.o or libfoo.so (but not -foo.o or @foo.o)
121+
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)
92122
}
93123

94124
var validLinkerFlagsWithNextArg = []string{
95125
"-F",
96126
"-l",
97127
"-L",
98128
"-framework",
129+
"-Wl,-framework",
99130
}
100131

101132
func checkCompilerFlags(name, source string, list []string) error {
@@ -147,10 +178,21 @@ Args:
147178
i++
148179
continue Args
149180
}
181+
182+
// Permit -Wl,-framework -Wl,name.
183+
if i+1 < len(list) &&
184+
strings.HasPrefix(arg, "-Wl,") &&
185+
strings.HasPrefix(list[i+1], "-Wl,") &&
186+
load.SafeArg(list[i+1][4:]) &&
187+
!strings.Contains(list[i+1][4:], ",") {
188+
i++
189+
continue Args
190+
}
191+
150192
if i+1 < len(list) {
151-
return fmt.Errorf("invalid flag in %s: %s %s", source, arg, list[i+1])
193+
return fmt.Errorf("invalid flag in %s: %s %s (see https://golang.org/s/invalidflag)", source, arg, list[i+1])
152194
}
153-
return fmt.Errorf("invalid flag in %s: %s without argument", source, arg)
195+
return fmt.Errorf("invalid flag in %s: %s without argument (see https://golang.org/s/invalidflag)", source, arg)
154196
}
155197
}
156198
Bad:

src/cmd/go/internal/work/security_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,9 @@ var goodLinkerFlags = [][]string{
132132
{"-l", "世界"},
133133
{"-L", "framework"},
134134
{"-framework", "Chocolate"},
135+
{"-Wl,-framework", "-Wl,Chocolate"},
136+
{"-Wl,-framework,Chocolate"},
137+
{"-Wl,-unresolved-symbols=ignore-all"},
135138
}
136139

137140
var badLinkerFlags = [][]string{
@@ -185,6 +188,10 @@ var badLinkerFlags = [][]string{
185188
{"-l", "-foo"},
186189
{"-framework", "-Caffeine"},
187190
{"-framework", "@Home"},
191+
{"-Wl,-framework,-Caffeine"},
192+
{"-Wl,-framework", "-Wl,@Home"},
193+
{"-Wl,-framework", "@Home"},
194+
{"-Wl,-framework,Chocolate,@Home"},
188195
{"-x", "--c"},
189196
{"-x", "@obj"},
190197
{"-Wl,-rpath,@foo"},

0 commit comments

Comments
 (0)