1
2
3
4
5
6
7 package fuzz
8
9 import (
10 "fmt"
11 "os"
12 "os/exec"
13 "syscall"
14 )
15
16 type sharedMemSys struct{}
17
18 func sharedMemMapFile(f *os.File, size int, removeOnClose bool) (*sharedMem, error) {
19 prot := syscall.PROT_READ | syscall.PROT_WRITE
20 flags := syscall.MAP_FILE | syscall.MAP_SHARED
21 region, err := syscall.Mmap(int(f.Fd()), 0, size, prot, flags)
22 if err != nil {
23 return nil, err
24 }
25
26 return &sharedMem{f: f, region: region, removeOnClose: removeOnClose}, nil
27 }
28
29
30
31 func (m *sharedMem) Close() error {
32
33
34
35 var errs []error
36 errs = append(errs,
37 syscall.Munmap(m.region),
38 m.f.Close())
39 if m.removeOnClose {
40 errs = append(errs, os.Remove(m.f.Name()))
41 }
42 for _, err := range errs {
43 if err != nil {
44 return err
45 }
46 }
47 return nil
48 }
49
50
51
52 func setWorkerComm(cmd *exec.Cmd, comm workerComm) {
53 mem := <-comm.memMu
54 memFile := mem.f
55 comm.memMu <- mem
56 cmd.ExtraFiles = []*os.File{comm.fuzzIn, comm.fuzzOut, memFile}
57 }
58
59
60 func getWorkerComm() (comm workerComm, err error) {
61 fuzzIn := os.NewFile(3, "fuzz_in")
62 fuzzOut := os.NewFile(4, "fuzz_out")
63 memFile := os.NewFile(5, "fuzz_mem")
64 fi, err := memFile.Stat()
65 if err != nil {
66 return workerComm{}, err
67 }
68 size := int(fi.Size())
69 if int64(size) != fi.Size() {
70 return workerComm{}, fmt.Errorf("fuzz temp file exceeds maximum size")
71 }
72 removeOnClose := false
73 mem, err := sharedMemMapFile(memFile, size, removeOnClose)
74 if err != nil {
75 return workerComm{}, err
76 }
77 memMu := make(chan *sharedMem, 1)
78 memMu <- mem
79 return workerComm{fuzzIn: fuzzIn, fuzzOut: fuzzOut, memMu: memMu}, nil
80 }
81
82
83
84 func isInterruptError(err error) bool {
85 exitErr, ok := err.(*exec.ExitError)
86 if !ok || exitErr.ExitCode() >= 0 {
87 return false
88 }
89 status := exitErr.Sys().(syscall.WaitStatus)
90 return status.Signal() == syscall.SIGINT
91 }
92
93
94
95
96 func terminationSignal(err error) (os.Signal, bool) {
97 exitErr, ok := err.(*exec.ExitError)
98 if !ok || exitErr.ExitCode() >= 0 {
99 return syscall.Signal(-1), false
100 }
101 status := exitErr.Sys().(syscall.WaitStatus)
102 return status.Signal(), status.Signaled()
103 }
104
105
106
107
108
109
110
111
112
113
114
115
116 func isCrashSignal(signal os.Signal) bool {
117 switch signal {
118 case
119 syscall.SIGILL,
120 syscall.SIGTRAP,
121 syscall.SIGABRT,
122 syscall.SIGBUS,
123 syscall.SIGFPE,
124 syscall.SIGSEGV,
125 syscall.SIGPIPE:
126 return true
127 default:
128 return false
129 }
130 }
131
View as plain text