aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2024-05-17 17:20:45 +0200
committerDmitry Vyukov <dvyukov@google.com>2024-05-21 09:46:36 +0000
commit1d3c25e7679384c386e7710ea11e364ce9f9e028 (patch)
treec154a9578f63037babef096e85fe9a34183ee640
parenta38fb99b3fbff0c988e64bf4bf277071e18b18af (diff)
pkg/ipc: remove ProgInfo
Switch to flatrpc.ProgInfo. Note: this disables syz-runtest and syz-verifier.
-rw-r--r--Makefile9
-rw-r--r--pkg/flatrpc/helpers.go42
-rw-r--r--pkg/fuzzer/fuzzer.go17
-rw-r--r--pkg/fuzzer/fuzzer_test.go12
-rw-r--r--pkg/fuzzer/job.go38
-rw-r--r--pkg/fuzzer/job_test.go14
-rw-r--r--pkg/fuzzer/queue/queue.go6
-rw-r--r--pkg/ipc/ipc.go100
-rw-r--r--pkg/ipc/ipc_test.go16
-rw-r--r--pkg/rpctype/rpctype.go159
-rw-r--r--pkg/runtest/run.go63
-rw-r--r--pkg/vminfo/features.go4
-rw-r--r--pkg/vminfo/syscalls.go18
-rw-r--r--pkg/vminfo/vminfo_test.go8
-rw-r--r--syz-fuzzer/fuzzer.go4
-rw-r--r--syz-fuzzer/proc.go48
-rw-r--r--syz-fuzzer/testing.go2
-rw-r--r--syz-manager/rpc.go42
-rw-r--r--syz-runner/runner.go5
-rw-r--r--syz-verifier/execresult.go4
-rw-r--r--syz-verifier/execresult_test.go4
-rw-r--r--syz-verifier/exectask.go4
-rw-r--r--syz-verifier/exectask_test.go4
-rwxr-xr-xsyz-verifier/main.go4
-rw-r--r--syz-verifier/main_test.go3
-rw-r--r--syz-verifier/monitoring_api.go4
-rw-r--r--syz-verifier/rpcserver.go4
-rw-r--r--syz-verifier/rpcserver_test.go4
-rw-r--r--syz-verifier/stats.go4
-rw-r--r--syz-verifier/stats_test.go5
-rw-r--r--syz-verifier/utils_test.go4
-rw-r--r--syz-verifier/verifier.go4
-rw-r--r--syz-verifier/verifier_test.go4
-rw-r--r--tools/syz-execprog/execprog.go37
-rw-r--r--tools/syz-runtest/runtest.go4
35 files changed, 266 insertions, 438 deletions
diff --git a/Makefile b/Makefile
index 258eaf2e2..5a1d3d010 100644
--- a/Makefile
+++ b/Makefile
@@ -156,7 +156,8 @@ manager: descriptions
GOOS=$(HOSTOS) GOARCH=$(HOSTARCH) $(HOSTGO) build $(GOHOSTFLAGS) -o ./bin/syz-manager github.com/google/syzkaller/syz-manager
runtest: descriptions
- GOOS=$(HOSTOS) GOARCH=$(HOSTARCH) $(HOSTGO) build $(GOHOSTFLAGS) -o ./bin/syz-runtest github.com/google/syzkaller/tools/syz-runtest
+ # TODO: fold syz-runtest into syz-manager.
+ # GOOS=$(HOSTOS) GOARCH=$(HOSTARCH) $(HOSTGO) build $(GOHOSTFLAGS) -o ./bin/syz-runtest github.com/google/syzkaller/tools/syz-runtest
fuzzer: descriptions
GOOS=$(TARGETGOOS) GOARCH=$(TARGETGOARCH) $(GO) build $(GOTARGETFLAGS) -o ./bin/$(TARGETOS)_$(TARGETVMARCH)/syz-fuzzer$(EXE) github.com/google/syzkaller/syz-fuzzer
@@ -213,10 +214,12 @@ bisect: descriptions
GOOS=$(HOSTOS) GOARCH=$(HOSTARCH) $(HOSTGO) build $(GOHOSTFLAGS) -o ./bin/syz-bisect github.com/google/syzkaller/tools/syz-bisect
verifier: descriptions
- GOOS=$(HOSTOS) GOARCH=$(HOSTARCH) $(HOSTGO) build $(GOHOSTFLAGS) -o ./bin/syz-verifier github.com/google/syzkaller/syz-verifier
+ # TODO: switch syz-verifier to use syz-fuzzer.
+ # GOOS=$(HOSTOS) GOARCH=$(HOSTARCH) $(HOSTGO) build $(GOHOSTFLAGS) -o ./bin/syz-verifier github.com/google/syzkaller/syz-verifier
runner: descriptions
- GOOS=$(TARGETGOOS) GOARCH=$(TARGETGOARCH) $(GO) build $(GOTARGETFLAGS) -o ./bin/$(TARGETOS)_$(TARGETVMARCH)/syz-runner$(EXE) github.com/google/syzkaller/syz-runner
+ # TODO: switch syz-verifier to use syz-fuzzer.
+ # GOOS=$(TARGETGOOS) GOARCH=$(TARGETGOARCH) $(GO) build $(GOTARGETFLAGS) -o ./bin/$(TARGETOS)_$(TARGETVMARCH)/syz-runner$(EXE) github.com/google/syzkaller/syz-runner
# `extract` extracts const files from various kernel sources, and may only
# re-generate parts of files.
diff --git a/pkg/flatrpc/helpers.go b/pkg/flatrpc/helpers.go
index 92e583400..843b281d3 100644
--- a/pkg/flatrpc/helpers.go
+++ b/pkg/flatrpc/helpers.go
@@ -3,6 +3,11 @@
package flatrpc
+import (
+ "slices"
+ "syscall"
+)
+
const AllFeatures = ^Feature(0)
// Flatbuffers compiler adds T suffix to object API types, which are actual structs representing types.
@@ -26,3 +31,40 @@ type CallInfo = CallInfoRawT
type Comparison = ComparisonRawT
type ProgInfo = ProgInfoRawT
type ExecResult = ExecResultRawT
+
+func (pi *ProgInfo) Clone() *ProgInfo {
+ if pi == nil {
+ return nil
+ }
+ ret := *pi
+ ret.Extra = ret.Extra.clone()
+ ret.Calls = make([]*CallInfo, len(pi.Calls))
+ for i, call := range pi.Calls {
+ ret.Calls[i] = call.clone()
+ }
+ return &ret
+}
+
+func (ci *CallInfo) clone() *CallInfo {
+ if ci == nil {
+ return nil
+ }
+ ret := *ci
+ ret.Signal = slices.Clone(ret.Signal)
+ ret.Cover = slices.Clone(ret.Cover)
+ ret.Comps = slices.Clone(ret.Comps)
+ return &ret
+}
+
+func EmptyProgInfo(calls int) *ProgInfo {
+ info := &ProgInfo{}
+ for i := 0; i < calls; i++ {
+ info.Calls = append(info.Calls, &CallInfo{
+ // Store some unsuccessful errno in the case we won't get any result.
+ // It also won't have CallExecuted flag, but it's handy to make it
+ // look failed based on errno as well.
+ Error: int32(syscall.ENOSYS),
+ })
+ }
+ return info
+}
diff --git a/pkg/fuzzer/fuzzer.go b/pkg/fuzzer/fuzzer.go
index 92b4c8bf1..f079e1dc7 100644
--- a/pkg/fuzzer/fuzzer.go
+++ b/pkg/fuzzer/fuzzer.go
@@ -124,12 +124,12 @@ func (fuzzer *Fuzzer) processResult(req *queue.Request, res *queue.Result, flags
// If we are already triaging this exact prog, this is flaky coverage.
if req.ExecOpts.ExecFlags&flatrpc.ExecFlagCollectSignal > 0 && res.Info != nil && !inTriage {
for call, info := range res.Info.Calls {
- fuzzer.triageProgCall(req.Prog, &info, call, flags)
+ fuzzer.triageProgCall(req.Prog, info, call, flags)
}
- fuzzer.triageProgCall(req.Prog, &res.Info.Extra, -1, flags)
+ fuzzer.triageProgCall(req.Prog, res.Info.Extra, -1, flags)
}
if res.Info != nil {
- fuzzer.statExecTime.Add(int(res.Info.Elapsed.Milliseconds()))
+ fuzzer.statExecTime.Add(int(res.Info.Elapsed / 1e6))
}
}
@@ -148,7 +148,10 @@ type Config struct {
NewInputFilter func(call string) bool
}
-func (fuzzer *Fuzzer) triageProgCall(p *prog.Prog, info *ipc.CallInfo, call int, flags ProgTypes) {
+func (fuzzer *Fuzzer) triageProgCall(p *prog.Prog, info *flatrpc.CallInfo, call int, flags ProgTypes) {
+ if info == nil {
+ return
+ }
prio := signalPrio(p, info, call)
newMaxSignal := fuzzer.Cover.addRawMaxSignal(info.Signal, prio)
if newMaxSignal.Empty() {
@@ -166,18 +169,18 @@ func (fuzzer *Fuzzer) triageProgCall(p *prog.Prog, info *ipc.CallInfo, call int,
fuzzer.startJob(fuzzer.statJobsTriage, &triageJob{
p: p.Clone(),
call: call,
- info: *info,
+ info: info,
newSignal: newMaxSignal,
flags: flags,
queue: queue.Append(),
})
}
-func signalPrio(p *prog.Prog, info *ipc.CallInfo, call int) (prio uint8) {
+func signalPrio(p *prog.Prog, info *flatrpc.CallInfo, call int) (prio uint8) {
if call == -1 {
return 0
}
- if info.Errno == 0 {
+ if info.Error == 0 {
prio |= 1 << 1
}
if !p.Target.CallContainsAny(p.Calls[call]) {
diff --git a/pkg/fuzzer/fuzzer_test.go b/pkg/fuzzer/fuzzer_test.go
index cb58a4e10..07e09e25a 100644
--- a/pkg/fuzzer/fuzzer_test.go
+++ b/pkg/fuzzer/fuzzer_test.go
@@ -186,16 +186,16 @@ var crc32q = crc32.MakeTable(0xD5828281)
func emulateExec(req *queue.Request) (*queue.Result, string, error) {
serializedLines := bytes.Split(req.Prog.Serialize(), []byte("\n"))
- var info ipc.ProgInfo
+ var info flatrpc.ProgInfo
for i, call := range req.Prog.Calls {
- cover := uint32(call.Meta.ID*1024) +
- crc32.Checksum(serializedLines[i], crc32q)%4
- callInfo := ipc.CallInfo{}
+ cover := []uint32{uint32(call.Meta.ID*1024) +
+ crc32.Checksum(serializedLines[i], crc32q)%4}
+ callInfo := &flatrpc.CallInfo{}
if req.ExecOpts.ExecFlags&flatrpc.ExecFlagCollectCover > 0 {
- callInfo.Cover = []uint32{cover}
+ callInfo.Cover = cover
}
if req.ExecOpts.ExecFlags&flatrpc.ExecFlagCollectSignal > 0 {
- callInfo.Signal = []uint32{cover}
+ callInfo.Signal = cover
}
info.Calls = append(info.Calls, callInfo)
}
diff --git a/pkg/fuzzer/job.go b/pkg/fuzzer/job.go
index 4e605f1c2..a5a22b2e8 100644
--- a/pkg/fuzzer/job.go
+++ b/pkg/fuzzer/job.go
@@ -11,7 +11,6 @@ import (
"github.com/google/syzkaller/pkg/cover"
"github.com/google/syzkaller/pkg/flatrpc"
"github.com/google/syzkaller/pkg/fuzzer/queue"
- "github.com/google/syzkaller/pkg/ipc"
"github.com/google/syzkaller/pkg/signal"
"github.com/google/syzkaller/pkg/stats"
"github.com/google/syzkaller/prog"
@@ -83,7 +82,7 @@ func candidateRequest(fuzzer *Fuzzer, input Candidate) (*queue.Request, ProgType
type triageJob struct {
p *prog.Prog
call int
- info ipc.CallInfo
+ info *flatrpc.CallInfo
newSignal signal.Signal
flags ProgTypes
fuzzer *Fuzzer
@@ -172,7 +171,7 @@ func (job *triageJob) deflake(exec func(*queue.Request, ProgTypes) *queue.Result
stop = true
return
}
- if !reexecutionSuccess(result.Info, &job.info, job.call) {
+ if !reexecutionSuccess(result.Info, job.info, job.call) {
// The call was not executed or failed.
continue
}
@@ -213,7 +212,7 @@ func (job *triageJob) minimize(newSignal signal.Signal) (stop bool) {
return false
}
info := result.Info
- if !reexecutionSuccess(info, &job.info, call1) {
+ if !reexecutionSuccess(info, job.info, call1) {
// The call was not executed or failed.
continue
}
@@ -227,25 +226,28 @@ func (job *triageJob) minimize(newSignal signal.Signal) (stop bool) {
return stop
}
-func reexecutionSuccess(info *ipc.ProgInfo, oldInfo *ipc.CallInfo, call int) bool {
+func reexecutionSuccess(info *flatrpc.ProgInfo, oldInfo *flatrpc.CallInfo, call int) bool {
if info == nil || len(info.Calls) == 0 {
return false
}
if call != -1 {
// Don't minimize calls from successful to unsuccessful.
// Successful calls are much more valuable.
- if oldInfo.Errno == 0 && info.Calls[call].Errno != 0 {
+ if oldInfo.Error == 0 && info.Calls[call].Error != 0 {
return false
}
return len(info.Calls[call].Signal) != 0
}
- return len(info.Extra.Signal) != 0
+ return info.Extra != nil && len(info.Extra.Signal) != 0
}
-func getSignalAndCover(p *prog.Prog, info *ipc.ProgInfo, call int) (signal.Signal, []uint32) {
- inf := &info.Extra
+func getSignalAndCover(p *prog.Prog, info *flatrpc.ProgInfo, call int) (signal.Signal, []uint32) {
+ inf := info.Extra
if call != -1 {
- inf = &info.Calls[call]
+ inf = info.Calls[call]
+ }
+ if inf == nil {
+ return nil, nil
}
return signal.FromRaw(inf.Signal, signalPrio(p, inf, call)), inf.Cover
}
@@ -332,7 +334,7 @@ func (job *smashJob) faultInjection(fuzzer *Fuzzer) {
}
info := result.Info
if info != nil && len(info.Calls) > job.call &&
- info.Calls[job.call].Flags&ipc.CallFaultInjected == 0 {
+ info.Calls[job.call].Flags&flatrpc.CallFlagFaultInjected == 0 {
break
}
}
@@ -358,13 +360,17 @@ func (job *hintsJob) run(fuzzer *Fuzzer) {
if result.Stop() || result.Info == nil {
return
}
+ got := make(prog.CompMap)
+ for _, cmp := range result.Info.Calls[job.call].Comps {
+ got.AddComp(cmp.Op1, cmp.Op2)
+ }
+ if len(got) == 0 {
+ return
+ }
if i == 0 {
- comps = result.Info.Calls[job.call].Comps
- if len(comps) == 0 {
- return
- }
+ comps = got
} else {
- comps.InplaceIntersect(result.Info.Calls[job.call].Comps)
+ comps.InplaceIntersect(got)
}
}
diff --git a/pkg/fuzzer/job_test.go b/pkg/fuzzer/job_test.go
index b7718134b..70d083be5 100644
--- a/pkg/fuzzer/job_test.go
+++ b/pkg/fuzzer/job_test.go
@@ -6,8 +6,8 @@ package fuzzer
import (
"testing"
+ "github.com/google/syzkaller/pkg/flatrpc"
"github.com/google/syzkaller/pkg/fuzzer/queue"
- "github.com/google/syzkaller/pkg/ipc"
"github.com/google/syzkaller/pkg/signal"
"github.com/google/syzkaller/prog"
"github.com/google/syzkaller/sys/targets"
@@ -24,7 +24,7 @@ func TestDeflakeFail(t *testing.T) {
testJob := &triageJob{
p: prog,
- info: ipc.CallInfo{},
+ info: &flatrpc.CallInfo{},
newSignal: signal.FromRaw([]uint32{0, 1, 2, 3, 4}, 0),
}
@@ -50,7 +50,7 @@ func TestDeflakeSuccess(t *testing.T) {
testJob := &triageJob{
p: prog,
- info: ipc.CallInfo{},
+ info: &flatrpc.CallInfo{},
newSignal: signal.FromRaw([]uint32{0, 1, 2}, 0),
}
run := 0
@@ -80,12 +80,12 @@ func TestDeflakeSuccess(t *testing.T) {
assert.ElementsMatch(t, []uint32{0, 2}, ret.newStableSignal.ToRaw())
}
-func fakeResult(errno int, signal, cover []uint32) *queue.Result {
+func fakeResult(errno int32, signal, cover []uint32) *queue.Result {
return &queue.Result{
- Info: &ipc.ProgInfo{
- Calls: []ipc.CallInfo{
+ Info: &flatrpc.ProgInfo{
+ Calls: []*flatrpc.CallInfo{
{
- Errno: errno,
+ Error: errno,
Signal: signal,
Cover: cover,
},
diff --git a/pkg/fuzzer/queue/queue.go b/pkg/fuzzer/queue/queue.go
index 36226299a..0e578c6f9 100644
--- a/pkg/fuzzer/queue/queue.go
+++ b/pkg/fuzzer/queue/queue.go
@@ -135,7 +135,7 @@ func (r *Request) initChannel() {
}
type Result struct {
- Info *ipc.ProgInfo
+ Info *flatrpc.ProgInfo
Output []byte
Status Status
Err error // More details in case of ExecFailure.
@@ -143,9 +143,7 @@ type Result struct {
func (r *Result) clone() *Result {
ret := *r
- if ret.Info != nil {
- ret.Info = ret.Info.Clone()
- }
+ ret.Info = ret.Info.Clone()
return &ret
}
diff --git a/pkg/ipc/ipc.go b/pkg/ipc/ipc.go
index 0e12fa2bd..9b4f77d66 100644
--- a/pkg/ipc/ipc.go
+++ b/pkg/ipc/ipc.go
@@ -6,14 +6,12 @@ package ipc
import (
"fmt"
"io"
- "maps"
"os"
"os/exec"
"path/filepath"
"slices"
"strings"
"sync"
- "syscall"
"time"
"unsafe"
@@ -53,60 +51,6 @@ type Config struct {
Timeouts targets.Timeouts
}
-type CallFlags uint32
-
-const (
- CallExecuted CallFlags = 1 << iota // was started at all
- CallFinished // finished executing (rather than blocked forever)
- CallBlocked // finished but blocked during execution
- CallFaultInjected // fault was injected into this call
-)
-
-type CallInfo struct {
- Flags CallFlags
- Signal []uint32 // feedback signal, filled if FlagSignal is set
- Cover []uint32 // per-call coverage, filled if FlagSignal is set and cover == true,
- // if dedup == false, then cov effectively contains a trace, otherwise duplicates are removed
- Comps prog.CompMap // per-call comparison operands
- Errno int // call errno (0 if the call was successful)
-}
-
-func (ci *CallInfo) Clone() CallInfo {
- ret := *ci
- ret.Signal = slices.Clone(ret.Signal)
- ret.Cover = slices.Clone(ret.Cover)
- ret.Comps = maps.Clone(ret.Comps)
- return ret
-}
-
-type ProgInfo struct {
- Calls []CallInfo
- Extra CallInfo // stores Signal and Cover collected from background threads
- Elapsed time.Duration // total execution time of the program
- Freshness int // number of programs executed in the same process before this one
-}
-
-func (pi *ProgInfo) Clone() *ProgInfo {
- ret := *pi
- ret.Extra = ret.Extra.Clone()
- ret.Calls = slices.Clone(ret.Calls)
- for i, call := range ret.Calls {
- ret.Calls[i] = call.Clone()
- }
- return &ret
-}
-
-func EmptyProgInfo(calls int) *ProgInfo {
- info := &ProgInfo{Calls: make([]CallInfo, calls)}
- for i := range info.Calls {
- // Store some unsuccessful errno in the case we won't get any result.
- // It also won't have CallExecuted flag, but it's handy to make it
- // look failed based on errno as well.
- info.Calls[i].Errno = int(syscall.ENOSYS)
- }
- return info
-}
-
type Env struct {
in []byte
out []byte
@@ -312,7 +256,8 @@ func (env *Env) Close() error {
// info: per-call info
// hanged: program hanged and was killed
// err0: failed to start the process or bug in executor itself.
-func (env *Env) ExecProg(opts *ExecOpts, progData []byte) (output []byte, info *ProgInfo, hanged bool, err0 error) {
+func (env *Env) ExecProg(opts *ExecOpts, progData []byte) (
+ output []byte, info *flatrpc.ProgInfo, hanged bool, err0 error) {
ncalls, err := prog.ExecCallCount(progData)
if err != nil {
err0 = err
@@ -345,7 +290,7 @@ func (env *Env) ExecProg(opts *ExecOpts, progData []byte) (output []byte, info *
info, err0 = env.parseOutput(opts, ncalls)
if info != nil {
- info.Elapsed = elapsed
+ info.Elapsed = uint64(elapsed)
info.Freshness = env.cmd.freshness
}
env.cmd.freshness++
@@ -356,7 +301,7 @@ func (env *Env) ExecProg(opts *ExecOpts, progData []byte) (output []byte, info *
return
}
-func (env *Env) Exec(opts *ExecOpts, p *prog.Prog) (output []byte, info *ProgInfo, hanged bool, err0 error) {
+func (env *Env) Exec(opts *ExecOpts, p *prog.Prog) (output []byte, info *flatrpc.ProgInfo, hanged bool, err0 error) {
progData, err := p.SerializeForExec()
if err != nil {
err0 = err
@@ -396,21 +341,21 @@ var (
rateLimiter <-chan time.Time
)
-func (env *Env) parseOutput(opts *ExecOpts, ncalls int) (*ProgInfo, error) {
+func (env *Env) parseOutput(opts *ExecOpts, ncalls int) (*flatrpc.ProgInfo, error) {
out := env.out
ncmd, ok := readUint32(&out)
if !ok {
return nil, fmt.Errorf("failed to read number of calls")
}
- info := EmptyProgInfo(ncalls)
- extraParts := make([]CallInfo, 0)
+ info := flatrpc.EmptyProgInfo(ncalls)
+ extraParts := make([]flatrpc.CallInfo, 0)
for i := uint32(0); i < ncmd; i++ {
if len(out) < int(unsafe.Sizeof(callReply{})) {
return nil, fmt.Errorf("failed to read call %v reply", i)
}
reply := *(*callReply)(unsafe.Pointer(&out[0]))
out = out[unsafe.Sizeof(callReply{}):]
- var inf *CallInfo
+ var inf *flatrpc.CallInfo
if reply.magic != outMagic {
return nil, fmt.Errorf("bad reply magic 0x%x", reply.magic)
}
@@ -418,14 +363,14 @@ func (env *Env) parseOutput(opts *ExecOpts, ncalls int) (*ProgInfo, error) {
if int(reply.index) >= len(info.Calls) {
return nil, fmt.Errorf("bad call %v index %v/%v", i, reply.index, len(info.Calls))
}
- inf = &info.Calls[reply.index]
+ inf = info.Calls[reply.index]
if inf.Flags != 0 || inf.Signal != nil {
return nil, fmt.Errorf("duplicate reply for call %v/%v/%v", i, reply.index, reply.num)
}
- inf.Errno = int(reply.errno)
- inf.Flags = CallFlags(reply.flags)
+ inf.Error = int32(reply.errno)
+ inf.Flags = flatrpc.CallFlag(reply.flags)
} else {
- extraParts = append(extraParts, CallInfo{})
+ extraParts = append(extraParts, flatrpc.CallInfo{})
inf = &extraParts[len(extraParts)-1]
}
if inf.Signal, ok = readUint32Array(&out, reply.signalSize); !ok {
@@ -449,8 +394,8 @@ func (env *Env) parseOutput(opts *ExecOpts, ncalls int) (*ProgInfo, error) {
return info, nil
}
-func convertExtra(extraParts []CallInfo, dedupCover bool) CallInfo {
- var extra CallInfo
+func convertExtra(extraParts []flatrpc.CallInfo, dedupCover bool) *flatrpc.CallInfo {
+ var extra flatrpc.CallInfo
if dedupCover {
extraCover := make(cover.Cover)
for _, part := range extraParts {
@@ -472,14 +417,11 @@ func convertExtra(extraParts []CallInfo, dedupCover bool) CallInfo {
extra.Signal[i] = uint32(s)
i++
}
- return extra
+ return &extra
}
-func readComps(outp *[]byte, compsSize uint32) (prog.CompMap, error) {
- if compsSize == 0 {
- return nil, nil
- }
- compMap := make(prog.CompMap)
+func readComps(outp *[]byte, compsSize uint32) ([]*flatrpc.Comparison, error) {
+ comps := make([]*flatrpc.Comparison, 0, 2*compsSize)
for i := uint32(0); i < compsSize; i++ {
typ, ok := readUint32(outp)
if !ok {
@@ -505,7 +447,7 @@ func readComps(outp *[]byte, compsSize uint32) (prog.CompMap, error) {
if op1 == op2 {
continue // it's useless to store such comparisons
}
- compMap.AddComp(op2, op1)
+ comps = append(comps, &flatrpc.Comparison{Op1: op2, Op2: op1})
if (typ & compConstMask) != 0 {
// If one of the operands was const, then this operand is always
// placed first in the instrumented callbacks. Such an operand
@@ -513,9 +455,9 @@ func readComps(outp *[]byte, compsSize uint32) (prog.CompMap, error) {
// it wouldn't be const), thus we simply ignore it.
continue
}
- compMap.AddComp(op1, op2)
+ comps = append(comps, &flatrpc.Comparison{Op1: op1, Op2: op2})
}
- return compMap, nil
+ return comps, nil
}
func readUint32(outp *[]byte) (uint32, bool) {
@@ -567,7 +509,7 @@ type command struct {
inrp *os.File
outwp *os.File
outmem []byte
- freshness int
+ freshness uint64
}
const (
diff --git a/pkg/ipc/ipc_test.go b/pkg/ipc/ipc_test.go
index 30e97660f..af9557e1b 100644
--- a/pkg/ipc/ipc_test.go
+++ b/pkg/ipc/ipc_test.go
@@ -111,8 +111,8 @@ func TestExecute(t *testing.T) {
if len(info.Calls) != len(p.Calls) {
t.Fatalf("executed less calls (%v) than prog len(%v):\n%s", len(info.Calls), len(p.Calls), output)
}
- if info.Calls[0].Errno != 0 {
- t.Fatalf("simple call failed: %v\n%s", info.Calls[0].Errno, output)
+ if info.Calls[0].Error != 0 {
+ t.Fatalf("simple call failed: %v\n%s", info.Calls[0].Error, output)
}
if len(output) != 0 {
t.Fatalf("output on empty program")
@@ -159,8 +159,8 @@ func TestParallel(t *testing.T) {
err = fmt.Errorf("no calls executed:\n%s", output)
return
}
- if info.Calls[0].Errno != 0 {
- err = fmt.Errorf("simple call failed: %v\n%s", info.Calls[0].Errno, output)
+ if info.Calls[0].Error != 0 {
+ err = fmt.Errorf("simple call failed: %v\n%s", info.Calls[0].Error, output)
return
}
if len(output) != 0 {
@@ -211,8 +211,8 @@ func TestZlib(t *testing.T) {
if err != nil {
t.Fatalf("failed to run executor: %v", err)
}
- if info.Calls[0].Errno != 0 {
- t.Fatalf("data comparison failed: %v\n%s", info.Calls[0].Errno, output)
+ if info.Calls[0].Error != 0 {
+ t.Fatalf("data comparison failed: %v\n%s", info.Calls[0].Error, output)
}
}
}
@@ -258,7 +258,7 @@ func TestExecutorCommonExt(t *testing.T) {
if err != nil {
t.Fatal(err)
}
- if call := info.Calls[0]; (call.Flags&CallFinished) == 0 || call.Errno != 0 {
- t.Fatalf("bad call result: flags=%x errno=%v", call.Flags, call.Errno)
+ if call := info.Calls[0]; call.Flags&flatrpc.CallFlagFinished == 0 || call.Error != 0 {
+ t.Fatalf("bad call result: flags=%x errno=%v", call.Flags, call.Error)
}
}
diff --git a/pkg/rpctype/rpctype.go b/pkg/rpctype/rpctype.go
index 89ff419c1..e314424ea 100644
--- a/pkg/rpctype/rpctype.go
+++ b/pkg/rpctype/rpctype.go
@@ -2,166 +2,9 @@
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
// Package rpctype contains types of message passed via net/rpc connections
-// between various parts of the system.
+// between syz-manager and syz-hub.
package rpctype
-import (
- "math"
- "time"
-
- "github.com/google/syzkaller/pkg/flatrpc"
- "github.com/google/syzkaller/pkg/ipc"
- "github.com/google/syzkaller/pkg/signal"
-)
-
-// ExecutionRequest describes the task of executing a particular program.
-// Corresponds to Fuzzer.Request.
-type ExecutionRequest struct {
- ID int64
- ProgData []byte
- ExecOpts ipc.ExecOpts
- NewSignal bool
- // If set, ProgData contains compiled executable binary
- // that needs to be written to disk and executed.
- IsBinary bool
- // If set, fully reset executor state befor executing the test.
- ResetState bool
- // If set, collect program output and return in ExecutionResult.Output.
- ReturnOutput bool
- // If set, don't fail on program failures, instead return the error in ExecutionResult.Error.
- ReturnError bool
- SignalFilter signal.Signal
- SignalFilterCall int
- // Repeat the program that many times (0 means 1).
- Repeat int
-}
-
-// ExecutionResult is sent after ExecutionRequest is completed.
-type ExecutionResult struct {
- ID int64
- ProcID int
- Try int
- Info ipc.ProgInfo
- Output []byte
- Error string
-}
-
-// ExchangeInfoRequest is periodically sent by syz-fuzzer to syz-manager.
-type ExchangeInfoRequest struct {
- Name string
- NeedProgs int
- StatsDelta map[string]uint64
- Results []ExecutionResult
- Latency time.Duration // latency of the previous ExchangeInfo request
-}
-
-// ExchangeInfoReply is a reply to ExchangeInfoRequest.
-type ExchangeInfoReply struct {
- Requests []ExecutionRequest
- NewMaxSignal []uint32
- DropMaxSignal []uint32
-}
-
-// ExecutingRequest is notification from the fuzzer that it started executing
-// the program ProgID. We want this request to be as small and as fast as possible
-// b/c we want it to reach manager (or at least leave the VM) before it crashes
-// executing this program.
-type ExecutingRequest struct {
- Name string
- ID int64
- ProcID int
- Try int
-}
-
-// TODO: merge ExecutionRequest and ExecTask.
-type ExecTask struct {
- Prog []byte
- ID int64
-}
-
-type ConnectArgs struct {
- Name string
- GitRevision string
- SyzRevision string
- ExecutorArch string
- ExecutorGitRevision string
- ExecutorSyzRevision string
-}
-
-type ConnectRes struct {
- MemoryLeakFrames []string
- DataRaceFrames []string
- // Bitmask of features to try to setup.
- Features flatrpc.Feature
- // Fuzzer reads these files inside of the VM and returns contents in CheckArgs.Files.
- ReadFiles []string
- ReadGlobs []string
-}
-
-type CheckArgs struct {
- Name string
- Error string
- Features []*flatrpc.FeatureInfo
- Globs map[string][]string
- Files []*flatrpc.FileInfo
-}
-
-type CheckRes struct {
- CoverFilterBitmap []byte
-}
-
-type SyscallReason struct {
- ID int
- Reason string
-}
-
-type RunnerConnectArgs struct {
- Pool, VM int
-}
-
-type RunnerConnectRes struct {
- // CheckUnsupportedCalls is set to true if the Runner needs to query the kernel
- // for unsupported system calls and report them back to the server.
- CheckUnsupportedCalls bool
-}
-
-// UpdateUnsupportedArgs contains the data passed from client to server in an
-// UpdateSupported call, namely the system calls not supported by the client's
-// kernel.
-type UpdateUnsupportedArgs struct {
- // Pool is used to identify the checked kernel.
- Pool int
- // UnsupportedCalls contains the ID's of system calls not supported by the
- // client and the reason for this.
- UnsupportedCalls []SyscallReason
-}
-
-// NextExchangeArgs contains the data passed from client to server namely
-// identification information of the VM and program execution results.
-type NextExchangeArgs struct {
- // Pool/VM are used to identify the instance on which the client is running.
- Pool, VM int
- // ExecTaskID is used to uniquely identify the program for which the client is
- // sending results.
- ExecTaskID int64
- // Hanged is set to true if the program for which we are sending results
- // was killed due to hanging.
- Hanged bool
- // Info contains information about the execution of each system call in the
- // program.
- Info ipc.ProgInfo
-}
-
-// NextExchaneRes contains the data passed from server to client namely
-// programs to execute on the VM.
-type NextExchangeRes struct {
- ExecTask
-}
-
-const (
- NoTask int64 = math.MaxInt64
-)
-
type HubConnectArgs struct {
// Client/Key are used for authentication.
Client string
diff --git a/pkg/runtest/run.go b/pkg/runtest/run.go
index 29fa9d0cf..2c6a60d4a 100644
--- a/pkg/runtest/run.go
+++ b/pkg/runtest/run.go
@@ -38,7 +38,7 @@ type runRequest struct {
err error
result *queue.Result
- results *ipc.ProgInfo // the expected results
+ results *flatrpc.ProgInfo // the expected results
name string
broken string
@@ -291,7 +291,7 @@ nextSandbox:
return nil
}
-func parseProg(target *prog.Target, dir, filename string) (*prog.Prog, map[string]bool, *ipc.ProgInfo, error) {
+func parseProg(target *prog.Target, dir, filename string) (*prog.Prog, map[string]bool, *flatrpc.ProgInfo, error) {
data, err := os.ReadFile(filepath.Join(dir, filename))
if err != nil {
return nil, nil, nil, fmt.Errorf("failed to read %v: %w", filename, err)
@@ -306,7 +306,7 @@ func parseProg(target *prog.Target, dir, filename string) (*prog.Prog, map[strin
if err != nil {
return nil, nil, nil, fmt.Errorf("failed to deserialize %v: %w", filename, err)
}
- errnos := map[string]int{
+ errnos := map[string]int32{
"": 0,
"EPERM": 1,
"ENOENT": 2,
@@ -332,24 +332,27 @@ func parseProg(target *prog.Target, dir, filename string) (*prog.Prog, map[strin
"ZX_ERR_ALREADY_EXISTS": 26,
"ZX_ERR_ACCESS_DENIED": 30,
}
- info := &ipc.ProgInfo{Calls: make([]ipc.CallInfo, len(p.Calls))}
- for i, call := range p.Calls {
- info.Calls[i].Flags |= ipc.CallExecuted | ipc.CallFinished
+ info := &flatrpc.ProgInfo{}
+ for _, call := range p.Calls {
+ ci := &flatrpc.CallInfo{
+ Flags: flatrpc.CallFlagExecuted | flatrpc.CallFlagFinished,
+ }
switch call.Comment {
case "blocked":
- info.Calls[i].Flags |= ipc.CallBlocked
+ ci.Flags |= flatrpc.CallFlagBlocked
case "unfinished":
- info.Calls[i].Flags &^= ipc.CallFinished
+ ci.Flags &^= flatrpc.CallFlagFinished
case "unexecuted":
- info.Calls[i].Flags &^= ipc.CallExecuted | ipc.CallFinished
+ ci.Flags &^= flatrpc.CallFlagExecuted | flatrpc.CallFlagFinished
default:
res, ok := errnos[call.Comment]
if !ok {
return nil, nil, nil, fmt.Errorf("%v: unknown call comment %q",
filename, call.Comment)
}
- info.Calls[i].Errno = res
+ ci.Error = res
}
+ info.Calls = append(info.Calls, ci)
}
return p, requires, info, nil
}
@@ -386,7 +389,7 @@ func checkArch(requires map[string]bool, arch string) bool {
}
func (ctx *Context) produceTest(progs chan *runRequest, req *runRequest, name string,
- properties, requires map[string]bool, results *ipc.ProgInfo) {
+ properties, requires map[string]bool, results *flatrpc.ProgInfo) {
req.name = name
req.results = results
if !match(properties, requires) {
@@ -505,7 +508,7 @@ func checkResult(req *runRequest) error {
if req.result.Status != queue.Success {
return fmt.Errorf("non-successful result status (%v)", req.result.Status)
}
- var infos []ipc.ProgInfo
+ var infos []*flatrpc.ProgInfo
isC := req.BinaryFile != ""
if isC {
var err error
@@ -516,7 +519,7 @@ func checkResult(req *runRequest) error {
raw := req.result.Info
for len(raw.Calls) != 0 {
ncalls := min(len(raw.Calls), len(req.Prog.Calls))
- infos = append(infos, ipc.ProgInfo{
+ infos = append(infos, &flatrpc.ProgInfo{
Extra: raw.Extra,
Calls: raw.Calls[:ncalls],
})
@@ -538,15 +541,11 @@ func checkResult(req *runRequest) error {
return nil
}
-func checkCallResult(req *runRequest, isC bool, run, call int, info ipc.ProgInfo, calls map[string]bool) error {
+func checkCallResult(req *runRequest, isC bool, run, call int, info *flatrpc.ProgInfo, calls map[string]bool) error {
inf := info.Calls[call]
want := req.results.Calls[call]
- for flag, what := range map[ipc.CallFlags]string{
- ipc.CallExecuted: "executed",
- ipc.CallBlocked: "blocked",
- ipc.CallFinished: "finished",
- } {
- if flag != ipc.CallFinished {
+ for flag, what := range flatrpc.EnumNamesCallFlag {
+ if flag != flatrpc.CallFlagFinished {
if isC {
// C code does not detect blocked/non-finished calls.
continue
@@ -557,7 +556,7 @@ func checkCallResult(req *runRequest, isC bool, run, call int, info ipc.ProgInfo
continue
}
}
- if runtime.GOOS == targets.FreeBSD && flag == ipc.CallBlocked {
+ if runtime.GOOS == targets.FreeBSD && flag == flatrpc.CallFlagBlocked {
// Blocking detection is flaky on freebsd.
// TODO(dvyukov): try to increase the timeout in executor to make it non-flaky.
continue
@@ -570,11 +569,11 @@ func checkCallResult(req *runRequest, isC bool, run, call int, info ipc.ProgInfo
return fmt.Errorf("run %v: call %v is%v %v", run, call, not, what)
}
}
- if inf.Flags&ipc.CallFinished != 0 && inf.Errno != want.Errno {
+ if inf.Flags&flatrpc.CallFlagFinished != 0 && inf.Error != want.Error {
return fmt.Errorf("run %v: wrong call %v result %v, want %v",
- run, call, inf.Errno, want.Errno)
+ run, call, inf.Error, want.Error)
}
- if isC || inf.Flags&ipc.CallExecuted == 0 {
+ if isC || inf.Flags&flatrpc.CallFlagExecuted == 0 {
return nil
}
if req.ExecOpts.EnvFlags&flatrpc.ExecEnvSignal != 0 {
@@ -600,13 +599,17 @@ func checkCallResult(req *runRequest, isC bool, run, call int, info ipc.ProgInfo
return nil
}
-func parseBinOutput(req *runRequest) ([]ipc.ProgInfo, error) {
- var infos []ipc.ProgInfo
+func parseBinOutput(req *runRequest) ([]*flatrpc.ProgInfo, error) {
+ var infos []*flatrpc.ProgInfo
s := bufio.NewScanner(bytes.NewReader(req.result.Output))
re := regexp.MustCompile("^### call=([0-9]+) errno=([0-9]+)$")
for s.Scan() {
if s.Text() == "### start" {
- infos = append(infos, ipc.ProgInfo{Calls: make([]ipc.CallInfo, len(req.Prog.Calls))})
+ pi := &flatrpc.ProgInfo{}
+ for range req.Prog.Calls {
+ pi.Calls = append(pi.Calls, &flatrpc.CallInfo{})
+ }
+ infos = append(infos, pi)
}
match := re.FindSubmatch(s.Bytes())
if match == nil {
@@ -625,15 +628,15 @@ func parseBinOutput(req *runRequest) ([]ipc.ProgInfo, error) {
return nil, fmt.Errorf("failed to parse errno %q in %q",
string(match[2]), s.Text())
}
- info := &infos[len(infos)-1]
+ info := infos[len(infos)-1]
if call >= uint64(len(info.Calls)) {
return nil, fmt.Errorf("bad call index %v", call)
}
if info.Calls[call].Flags != 0 {
return nil, fmt.Errorf("double result for call %v", call)
}
- info.Calls[call].Flags |= ipc.CallExecuted | ipc.CallFinished
- info.Calls[call].Errno = int(errno)
+ info.Calls[call].Flags |= flatrpc.CallFlagExecuted | flatrpc.CallFlagFinished
+ info.Calls[call].Error = int32(errno)
}
return infos, nil
}
diff --git a/pkg/vminfo/features.go b/pkg/vminfo/features.go
index 3b7bae8d5..905fc630f 100644
--- a/pkg/vminfo/features.go
+++ b/pkg/vminfo/features.go
@@ -186,8 +186,8 @@ func (ctx *checkContext) featureSucceeded(feat flatrpc.Feature, testProg *prog.P
len(res.Info.Calls), len(testProg.Calls))
}
for i, call := range res.Info.Calls {
- if call.Errno != 0 {
- return fmt.Sprintf("call %v failed with errno %v", i, call.Errno)
+ if call.Error != 0 {
+ return fmt.Sprintf("call %v failed with errno %v", i, call.Error)
}
}
call := res.Info.Calls[0]
diff --git a/pkg/vminfo/syscalls.go b/pkg/vminfo/syscalls.go
index f6ab24a04..23c9504e2 100644
--- a/pkg/vminfo/syscalls.go
+++ b/pkg/vminfo/syscalls.go
@@ -140,7 +140,7 @@ func (ctx *checkContext) canOpenImpl(file string, modes []uint64, root bool) str
}
info := ctx.execRaw(calls, prog.StrictUnsafe, root)
for _, call := range info.Calls {
- if call.Errno == 0 {
+ if call.Error == 0 {
return ""
}
}
@@ -148,7 +148,7 @@ func (ctx *checkContext) canOpenImpl(file string, modes []uint64, root bool) str
if root {
who = "root "
}
- return fmt.Sprintf("%vfailed to open %s: %v", who, file, syscall.Errno(info.Calls[0].Errno))
+ return fmt.Sprintf("%vfailed to open %s: %v", who, file, syscall.Errno(info.Calls[0].Error))
}
func (ctx *checkContext) supportedSyscalls(names []string) string {
@@ -161,7 +161,7 @@ func (ctx *checkContext) supportedSyscalls(names []string) string {
}
info := ctx.execRaw(calls, prog.NonStrictUnsafe, false)
for i, res := range info.Calls {
- if res.Errno == int(syscall.ENOSYS) {
+ if res.Error == int32(syscall.ENOSYS) {
return fmt.Sprintf("syscall %v is not present", names[i])
}
}
@@ -201,17 +201,17 @@ func (ctx *checkContext) callSucceeds(call string) string {
func (ctx *checkContext) execCall(call string) syscall.Errno {
info := ctx.execRaw([]string{call}, prog.StrictUnsafe, false)
- return syscall.Errno(info.Calls[0].Errno)
+ return syscall.Errno(info.Calls[0].Error)
}
func (ctx *checkContext) anyCallSucceeds(calls []string, msg string) string {
info := ctx.execRaw(calls, prog.StrictUnsafe, false)
for _, call := range info.Calls {
- if call.Errno == 0 {
+ if call.Error == 0 {
return ""
}
}
- return fmt.Sprintf("%s: %v", msg, syscall.Errno(info.Calls[0].Errno))
+ return fmt.Sprintf("%s: %v", msg, syscall.Errno(info.Calls[0].Error))
}
func (ctx *checkContext) onlySandboxNone() string {
@@ -236,12 +236,12 @@ func (ctx *checkContext) val(name string) uint64 {
return val
}
-func (ctx *checkContext) execRaw(calls []string, mode prog.DeserializeMode, root bool) *ipc.ProgInfo {
+func (ctx *checkContext) execRaw(calls []string, mode prog.DeserializeMode, root bool) *flatrpc.ProgInfo {
sandbox := ctx.sandbox
if root {
sandbox = 0
}
- info := &ipc.ProgInfo{}
+ info := &flatrpc.ProgInfo{}
for remain := calls; len(remain) != 0; {
// Don't put too many syscalls into a single program,
// it will have higher chances to time out.
@@ -267,7 +267,7 @@ func (ctx *checkContext) execRaw(calls []string, mode prog.DeserializeMode, root
info.Calls = append(info.Calls, res.Info.Calls...)
} else if res.Status == queue.Crashed {
// Pretend these calls were not executed.
- info.Calls = append(info.Calls, ipc.EmptyProgInfo(ncalls).Calls...)
+ info.Calls = append(info.Calls, flatrpc.EmptyProgInfo(ncalls).Calls...)
} else {
// The program must have been either executed or not due to a crash.
panic(fmt.Sprintf("got unexpected execution status (%d) for the prog %s",
diff --git a/pkg/vminfo/vminfo_test.go b/pkg/vminfo/vminfo_test.go
index b73a6ad66..0e5d17ef2 100644
--- a/pkg/vminfo/vminfo_test.go
+++ b/pkg/vminfo/vminfo_test.go
@@ -103,14 +103,12 @@ func createSuccessfulResults(source queue.Source, stop chan struct{}) {
// Currently we have 641 (when we failed to properly dedup syscall tests, it was 4349).
panic("too many test programs")
}
- info := &ipc.ProgInfo{}
+ info := &flatrpc.ProgInfo{}
for range req.Prog.Calls {
- info.Calls = append(info.Calls, ipc.CallInfo{
+ info.Calls = append(info.Calls, &flatrpc.CallInfo{
Cover: []uint32{1},
Signal: []uint32{1},
- Comps: map[uint64]map[uint64]bool{
- 1: {2: true},
- },
+ Comps: []*flatrpc.Comparison{{Op1: 1, Op2: 2}},
})
}
req.Done(&queue.Result{
diff --git a/syz-fuzzer/fuzzer.go b/syz-fuzzer/fuzzer.go
index 5feae7585..fbc00feeb 100644
--- a/syz-fuzzer/fuzzer.go
+++ b/syz-fuzzer/fuzzer.go
@@ -268,7 +268,9 @@ func (tool *FuzzerTool) diffMaxSignal(info *flatrpc.ProgInfo, mask signal.Signal
}
func diffMaxSignal(info *flatrpc.ProgInfo, max, mask signal.Signal, maskCall int) {
- info.Extra.Signal = diffCallSignal(info.Extra.Signal, max, mask, -1, maskCall)
+ if info.Extra != nil {
+ info.Extra.Signal = diffCallSignal(info.Extra.Signal, max, mask, -1, maskCall)
+ }
for i := 0; i < len(info.Calls); i++ {
info.Calls[i].Signal = diffCallSignal(info.Calls[i].Signal, max, mask, i, maskCall)
}
diff --git a/syz-fuzzer/proc.go b/syz-fuzzer/proc.go
index acc333b9b..c243c8a31 100644
--- a/syz-fuzzer/proc.go
+++ b/syz-fuzzer/proc.go
@@ -52,7 +52,7 @@ func (proc *Proc) loop() {
info, output, err := proc.execute(req, wait)
res := &flatrpc.ExecResult{
Id: req.Id,
- Info: convertProgInfo(info),
+ Info: info,
Output: output,
Error: err,
}
@@ -63,9 +63,9 @@ func (proc *Proc) loop() {
}
info, output, err := proc.execute(req, 0)
if res.Info == nil {
- res.Info = convertProgInfo(info)
+ res.Info = info
} else if info != nil {
- res.Info.Calls = append(res.Info.Calls, convertCalls(info)...)
+ res.Info.Calls = append(res.Info.Calls, info.Calls...)
}
res.Output = append(res.Output, output...)
res.Error = err
@@ -101,7 +101,7 @@ func (proc *Proc) nextRequest() (*flatrpc.ExecRequest, time.Duration) {
}
func (proc *Proc) execute(req *flatrpc.ExecRequest, wait time.Duration) (
- info *ipc.ProgInfo, output []byte, errStr string) {
+ info *flatrpc.ProgInfo, output []byte, errStr string) {
var err error
if req.Flags&flatrpc.RequestFlagIsBinary != 0 {
output, err = executeBinary(req)
@@ -117,7 +117,7 @@ func (proc *Proc) execute(req *flatrpc.ExecRequest, wait time.Duration) (
return
}
-func (proc *Proc) executeProgram(req *flatrpc.ExecRequest, wait time.Duration) (*ipc.ProgInfo, []byte, error) {
+func (proc *Proc) executeProgram(req *flatrpc.ExecRequest, wait time.Duration) (*flatrpc.ProgInfo, []byte, error) {
returnError := req.Flags&flatrpc.RequestFlagReturnError != 0
execOpts := &ipc.ExecOpts{
EnvFlags: req.ExecEnv,
@@ -126,7 +126,7 @@ func (proc *Proc) executeProgram(req *flatrpc.ExecRequest, wait time.Duration) (
}
for try := 0; ; try++ {
var output []byte
- var info *ipc.ProgInfo
+ var info *flatrpc.ProgInfo
var hanged bool
// On a heavily loaded VM, syz-executor may take significant time to start.
// Let's do it outside of the gate ticket.
@@ -180,39 +180,3 @@ func executeBinary(req *flatrpc.ExecRequest) ([]byte, error) {
}
return output, err
}
-
-func convertProgInfo(info *ipc.ProgInfo) *flatrpc.ProgInfo {
- if info == nil {
- return nil
- }
- return &flatrpc.ProgInfo{
- Elapsed: uint64(info.Elapsed),
- Freshness: uint64(info.Freshness),
- Extra: convertCallInfo(info.Extra),
- Calls: convertCalls(info),
- }
-}
-
-func convertCalls(info *ipc.ProgInfo) []*flatrpc.CallInfo {
- var calls []*flatrpc.CallInfo
- for _, call := range info.Calls {
- calls = append(calls, convertCallInfo(call))
- }
- return calls
-}
-
-func convertCallInfo(info ipc.CallInfo) *flatrpc.CallInfo {
- var comps []*flatrpc.Comparison
- for op1, ops := range info.Comps {
- for op2 := range ops {
- comps = append(comps, &flatrpc.Comparison{Op1: op1, Op2: op2})
- }
- }
- return &flatrpc.CallInfo{
- Flags: flatrpc.CallFlag(info.Flags),
- Error: int32(info.Errno),
- Cover: info.Cover,
- Signal: info.Signal,
- Comps: comps,
- }
-}
diff --git a/syz-fuzzer/testing.go b/syz-fuzzer/testing.go
index 100f63fad..e22813d2a 100644
--- a/syz-fuzzer/testing.go
+++ b/syz-fuzzer/testing.go
@@ -111,7 +111,7 @@ func checkSimpleProgram(args *checkArgs) error {
if len(info.Calls) == 0 {
return fmt.Errorf("no calls executed:\n%s", output)
}
- if info.Calls[0].Errno != 0 {
+ if info.Calls[0].Error != 0 {
return fmt.Errorf("simple call failed: %+v\n%s", info.Calls[0], output)
}
if args.ipcExecOpts.EnvFlags&flatrpc.ExecEnvSignal != 0 && len(info.Calls[0].Signal) < 2 {
diff --git a/syz-manager/rpc.go b/syz-manager/rpc.go
index 2f26ac4c2..711c0a6a4 100644
--- a/syz-manager/rpc.go
+++ b/syz-manager/rpc.go
@@ -383,8 +383,10 @@ func (serv *RPCServer) handleExecResult(runner *Runner, msg *flatrpc.ExecResult)
call.Cover = runner.canonicalizer.Canonicalize(call.Cover)
call.Signal = runner.canonicalizer.Canonicalize(call.Signal)
}
- msg.Info.Extra.Cover = runner.canonicalizer.Canonicalize(msg.Info.Extra.Cover)
- msg.Info.Extra.Signal = runner.canonicalizer.Canonicalize(msg.Info.Extra.Signal)
+ if msg.Info.Extra != nil {
+ msg.Info.Extra.Cover = runner.canonicalizer.Canonicalize(msg.Info.Extra.Cover)
+ msg.Info.Extra.Signal = runner.canonicalizer.Canonicalize(msg.Info.Extra.Signal)
+ }
}
status := queue.Success
var resErr error
@@ -394,7 +396,7 @@ func (serv *RPCServer) handleExecResult(runner *Runner, msg *flatrpc.ExecResult)
}
req.Done(&queue.Result{
Status: status,
- Info: convertProgInfo(msg.Info),
+ Info: msg.Info,
Output: slices.Clone(msg.Output),
Err: resErr,
})
@@ -623,37 +625,3 @@ func addFallbackSignal(p *prog.Prog, info *flatrpc.ProgInfo) {
info.Calls[i].Signal = inf.Signal
}
}
-
-func convertProgInfo(info *flatrpc.ProgInfo) *ipc.ProgInfo {
- if info == nil {
- return nil
- }
- return &ipc.ProgInfo{
- Elapsed: time.Duration(info.Elapsed),
- Freshness: int(info.Freshness),
- Extra: convertCallInfo(info.Extra),
- Calls: convertCalls(info),
- }
-}
-
-func convertCalls(info *flatrpc.ProgInfo) []ipc.CallInfo {
- var calls []ipc.CallInfo
- for _, call := range info.Calls {
- calls = append(calls, convertCallInfo(call))
- }
- return calls
-}
-
-func convertCallInfo(info *flatrpc.CallInfo) ipc.CallInfo {
- comps := make(prog.CompMap)
- for _, comp := range info.Comps {
- comps.AddComp(comp.Op1, comp.Op2)
- }
- return ipc.CallInfo{
- Flags: ipc.CallFlags(info.Flags),
- Errno: int(info.Error),
- Cover: info.Cover,
- Signal: info.Signal,
- Comps: comps,
- }
-}
diff --git a/syz-runner/runner.go b/syz-runner/runner.go
index 8c9f3a5c3..5a9248611 100644
--- a/syz-runner/runner.go
+++ b/syz-runner/runner.go
@@ -1,5 +1,10 @@
// Copyright 2021 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+
+// TODO: switch syz-verifier to use syz-fuzzer.
+
+//go:build never
+
package main
import (
diff --git a/syz-verifier/execresult.go b/syz-verifier/execresult.go
index 9db053a35..dcf2f5812 100644
--- a/syz-verifier/execresult.go
+++ b/syz-verifier/execresult.go
@@ -1,6 +1,10 @@
// Copyright 2021 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+// TODO: switch syz-verifier to use syz-fuzzer.
+
+//go:build never
+
package main
import (
diff --git a/syz-verifier/execresult_test.go b/syz-verifier/execresult_test.go
index 1ff25e73d..af82130d8 100644
--- a/syz-verifier/execresult_test.go
+++ b/syz-verifier/execresult_test.go
@@ -1,6 +1,10 @@
// Copyright 2021 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+// TODO: switch syz-verifier to use syz-fuzzer.
+
+//go:build never
+
package main
import (
diff --git a/syz-verifier/exectask.go b/syz-verifier/exectask.go
index 77ccf1cb5..2e47069c3 100644
--- a/syz-verifier/exectask.go
+++ b/syz-verifier/exectask.go
@@ -1,6 +1,10 @@
// Copyright 2021 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+// TODO: switch syz-verifier to use syz-fuzzer.
+
+//go:build never
+
package main
import (
diff --git a/syz-verifier/exectask_test.go b/syz-verifier/exectask_test.go
index b8e73a587..043cbcd63 100644
--- a/syz-verifier/exectask_test.go
+++ b/syz-verifier/exectask_test.go
@@ -1,6 +1,10 @@
// Copyright 2022 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+// TODO: switch syz-verifier to use syz-fuzzer.
+
+//go:build never
+
package main
import (
diff --git a/syz-verifier/main.go b/syz-verifier/main.go
index 7e58cd0fe..2ae5894e5 100755
--- a/syz-verifier/main.go
+++ b/syz-verifier/main.go
@@ -1,6 +1,10 @@
// Copyright 2021 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+// TODO: switch syz-verifier to use syz-fuzzer.
+
+//go:build never
+
// package main starts the syz-verifier tool. High-level documentation can be
// found in docs/syz_verifier.md.
package main
diff --git a/syz-verifier/main_test.go b/syz-verifier/main_test.go
deleted file mode 100644
index 197daa285..000000000
--- a/syz-verifier/main_test.go
+++ /dev/null
@@ -1,3 +0,0 @@
-// Copyright 2021 syzkaller project authors. All rights reserved.
-// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
-package main
diff --git a/syz-verifier/monitoring_api.go b/syz-verifier/monitoring_api.go
index 50cef162b..51d373f2f 100644
--- a/syz-verifier/monitoring_api.go
+++ b/syz-verifier/monitoring_api.go
@@ -1,6 +1,10 @@
// Copyright 2021 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+// TODO: switch syz-verifier to use syz-fuzzer.
+
+//go:build never
+
package main
import (
diff --git a/syz-verifier/rpcserver.go b/syz-verifier/rpcserver.go
index f80fb7a46..66f15421b 100644
--- a/syz-verifier/rpcserver.go
+++ b/syz-verifier/rpcserver.go
@@ -1,6 +1,10 @@
// Copyright 2021 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+// TODO: switch syz-verifier to use syz-fuzzer.
+
+//go:build never
+
package main
import (
diff --git a/syz-verifier/rpcserver_test.go b/syz-verifier/rpcserver_test.go
index 71047fd2f..a31056a8a 100644
--- a/syz-verifier/rpcserver_test.go
+++ b/syz-verifier/rpcserver_test.go
@@ -1,6 +1,10 @@
// Copyright 2021 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+// TODO: switch syz-verifier to use syz-fuzzer.
+
+//go:build never
+
package main
import (
diff --git a/syz-verifier/stats.go b/syz-verifier/stats.go
index 41ffb7848..22d732034 100644
--- a/syz-verifier/stats.go
+++ b/syz-verifier/stats.go
@@ -1,6 +1,10 @@
// Copyright 2021 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+// TODO: switch syz-verifier to use syz-fuzzer.
+
+//go:build never
+
package main
import (
diff --git a/syz-verifier/stats_test.go b/syz-verifier/stats_test.go
index 762f9092c..b569f0965 100644
--- a/syz-verifier/stats_test.go
+++ b/syz-verifier/stats_test.go
@@ -1,5 +1,10 @@
// Copyright 2021 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+
+// TODO: switch syz-verifier to use syz-fuzzer.
+
+//go:build never
+
package main
import (
diff --git a/syz-verifier/utils_test.go b/syz-verifier/utils_test.go
index 36bec3f74..deaada1b9 100644
--- a/syz-verifier/utils_test.go
+++ b/syz-verifier/utils_test.go
@@ -1,6 +1,10 @@
// Copyright 2021 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+// TODO: switch syz-verifier to use syz-fuzzer.
+
+//go:build never
+
package main
import (
diff --git a/syz-verifier/verifier.go b/syz-verifier/verifier.go
index 295a9da93..c9ca38512 100644
--- a/syz-verifier/verifier.go
+++ b/syz-verifier/verifier.go
@@ -1,6 +1,10 @@
// Copyright 2021 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+// TODO: switch syz-verifier to use syz-fuzzer.
+
+//go:build never
+
package main
import (
diff --git a/syz-verifier/verifier_test.go b/syz-verifier/verifier_test.go
index bf3ba719d..5dd689421 100644
--- a/syz-verifier/verifier_test.go
+++ b/syz-verifier/verifier_test.go
@@ -1,6 +1,10 @@
// Copyright 2021 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+// TODO: switch syz-verifier to use syz-fuzzer.
+
+//go:build never
+
package main
import (
diff --git a/tools/syz-execprog/execprog.go b/tools/syz-execprog/execprog.go
index fdeee6cef..066c1f4ee 100644
--- a/tools/syz-execprog/execprog.go
+++ b/tools/syz-execprog/execprog.go
@@ -251,43 +251,40 @@ func (ctx *Context) logProgram(pid int, p *prog.Prog, callOpts *ipc.ExecOpts) {
ctx.logMu.Unlock()
}
-func (ctx *Context) printCallResults(info *ipc.ProgInfo) {
+func (ctx *Context) printCallResults(info *flatrpc.ProgInfo) {
for i, inf := range info.Calls {
- if inf.Flags&ipc.CallExecuted == 0 {
+ if inf.Flags&flatrpc.CallFlagExecuted == 0 {
continue
}
flags := ""
- if inf.Flags&ipc.CallFinished == 0 {
+ if inf.Flags&flatrpc.CallFlagFinished == 0 {
flags += " unfinished"
}
- if inf.Flags&ipc.CallBlocked != 0 {
+ if inf.Flags&flatrpc.CallFlagBlocked != 0 {
flags += " blocked"
}
- if inf.Flags&ipc.CallFaultInjected != 0 {
+ if inf.Flags&flatrpc.CallFlagFaultInjected != 0 {
flags += " faulted"
}
log.Logf(1, "CALL %v: signal %v, coverage %v errno %v%v",
- i, len(inf.Signal), len(inf.Cover), inf.Errno, flags)
+ i, len(inf.Signal), len(inf.Cover), inf.Error, flags)
}
}
-func (ctx *Context) printHints(p *prog.Prog, info *ipc.ProgInfo) {
+func (ctx *Context) printHints(p *prog.Prog, info *flatrpc.ProgInfo) {
ncomps, ncandidates := 0, 0
for i := range p.Calls {
if *flagOutput {
fmt.Printf("call %v:\n", i)
}
- comps := info.Calls[i].Comps
- for v, args := range comps {
- ncomps += len(args)
+ comps := make(prog.CompMap)
+ for _, cmp := range info.Calls[i].Comps {
+ comps.AddComp(cmp.Op1, cmp.Op2)
if *flagOutput {
- fmt.Printf("comp 0x%x:", v)
- for arg := range args {
- fmt.Printf(" 0x%x", arg)
- }
- fmt.Printf("\n")
+ fmt.Printf("comp 0x%x ? 0x%x\n", cmp.Op1, cmp.Op2)
}
}
+ ncomps += len(comps)
p.MutateWithHints(i, comps, func(p *prog.Prog) bool {
ncandidates++
if *flagOutput {
@@ -325,8 +322,8 @@ func getKernelUpperBase(target *targets.Target) uint32 {
return defaultRet
}
-func (ctx *Context) dumpCallCoverage(coverFile string, info *ipc.CallInfo) {
- if len(info.Cover) == 0 {
+func (ctx *Context) dumpCallCoverage(coverFile string, info *flatrpc.CallInfo) {
+ if info == nil || len(info.Cover) == 0 {
return
}
buf := new(bytes.Buffer)
@@ -340,13 +337,13 @@ func (ctx *Context) dumpCallCoverage(coverFile string, info *ipc.CallInfo) {
}
}
-func (ctx *Context) dumpCoverage(coverFile string, info *ipc.ProgInfo) {
+func (ctx *Context) dumpCoverage(coverFile string, info *flatrpc.ProgInfo) {
for i, inf := range info.Calls {
log.Logf(0, "call #%v: signal %v, coverage %v", i, len(inf.Signal), len(inf.Cover))
- ctx.dumpCallCoverage(fmt.Sprintf("%v.%v", coverFile, i), &inf)
+ ctx.dumpCallCoverage(fmt.Sprintf("%v.%v", coverFile, i), inf)
}
log.Logf(0, "extra: signal %v, coverage %v", len(info.Extra.Signal), len(info.Extra.Cover))
- ctx.dumpCallCoverage(fmt.Sprintf("%v.extra", coverFile), &info.Extra)
+ ctx.dumpCallCoverage(fmt.Sprintf("%v.extra", coverFile), info.Extra)
}
func (ctx *Context) getProgramIndex() int {
diff --git a/tools/syz-runtest/runtest.go b/tools/syz-runtest/runtest.go
index b1caef092..370bc3954 100644
--- a/tools/syz-runtest/runtest.go
+++ b/tools/syz-runtest/runtest.go
@@ -1,6 +1,10 @@
// Copyright 2018 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+// TODO: fold syz-runtest into syz-manager.
+
+//go:build never
+
// Runtest runs syzkaller test programs in sys/*/test/*. Start as:
// $ syz-runtest -config manager.config
// Also see pkg/runtest docs.