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 name := strings.TrimSuffix(tc.goSrc, ".go")
47 t.Run(name, func(t *testing.T) {
48 t.Parallel()
49
50 dir := newTempDir(t)
51 defer dir.RemoveAll(t)
52
53
54 outPath := dir.Join(name)
55 archivePath := dir.Join(name + ".a")
56 mustRun(t, config.goCmd("build", "-buildmode=c-archive", "-o", archivePath, srcPath(tc.goSrc)))
57
58
59 cmd, err := cc(config.cFlags...)
60 if err != nil {
61 t.Fatalf("error running cc: %v", err)
62 }
63 cmd.Args = append(cmd.Args, config.ldFlags...)
64 cmd.Args = append(cmd.Args, "-o", outPath, "-I", dir.Base())
65 if tc.cSrc != "" {
66 cmd.Args = append(cmd.Args, srcPath(tc.cSrc))
67 }
68 cmd.Args = append(cmd.Args, archivePath)
69 mustRun(t, cmd)
70
71 cmd = hangProneCmd(outPath)
72 cmd.Dir = dir.Base()
73 outb, err := cmd.CombinedOutput()
74 out := string(outb)
75 if err == nil {
76 t.Fatalf("fuzzing succeeded unexpectedly; output:\n%s", out)
77 }
78 if !strings.Contains(out, tc.expectedError) {
79 t.Errorf("exited without expected error %q; got\n%s", tc.expectedError, out)
80 }
81 })
82 }
83 }
84
85
86
87 func libFuzzerSupported(goos, goarch string) bool {
88 switch goarch {
89 case "amd64", "arm64":
90
91 switch goos {
92 case "darwin", "freebsd", "linux", "windows":
93 return true
94 default:
95 return false
96 }
97 case "loong64":
98 return true
99 default:
100 return false
101 }
102 }
103
View as plain text