...
1
2
3
4
5
6
7 package sanitizers_test
8
9 import (
10 "internal/testenv"
11 "strings"
12 "testing"
13 )
14
15 func TestLibFuzzer(t *testing.T) {
16
17 if testing.Short() {
18 t.Skip("libfuzzer tests can take upwards of minutes to run; skipping in short mode")
19 }
20 testenv.MustHaveGoBuild(t)
21 testenv.MustHaveCGO(t)
22
23 goos, err := goEnv("GOOS")
24 if err != nil {
25 t.Fatal(err)
26 }
27 goarch, err := goEnv("GOARCH")
28 if err != nil {
29 t.Fatal(err)
30 }
31 if !libFuzzerSupported(goos, goarch) {
32 t.Skipf("skipping on %s/%s; libfuzzer option is not supported.", goos, goarch)
33 }
34 config := configure("fuzzer")
35 config.skipIfCSanitizerBroken(t)
36
37 cases := []struct {
38 goSrc string
39 cSrc string
40 expectedError string
41 }{
42 {goSrc: "libfuzzer1.go", expectedError: "panic: found it"},
43 {goSrc: "libfuzzer2.go", cSrc: "libfuzzer2.c", expectedError: "panic: found it"},
44 }
45 for _, tc := range cases {
46 tc := tc
47 name := strings.TrimSuffix(tc.goSrc, ".go")
48 t.Run(name, func(t *testing.T) {
49 t.Parallel()
50
51 dir := newTempDir(t)
52 defer dir.RemoveAll(t)
53
54
55 outPath := dir.Join(name)
56 archivePath := dir.Join(name + ".a")
57 mustRun(t, config.goCmd("build", "-buildmode=c-archive", "-o", archivePath, srcPath(tc.goSrc)))
58
59
60 cmd, err := cc(config.cFlags...)
61 if err != nil {
62 t.Fatalf("error running cc: %v", err)
63 }
64 cmd.Args = append(cmd.Args, config.ldFlags...)
65 cmd.Args = append(cmd.Args, "-o", outPath, "-I", dir.Base())
66 if tc.cSrc != "" {
67 cmd.Args = append(cmd.Args, srcPath(tc.cSrc))
68 }
69 cmd.Args = append(cmd.Args, archivePath)
70 mustRun(t, cmd)
71
72 cmd = hangProneCmd(outPath)
73 cmd.Dir = dir.Base()
74 outb, err := cmd.CombinedOutput()
75 out := string(outb)
76 if err == nil {
77 t.Fatalf("fuzzing succeeded unexpectedly; output:\n%s", out)
78 }
79 if !strings.Contains(out, tc.expectedError) {
80 t.Errorf("exited without expected error %q; got\n%s", tc.expectedError, out)
81 }
82 })
83 }
84 }
85
86
87
88 func libFuzzerSupported(goos, goarch string) bool {
89 switch goarch {
90 case "amd64", "arm64":
91
92 switch goos {
93 case "darwin", "freebsd", "linux", "windows":
94 return true
95 default:
96 return false
97 }
98 default:
99 return false
100 }
101 }
102
View as plain text