github.com/go-asm/go@v1.21.1-0.20240213172139-40c5ead50c48/cmd/go/work/security_test.go (about) 1 // Copyright 2018 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package work 6 7 import ( 8 "os" 9 "strings" 10 "testing" 11 ) 12 13 var goodCompilerFlags = [][]string{ 14 {"-DFOO"}, 15 {"-Dfoo=bar"}, 16 {"-Ufoo"}, 17 {"-Ufoo1"}, 18 {"-F/Qt"}, 19 {"-F", "/Qt"}, 20 {"-I/"}, 21 {"-I/etc/passwd"}, 22 {"-I."}, 23 {"-O"}, 24 {"-O2"}, 25 {"-Osmall"}, 26 {"-W"}, 27 {"-Wall"}, 28 {"-Wp,-Dfoo=bar"}, 29 {"-Wp,-Ufoo"}, 30 {"-Wp,-Dfoo1"}, 31 {"-Wp,-Ufoo1"}, 32 {"-flto"}, 33 {"-fobjc-arc"}, 34 {"-fno-objc-arc"}, 35 {"-fomit-frame-pointer"}, 36 {"-fno-omit-frame-pointer"}, 37 {"-fpic"}, 38 {"-fno-pic"}, 39 {"-fPIC"}, 40 {"-fno-PIC"}, 41 {"-fpie"}, 42 {"-fno-pie"}, 43 {"-fPIE"}, 44 {"-fno-PIE"}, 45 {"-fsplit-stack"}, 46 {"-fno-split-stack"}, 47 {"-fstack-xxx"}, 48 {"-fno-stack-xxx"}, 49 {"-fsanitize=hands"}, 50 {"-g"}, 51 {"-ggdb"}, 52 {"-march=souza"}, 53 {"-mcpu=123"}, 54 {"-mfpu=123"}, 55 {"-mtune=happybirthday"}, 56 {"-mstack-overflow"}, 57 {"-mno-stack-overflow"}, 58 {"-mmacosx-version"}, 59 {"-mnop-fun-dllimport"}, 60 {"-pthread"}, 61 {"-std=c99"}, 62 {"-xc"}, 63 {"-D", "FOO"}, 64 {"-D", "foo=bar"}, 65 {"-I", "."}, 66 {"-I", "/etc/passwd"}, 67 {"-I", "世界"}, 68 {"-I", "=/usr/include/libxml2"}, 69 {"-I", "dir"}, 70 {"-I", "$SYSROOT/dir"}, 71 {"-isystem", "/usr/include/mozjs-68"}, 72 {"-include", "/usr/include/mozjs-68/RequiredDefines.h"}, 73 {"-framework", "Chocolate"}, 74 {"-x", "c"}, 75 {"-v"}, 76 } 77 78 var badCompilerFlags = [][]string{ 79 {"-D@X"}, 80 {"-D-X"}, 81 {"-Ufoo=bar"}, 82 {"-F@dir"}, 83 {"-F-dir"}, 84 {"-I@dir"}, 85 {"-I-dir"}, 86 {"-O@1"}, 87 {"-Wa,-foo"}, 88 {"-W@foo"}, 89 {"-Wp,-DX,-D@X"}, 90 {"-Wp,-UX,-U@X"}, 91 {"-g@gdb"}, 92 {"-g-gdb"}, 93 {"-march=@dawn"}, 94 {"-march=-dawn"}, 95 {"-std=@c99"}, 96 {"-std=-c99"}, 97 {"-x@c"}, 98 {"-x-c"}, 99 {"-D", "@foo"}, 100 {"-D", "-foo"}, 101 {"-I", "@foo"}, 102 {"-I", "-foo"}, 103 {"-I", "=@obj"}, 104 {"-include", "@foo"}, 105 {"-framework", "-Caffeine"}, 106 {"-framework", "@Home"}, 107 {"-x", "--c"}, 108 {"-x", "@obj"}, 109 } 110 111 func TestCheckCompilerFlags(t *testing.T) { 112 for _, f := range goodCompilerFlags { 113 if err := checkCompilerFlags("test", "test", f); err != nil { 114 t.Errorf("unexpected error for %q: %v", f, err) 115 } 116 } 117 for _, f := range badCompilerFlags { 118 if err := checkCompilerFlags("test", "test", f); err == nil { 119 t.Errorf("missing error for %q", f) 120 } 121 } 122 } 123 124 var goodLinkerFlags = [][]string{ 125 {"-Fbar"}, 126 {"-lbar"}, 127 {"-Lbar"}, 128 {"-fpic"}, 129 {"-fno-pic"}, 130 {"-fPIC"}, 131 {"-fno-PIC"}, 132 {"-fpie"}, 133 {"-fno-pie"}, 134 {"-fPIE"}, 135 {"-fno-PIE"}, 136 {"-fsanitize=hands"}, 137 {"-g"}, 138 {"-ggdb"}, 139 {"-march=souza"}, 140 {"-mcpu=123"}, 141 {"-mfpu=123"}, 142 {"-mtune=happybirthday"}, 143 {"-pic"}, 144 {"-pthread"}, 145 {"-Wl,--hash-style=both"}, 146 {"-Wl,-rpath,foo"}, 147 {"-Wl,-rpath,$ORIGIN/foo"}, 148 {"-Wl,-R", "/foo"}, 149 {"-Wl,-R", "foo"}, 150 {"-Wl,-R,foo"}, 151 {"-Wl,--just-symbols=foo"}, 152 {"-Wl,--just-symbols,foo"}, 153 {"-Wl,--warn-error"}, 154 {"-Wl,--no-warn-error"}, 155 {"foo.so"}, 156 {"_世界.dll"}, 157 {"./x.o"}, 158 {"libcgosotest.dylib"}, 159 {"-F", "framework"}, 160 {"-l", "."}, 161 {"-l", "/etc/passwd"}, 162 {"-l", "世界"}, 163 {"-L", "framework"}, 164 {"-framework", "Chocolate"}, 165 {"-v"}, 166 {"-Wl,-sectcreate,__TEXT,__info_plist,${SRCDIR}/Info.plist"}, 167 {"-Wl,-framework", "-Wl,Chocolate"}, 168 {"-Wl,-framework,Chocolate"}, 169 {"-Wl,-unresolved-symbols=ignore-all"}, 170 {"libcgotbdtest.tbd"}, 171 {"./libcgotbdtest.tbd"}, 172 } 173 174 var badLinkerFlags = [][]string{ 175 {"-DFOO"}, 176 {"-Dfoo=bar"}, 177 {"-W"}, 178 {"-Wall"}, 179 {"-fobjc-arc"}, 180 {"-fno-objc-arc"}, 181 {"-fomit-frame-pointer"}, 182 {"-fno-omit-frame-pointer"}, 183 {"-fsplit-stack"}, 184 {"-fno-split-stack"}, 185 {"-fstack-xxx"}, 186 {"-fno-stack-xxx"}, 187 {"-mstack-overflow"}, 188 {"-mno-stack-overflow"}, 189 {"-mnop-fun-dllimport"}, 190 {"-std=c99"}, 191 {"-xc"}, 192 {"-D", "FOO"}, 193 {"-D", "foo=bar"}, 194 {"-I", "FOO"}, 195 {"-L", "@foo"}, 196 {"-L", "-foo"}, 197 {"-x", "c"}, 198 {"-D@X"}, 199 {"-D-X"}, 200 {"-I@dir"}, 201 {"-I-dir"}, 202 {"-O@1"}, 203 {"-Wa,-foo"}, 204 {"-W@foo"}, 205 {"-g@gdb"}, 206 {"-g-gdb"}, 207 {"-march=@dawn"}, 208 {"-march=-dawn"}, 209 {"-std=@c99"}, 210 {"-std=-c99"}, 211 {"-x@c"}, 212 {"-x-c"}, 213 {"-D", "@foo"}, 214 {"-D", "-foo"}, 215 {"-I", "@foo"}, 216 {"-I", "-foo"}, 217 {"-l", "@foo"}, 218 {"-l", "-foo"}, 219 {"-framework", "-Caffeine"}, 220 {"-framework", "@Home"}, 221 {"-Wl,-framework,-Caffeine"}, 222 {"-Wl,-framework", "-Wl,@Home"}, 223 {"-Wl,-framework", "@Home"}, 224 {"-Wl,-framework,Chocolate,@Home"}, 225 {"-Wl,--hash-style=foo"}, 226 {"-x", "--c"}, 227 {"-x", "@obj"}, 228 {"-Wl,-rpath,@foo"}, 229 {"-Wl,-R,foo,bar"}, 230 {"-Wl,-R,@foo"}, 231 {"-Wl,--just-symbols,@foo"}, 232 {"../x.o"}, 233 {"-Wl,-R,"}, 234 {"-Wl,-O"}, 235 {"-Wl,-e="}, 236 {"-Wl,-e,"}, 237 {"-Wl,-R,-flag"}, 238 } 239 240 func TestCheckLinkerFlags(t *testing.T) { 241 for _, f := range goodLinkerFlags { 242 if err := checkLinkerFlags("test", "test", f); err != nil { 243 t.Errorf("unexpected error for %q: %v", f, err) 244 } 245 } 246 for _, f := range badLinkerFlags { 247 if err := checkLinkerFlags("test", "test", f); err == nil { 248 t.Errorf("missing error for %q", f) 249 } 250 } 251 } 252 253 func TestCheckFlagAllowDisallow(t *testing.T) { 254 if err := checkCompilerFlags("TEST", "test", []string{"-disallow"}); err == nil { 255 t.Fatalf("missing error for -disallow") 256 } 257 os.Setenv("CGO_TEST_ALLOW", "-disallo") 258 if err := checkCompilerFlags("TEST", "test", []string{"-disallow"}); err == nil { 259 t.Fatalf("missing error for -disallow with CGO_TEST_ALLOW=-disallo") 260 } 261 os.Setenv("CGO_TEST_ALLOW", "-disallow") 262 if err := checkCompilerFlags("TEST", "test", []string{"-disallow"}); err != nil { 263 t.Fatalf("unexpected error for -disallow with CGO_TEST_ALLOW=-disallow: %v", err) 264 } 265 os.Unsetenv("CGO_TEST_ALLOW") 266 267 if err := checkCompilerFlags("TEST", "test", []string{"-Wall"}); err != nil { 268 t.Fatalf("unexpected error for -Wall: %v", err) 269 } 270 os.Setenv("CGO_TEST_DISALLOW", "-Wall") 271 if err := checkCompilerFlags("TEST", "test", []string{"-Wall"}); err == nil { 272 t.Fatalf("missing error for -Wall with CGO_TEST_DISALLOW=-Wall") 273 } 274 os.Setenv("CGO_TEST_ALLOW", "-Wall") // disallow wins 275 if err := checkCompilerFlags("TEST", "test", []string{"-Wall"}); err == nil { 276 t.Fatalf("missing error for -Wall with CGO_TEST_DISALLOW=-Wall and CGO_TEST_ALLOW=-Wall") 277 } 278 279 os.Setenv("CGO_TEST_ALLOW", "-fplugin.*") 280 os.Setenv("CGO_TEST_DISALLOW", "-fplugin=lint.so") 281 if err := checkCompilerFlags("TEST", "test", []string{"-fplugin=faster.so"}); err != nil { 282 t.Fatalf("unexpected error for -fplugin=faster.so: %v", err) 283 } 284 if err := checkCompilerFlags("TEST", "test", []string{"-fplugin=lint.so"}); err == nil { 285 t.Fatalf("missing error for -fplugin=lint.so: %v", err) 286 } 287 } 288 289 func TestCheckCompilerFlagsForInternalLink(t *testing.T) { 290 // Any "bad" compiler flag should trigger external linking. 291 for _, f := range badCompilerFlags { 292 if err := checkCompilerFlagsForInternalLink("test", "test", f); err == nil { 293 t.Errorf("missing error for %q", f) 294 } 295 } 296 297 // All "good" compiler flags should not trigger external linking, 298 // except for anything that begins with "-flto". 299 for _, f := range goodCompilerFlags { 300 foundLTO := false 301 for _, s := range f { 302 if strings.Contains(s, "-flto") { 303 foundLTO = true 304 } 305 } 306 if err := checkCompilerFlagsForInternalLink("test", "test", f); err != nil { 307 // expect error for -flto 308 if !foundLTO { 309 t.Errorf("unexpected error for %q: %v", f, err) 310 } 311 } else { 312 // expect no error for everything else 313 if foundLTO { 314 t.Errorf("missing error for %q: %v", f, err) 315 } 316 } 317 } 318 }