prog: dump orig prog if Deserialize panics

We are seeing some one-off panics during Deserialization
and it's unclear if it's machine memory corrpution or
an actual bug in prog. I leam towards machine memory corruption
but it's impossible to prove without seeing the orig program.

Move git revision to prog and it's more base package
(sys can import prog, prog can't import sys).
This commit is contained in:
Dmitry Vyukov 2020-02-21 10:22:07 +01:00
parent bd2a74a31f
commit b6ed147834
11 changed files with 52 additions and 43 deletions

View File

@ -58,7 +58,7 @@ GITREVDATE=$(shell git log -n 1 --format="%ad")
# Reduces build time and binary sizes considerably.
# That's only needed if you use gdb or nm.
# If you need that, build manually without these flags.
GOFLAGS := "-ldflags=-s -w -X github.com/google/syzkaller/sys.GitRevision=$(REV) -X 'github.com/google/syzkaller/sys.gitRevisionDate=$(GITREVDATE)'"
GOFLAGS := "-ldflags=-s -w -X github.com/google/syzkaller/prog.GitRevision=$(REV) -X 'github.com/google/syzkaller/prog.gitRevisionDate=$(GITREVDATE)'"
GOHOSTFLAGS := $(GOFLAGS)
GOTARGETFLAGS := $(GOFLAGS)

View File

@ -204,6 +204,12 @@ const (
)
func (target *Target) Deserialize(data []byte, mode DeserializeMode) (*Prog, error) {
defer func() {
if err := recover(); err != nil {
panic(fmt.Errorf("%v\ntarget: %v/%v, rev: %v, mode=%v, prog:\n%q",
err, target.OS, target.Arch, GitRevision, mode, data))
}
}()
p := newParser(target, data, mode == Strict)
prog, err := p.parseProg()
if err := p.Err(); err != nil {

26
prog/meta.go Normal file
View File

@ -0,0 +1,26 @@
// Copyright 2020 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 prog
import (
"strings"
"time"
)
var (
GitRevision string // emitted by Makefile, may contain + at the end
GitRevisionBase string // without +
gitRevisionDate string // emitted by Makefile
GitRevisionDate time.Time // parsed from gitRevisionDate
)
func init() {
GitRevisionBase = strings.Replace(GitRevision, "+", "", -1)
if gitRevisionDate != "" {
var err error
if GitRevisionDate, err = time.Parse("Mon Jan 2 15:04:05 2006 -0700", gitRevisionDate); err != nil {
panic(err)
}
}
}

View File

@ -4,9 +4,6 @@
package sys
import (
"strings"
"time"
// Import all targets, so that users only need to import sys.
_ "github.com/google/syzkaller/sys/akaros/gen"
_ "github.com/google/syzkaller/sys/freebsd/gen"
@ -17,20 +14,3 @@ import (
_ "github.com/google/syzkaller/sys/test/gen"
_ "github.com/google/syzkaller/sys/windows/gen"
)
var (
GitRevision string // emitted by Makefile, may contain + at the end
GitRevisionBase string // without +
gitRevisionDate string // emitted by Makefile
GitRevisionDate time.Time // parsed from gitRevisionDate
)
func init() {
GitRevisionBase = strings.Replace(GitRevision, "+", "", -1)
if gitRevisionDate != "" {
var err error
if GitRevisionDate, err = time.Parse("Mon Jan 2 15:04:05 2006 -0700", gitRevisionDate); err != nil {
panic(err)
}
}
}

View File

@ -23,7 +23,8 @@ import (
"github.com/google/syzkaller/pkg/osutil"
"github.com/google/syzkaller/pkg/report"
"github.com/google/syzkaller/pkg/vcs"
"github.com/google/syzkaller/sys"
"github.com/google/syzkaller/prog"
_ "github.com/google/syzkaller/sys"
"github.com/google/syzkaller/sys/targets"
"github.com/google/syzkaller/vm"
)
@ -530,7 +531,7 @@ func (mgr *Manager) createDashboardBuild(info *BuildInfo, imageDir, typ string)
// Also mix in build type, so that image error builds are not merged into normal builds.
var tagData []byte
tagData = append(tagData, info.Tag...)
tagData = append(tagData, sys.GitRevisionBase...)
tagData = append(tagData, prog.GitRevisionBase...)
tagData = append(tagData, typ...)
build := &dashapi.Build{
Manager: mgr.name,
@ -538,8 +539,8 @@ func (mgr *Manager) createDashboardBuild(info *BuildInfo, imageDir, typ string)
OS: mgr.managercfg.TargetOS,
Arch: mgr.managercfg.TargetArch,
VMArch: mgr.managercfg.TargetVMArch,
SyzkallerCommit: sys.GitRevisionBase,
SyzkallerCommitDate: sys.GitRevisionDate,
SyzkallerCommit: prog.GitRevisionBase,
SyzkallerCommitDate: prog.GitRevisionDate,
CompilerID: info.CompilerID,
KernelRepo: info.KernelRepo,
KernelBranch: info.KernelBranch,

View File

@ -17,7 +17,7 @@ import (
"github.com/google/syzkaller/pkg/log"
"github.com/google/syzkaller/pkg/osutil"
"github.com/google/syzkaller/pkg/vcs"
"github.com/google/syzkaller/sys"
"github.com/google/syzkaller/prog"
)
const (
@ -119,7 +119,7 @@ func (upd *SyzUpdater) UpdateOnStart(autoupdate bool, shutdown chan struct{}) {
if st, err := os.Stat(upd.exe); err == nil {
exeMod = st.ModTime()
}
uptodate := sys.GitRevisionBase == latestTag && time.Since(exeMod) < time.Minute
uptodate := prog.GitRevisionBase == latestTag && time.Since(exeMod) < time.Minute
if uptodate || !autoupdate {
if uptodate {
// Have a fresh up-to-date build, probably just restarted.
@ -133,11 +133,11 @@ func (upd *SyzUpdater) UpdateOnStart(autoupdate bool, shutdown chan struct{}) {
return
}
}
log.Logf(0, "current executable is on %v", sys.GitRevision)
log.Logf(0, "current executable is on %v", prog.GitRevision)
log.Logf(0, "latest syzkaller build is on %v", latestTag)
// No syzkaller build or executable is stale.
lastCommit := sys.GitRevisionBase
lastCommit := prog.GitRevisionBase
for {
lastCommit = upd.pollAndBuild(lastCommit)
latestTag := upd.checkLatest()
@ -148,7 +148,7 @@ func (upd *SyzUpdater) UpdateOnStart(autoupdate bool, shutdown chan struct{}) {
if err := osutil.LinkFiles(upd.latestDir, upd.currentDir, upd.syzFiles); err != nil {
log.Fatal(err)
}
if autoupdate && sys.GitRevisionBase != latestTag {
if autoupdate && prog.GitRevisionBase != latestTag {
upd.UpdateAndRestart()
}
return

View File

@ -17,7 +17,6 @@ import (
"github.com/google/syzkaller/pkg/rpctype"
"github.com/google/syzkaller/pkg/runtest"
"github.com/google/syzkaller/prog"
"github.com/google/syzkaller/sys"
)
type checkArgs struct {
@ -203,13 +202,13 @@ func checkRevisions(args *checkArgs) error {
if args.target.Arch != vers[1] {
return fmt.Errorf("mismatching target/executor arches: %v vs %v", args.target.Arch, vers[1])
}
if sys.GitRevision != vers[3] {
if prog.GitRevision != vers[3] {
return fmt.Errorf("mismatching fuzzer/executor git revisions: %v vs %v",
sys.GitRevision, vers[3])
prog.GitRevision, vers[3])
}
if args.gitRevision != "" && args.gitRevision != sys.GitRevision {
if args.gitRevision != "" && args.gitRevision != prog.GitRevision {
return fmt.Errorf("mismatching manager/fuzzer git revisions: %v vs %v",
args.gitRevision, sys.GitRevision)
args.gitRevision, prog.GitRevision)
}
if args.target.Revision != vers[2] {
return fmt.Errorf("mismatching fuzzer/executor system call descriptions: %v vs %v",

View File

@ -27,7 +27,6 @@ import (
"github.com/google/syzkaller/pkg/signal"
"github.com/google/syzkaller/pkg/vcs"
"github.com/google/syzkaller/prog"
"github.com/google/syzkaller/sys"
)
func (mgr *Manager) initHTTP() {
@ -112,7 +111,7 @@ func (mgr *Manager) collectStats() []UIStat {
defer mgr.mu.Unlock()
rawStats := mgr.stats.all()
head := sys.GitRevisionBase
head := prog.GitRevisionBase
stats := []UIStat{
{Name: "revision", Value: fmt.Sprint(head[:8]), Link: vcs.LogLink(vcs.SyzkallerRepo, head)},
{Name: "config", Value: mgr.cfg.Name, Link: "/config"},

View File

@ -33,7 +33,6 @@ import (
"github.com/google/syzkaller/pkg/rpctype"
"github.com/google/syzkaller/pkg/signal"
"github.com/google/syzkaller/prog"
"github.com/google/syzkaller/sys"
"github.com/google/syzkaller/sys/targets"
"github.com/google/syzkaller/vm"
)
@ -112,7 +111,7 @@ type Crash struct {
}
func main() {
if sys.GitRevision == "" {
if prog.GitRevision == "" {
log.Fatalf("Bad syz-manager build. Build with make, run bin/syz-manager.")
}
flag.Parse()

View File

@ -15,7 +15,6 @@ import (
"github.com/google/syzkaller/pkg/rpctype"
"github.com/google/syzkaller/pkg/signal"
"github.com/google/syzkaller/prog"
"github.com/google/syzkaller/sys"
)
type RPCServer struct {
@ -97,7 +96,7 @@ func (serv *RPCServer) Connect(a *rpctype.ConnectArgs, r *rpctype.ConnectRes) er
r.MemoryLeakFrames = bugFrames.memoryLeaks
r.DataRaceFrames = bugFrames.dataRaces
r.EnabledCalls = serv.enabledSyscalls
r.GitRevision = sys.GitRevision
r.GitRevision = prog.GitRevision
r.TargetRevision = serv.target.Revision
// TODO: temporary disabled b/c we suspect this negatively affects fuzzing.
if false && serv.mgr.rotateCorpus() && serv.rnd.Intn(3) != 0 {

View File

@ -26,7 +26,7 @@ import (
"github.com/google/syzkaller/pkg/rpctype"
"github.com/google/syzkaller/pkg/runtest"
"github.com/google/syzkaller/prog"
"github.com/google/syzkaller/sys"
_ "github.com/google/syzkaller/sys"
"github.com/google/syzkaller/sys/targets"
"github.com/google/syzkaller/vm"
)
@ -213,7 +213,7 @@ func (mgr *Manager) finishRequest(name string, rep *report.Report) error {
}
func (mgr *Manager) Connect(a *rpctype.ConnectArgs, r *rpctype.ConnectRes) error {
r.GitRevision = sys.GitRevision
r.GitRevision = prog.GitRevision
r.TargetRevision = mgr.target.Revision
r.AllSandboxes = true
select {