aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2017-09-15 10:15:00 +0200
committerDmitry Vyukov <dvyukov@google.com>2017-09-15 16:02:37 +0200
commit539e603206f427ff6549cde661fef0205a4c9034 (patch)
treede4cd1db71fc293582ad495f4d8cc16f196c6827
parent19f9bc13d374058b83b2712f119bb42559b35c0c (diff)
syz-manager, syz-fuzzer, executor: ensure that binaries are consistent
Check that manager/fuzzer/executor are build on the same git revision, use the same syscall descriptions and the same target arch. Update #336
-rw-r--r--Makefile12
-rw-r--r--executor/executor.cc9
-rw-r--r--executor/syscalls.h10
-rw-r--r--pkg/rpctype/rpctype.go5
-rw-r--r--prog/target.go1
-rw-r--r--sys/linux/386.go4
-rw-r--r--sys/linux/amd64.go4
-rw-r--r--sys/linux/arm.go4
-rw-r--r--sys/linux/arm64.go4
-rw-r--r--sys/linux/init.go3
-rw-r--r--sys/linux/ppc64le.go4
-rw-r--r--sys/sys.go3
-rw-r--r--sys/syz-sysgen/sysgen.go27
-rw-r--r--syz-fuzzer/fuzzer.go14
-rw-r--r--syz-manager/manager.go14
15 files changed, 100 insertions, 18 deletions
diff --git a/Makefile b/Makefile
index b035653ae..d59970c05 100644
--- a/Makefile
+++ b/Makefile
@@ -15,6 +15,13 @@ endif
android \
format tidy test arch cross-compile presubmit clean
+GITREV=$(shell git rev-parse HEAD)
+ifeq ($(`git diff --shortstat`), "")
+ REV=$(GITREV)
+else
+ REV=$(GITREV)+
+endif
+
all:
$(MAKE) main
$(MAKE) tools
@@ -29,13 +36,14 @@ tools: execprog mutate prog2c stress repro upgrade db
# executor uses stacks of limited size, so no jumbo frames.
executor:
- $(CC) -o ./bin/syz-executor executor/executor.cc -pthread -Wall -Wframe-larger-than=8192 -Wparentheses -Werror -O1 -g $(STATIC_FLAG) $(CFLAGS)
+ $(CC) -o ./bin/syz-executor executor/executor.cc -pthread -Wall -Wframe-larger-than=8192 \
+ -Wparentheses -Werror -O1 -g $(STATIC_FLAG) $(CFLAGS) -DGIT_REVISION=\"$(REV)\"
# Don't generate symbol table and DWARF debug info.
# 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"
+GOFLAGS="-ldflags=-s -w -X github.com/google/syzkaller/sys.GitRevision=$(REV)"
manager:
go build $(GOFLAGS) -o ./bin/syz-manager github.com/google/syzkaller/syz-manager
diff --git a/executor/executor.cc b/executor/executor.cc
index 87a597253..ce8d0ed2f 100644
--- a/executor/executor.cc
+++ b/executor/executor.cc
@@ -228,8 +228,17 @@ uint64_t read_cover_size(thread_t* th);
static uint32_t hash(uint32_t a);
static bool dedup(uint32_t sig);
+#ifndef GIT_REVISION
+#define GIT_REVISION "unknown"
+#endif
+
int main(int argc, char** argv)
{
+ if (argc == 2 && strcmp(argv[1], "version") == 0) {
+ puts("linux " GOARCH " " SYZ_REVISION " " GIT_REVISION);
+ return 0;
+ }
+
prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
if (mmap(&input_data[0], kMaxInput, PROT_READ, MAP_PRIVATE | MAP_FIXED, kInFd, 0) != &input_data[0])
fail("mmap of input file failed");
diff --git a/executor/syscalls.h b/executor/syscalls.h
index 68446e9a0..c530a1359 100644
--- a/executor/syscalls.h
+++ b/executor/syscalls.h
@@ -6,6 +6,8 @@ struct call_t {
};
#if defined(__i386__) || 0
+#define GOARCH "386"
+#define SYZ_REVISION "fb26afa29ccd7317f2c0796cf1386b493eeb955f"
#define __NR_syz_emit_ethernet 1000000
#define __NR_syz_extract_tcp_res 1000001
#define __NR_syz_fuse_mount 1000002
@@ -1564,6 +1566,8 @@ static call_t syscalls[] = {
#endif
#if defined(__x86_64__) || 0
+#define GOARCH "amd64"
+#define SYZ_REVISION "c14ec0f07c2984481a0bf1453ea928549382eb25"
#define __NR_syz_emit_ethernet 1000000
#define __NR_syz_extract_tcp_res 1000001
#define __NR_syz_fuse_mount 1000002
@@ -3122,6 +3126,8 @@ static call_t syscalls[] = {
#endif
#if defined(__arm__) || 0
+#define GOARCH "arm"
+#define SYZ_REVISION "f73cb445fdead3417b165eec037a0d892cc3253e"
#define __NR_syz_emit_ethernet 1000000
#define __NR_syz_extract_tcp_res 1000001
#define __NR_syz_fuse_mount 1000002
@@ -4680,6 +4686,8 @@ static call_t syscalls[] = {
#endif
#if defined(__aarch64__) || 0
+#define GOARCH "arm64"
+#define SYZ_REVISION "72353a7ede1fe6cb903fcb02eb5eb11407bea5d8"
#define __NR_syz_emit_ethernet 1000000
#define __NR_syz_extract_tcp_res 1000001
#define __NR_syz_fuse_mount 1000002
@@ -6238,6 +6246,8 @@ static call_t syscalls[] = {
#endif
#if defined(__ppc64__) || defined(__PPC64__) || defined(__powerpc64__) || 0
+#define GOARCH "ppc64le"
+#define SYZ_REVISION "cec4f3697757a69ac044be83bac5ba45df7f2fbf"
#define __NR_syz_emit_ethernet 1000000
#define __NR_syz_extract_tcp_res 1000001
#define __NR_syz_fuse_mount 1000002
diff --git a/pkg/rpctype/rpctype.go b/pkg/rpctype/rpctype.go
index 90da1e7fe..78f8938f8 100644
--- a/pkg/rpctype/rpctype.go
+++ b/pkg/rpctype/rpctype.go
@@ -39,6 +39,11 @@ type CheckArgs struct {
UserNamespaces bool
CompsSupported bool
Calls []string
+ FuzzerGitRev string
+ FuzzerSyzRev string
+ ExecutorGitRev string
+ ExecutorSyzRev string
+ ExecutorArch string
}
type NewInputArgs struct {
diff --git a/prog/target.go b/prog/target.go
index 83cf1a77c..1a099bf8e 100644
--- a/prog/target.go
+++ b/prog/target.go
@@ -12,6 +12,7 @@ import (
type Target struct {
OS string
Arch string
+ Revision string // unique hash representing revision of the descriptions
PtrSize uint64
PageSize uint64
DataOffset uint64
diff --git a/sys/linux/386.go b/sys/linux/386.go
index 60842fd78..edce34ee9 100644
--- a/sys/linux/386.go
+++ b/sys/linux/386.go
@@ -4,7 +4,7 @@ package linux
import . "github.com/google/syzkaller/prog"
func init() {
- initArch(syscalls_386, resources_386, structDescs_386, consts_386, "386", 4)
+ initArch(revision_386, syscalls_386, resources_386, structDescs_386, consts_386, "386", 4)
}
var resources_386 = []*ResourceDesc{
@@ -17186,3 +17186,5 @@ var consts_386 = []ConstValue{
{Name: "__WCLONE", Value: 2147483648},
{Name: "__WNOTHREAD", Value: 536870912},
}
+
+const revision_386 = "fb26afa29ccd7317f2c0796cf1386b493eeb955f"
diff --git a/sys/linux/amd64.go b/sys/linux/amd64.go
index 5a64db3e7..53f1aacc4 100644
--- a/sys/linux/amd64.go
+++ b/sys/linux/amd64.go
@@ -4,7 +4,7 @@ package linux
import . "github.com/google/syzkaller/prog"
func init() {
- initArch(syscalls_amd64, resources_amd64, structDescs_amd64, consts_amd64, "amd64", 8)
+ initArch(revision_amd64, syscalls_amd64, resources_amd64, structDescs_amd64, consts_amd64, "amd64", 8)
}
var resources_amd64 = []*ResourceDesc{
@@ -17268,3 +17268,5 @@ var consts_amd64 = []ConstValue{
{Name: "__WCLONE", Value: 2147483648},
{Name: "__WNOTHREAD", Value: 536870912},
}
+
+const revision_amd64 = "c14ec0f07c2984481a0bf1453ea928549382eb25"
diff --git a/sys/linux/arm.go b/sys/linux/arm.go
index 3eb900c60..b364bdc71 100644
--- a/sys/linux/arm.go
+++ b/sys/linux/arm.go
@@ -4,7 +4,7 @@ package linux
import . "github.com/google/syzkaller/prog"
func init() {
- initArch(syscalls_arm, resources_arm, structDescs_arm, consts_arm, "arm", 4)
+ initArch(revision_arm, syscalls_arm, resources_arm, structDescs_arm, consts_arm, "arm", 4)
}
var resources_arm = []*ResourceDesc{
@@ -17140,3 +17140,5 @@ var consts_arm = []ConstValue{
{Name: "__WCLONE", Value: 2147483648},
{Name: "__WNOTHREAD", Value: 536870912},
}
+
+const revision_arm = "f73cb445fdead3417b165eec037a0d892cc3253e"
diff --git a/sys/linux/arm64.go b/sys/linux/arm64.go
index f82fa3974..8f90a0822 100644
--- a/sys/linux/arm64.go
+++ b/sys/linux/arm64.go
@@ -4,7 +4,7 @@ package linux
import . "github.com/google/syzkaller/prog"
func init() {
- initArch(syscalls_arm64, resources_arm64, structDescs_arm64, consts_arm64, "arm64", 8)
+ initArch(revision_arm64, syscalls_arm64, resources_arm64, structDescs_arm64, consts_arm64, "arm64", 8)
}
var resources_arm64 = []*ResourceDesc{
@@ -17182,3 +17182,5 @@ var consts_arm64 = []ConstValue{
{Name: "__WCLONE", Value: 2147483648},
{Name: "__WNOTHREAD", Value: 536870912},
}
+
+const revision_arm64 = "72353a7ede1fe6cb903fcb02eb5eb11407bea5d8"
diff --git a/sys/linux/init.go b/sys/linux/init.go
index cbf93e963..509e2ab04 100644
--- a/sys/linux/init.go
+++ b/sys/linux/init.go
@@ -9,12 +9,13 @@ import (
"github.com/google/syzkaller/prog"
)
-func initArch(syscalls []*prog.Syscall, resources []*prog.ResourceDesc,
+func initArch(rev string, syscalls []*prog.Syscall, resources []*prog.ResourceDesc,
structDescs []*prog.KeyedStruct, consts []prog.ConstValue, archName string, ptrSize uint64) {
arch := makeArch(syscalls, resources, structDescs, consts, archName)
target := &prog.Target{
OS: "linux",
Arch: archName,
+ Revision: rev,
PtrSize: ptrSize,
PageSize: pageSize,
DataOffset: dataOffset,
diff --git a/sys/linux/ppc64le.go b/sys/linux/ppc64le.go
index b1b9459ed..aa0f691a7 100644
--- a/sys/linux/ppc64le.go
+++ b/sys/linux/ppc64le.go
@@ -4,7 +4,7 @@ package linux
import . "github.com/google/syzkaller/prog"
func init() {
- initArch(syscalls_ppc64le, resources_ppc64le, structDescs_ppc64le, consts_ppc64le, "ppc64le", 8)
+ initArch(revision_ppc64le, syscalls_ppc64le, resources_ppc64le, structDescs_ppc64le, consts_ppc64le, "ppc64le", 8)
}
var resources_ppc64le = []*ResourceDesc{
@@ -17172,3 +17172,5 @@ var consts_ppc64le = []ConstValue{
{Name: "__WCLONE", Value: 2147483648},
{Name: "__WNOTHREAD", Value: 536870912},
}
+
+const revision_ppc64le = "cec4f3697757a69ac044be83bac5ba45df7f2fbf"
diff --git a/sys/sys.go b/sys/sys.go
index 7f52504fe..3ab982fdb 100644
--- a/sys/sys.go
+++ b/sys/sys.go
@@ -74,3 +74,6 @@ func init() {
}
}
}
+
+// Emitted by Makefile.
+var GitRevision string
diff --git a/sys/syz-sysgen/sysgen.go b/sys/syz-sysgen/sysgen.go
index ce88cb539..ea3e3e110 100644
--- a/sys/syz-sysgen/sysgen.go
+++ b/sys/syz-sysgen/sysgen.go
@@ -21,6 +21,7 @@ import (
"github.com/google/syzkaller/pkg/ast"
"github.com/google/syzkaller/pkg/compiler"
+ "github.com/google/syzkaller/pkg/hash"
"github.com/google/syzkaller/pkg/serializer"
"github.com/google/syzkaller/prog"
"github.com/google/syzkaller/sys"
@@ -79,9 +80,11 @@ func main() {
sysFile := filepath.Join("sys", OS, job.Target.Arch+".go")
out := new(bytes.Buffer)
generate(job.Target, prog, consts, out)
+ rev := hash.String(out.Bytes())
+ fmt.Fprintf(out, "const revision_%v = %q\n", job.Target.Arch, rev)
writeSource(sysFile, out.Bytes())
- job.ArchData = generateExecutorSyscalls(job.Target, prog.Syscalls)
+ job.ArchData = generateExecutorSyscalls(job.Target, prog.Syscalls, rev)
job.OK = true
}()
}
@@ -132,8 +135,8 @@ func generate(target *sys.Target, prg *compiler.Prog, consts map[string]uint64,
fmt.Fprintf(out, "import . \"github.com/google/syzkaller/prog\"\n\n")
fmt.Fprintf(out, "func init() {\n")
- fmt.Fprintf(out, "\tinitArch(syscalls_%v, resources_%v, structDescs_%v, consts_%v, %q, %v)\n",
- target.Arch, target.Arch, target.Arch, target.Arch, target.Arch, target.PtrSize)
+ fmt.Fprintf(out, "\tinitArch(revision_%v, syscalls_%v, resources_%v, structDescs_%v, consts_%v, %q, %v)\n",
+ target.Arch, target.Arch, target.Arch, target.Arch, target.Arch, target.Arch, target.PtrSize)
fmt.Fprintf(out, "}\n\n")
fmt.Fprintf(out, "var resources_%v = ", target.Arch)
@@ -157,21 +160,25 @@ func generate(target *sys.Target, prg *compiler.Prog, consts map[string]uint64,
})
fmt.Fprintf(out, "var consts_%v = ", target.Arch)
serializer.Write(out, constArr)
- fmt.Fprintf(out, "\n")
+ fmt.Fprintf(out, "\n\n")
}
-func generateExecutorSyscalls(target *sys.Target, syscalls []*prog.Syscall) []byte {
+func generateExecutorSyscalls(target *sys.Target, syscalls []*prog.Syscall, rev string) []byte {
type SyscallData struct {
Name string
NR int32
}
type ArchData struct {
- CARCH []string
- Calls []SyscallData
- Fake []SyscallData
+ Revision string
+ GOARCH string
+ CARCH []string
+ Calls []SyscallData
+ Fake []SyscallData
}
data := ArchData{
- CARCH: target.CArch,
+ Revision: rev,
+ GOARCH: target.Arch,
+ CARCH: target.CArch,
}
fake := make(map[string]uint64)
for _, c := range syscalls {
@@ -247,6 +254,8 @@ struct call_t {
var archTempl = template.Must(template.New("").Parse(`
#if {{range $cdef := $.CARCH}}defined({{$cdef}}) || {{end}}0
+#define GOARCH "{{.GOARCH}}"
+#define SYZ_REVISION "{{.Revision}}"
{{range $c := $.Fake}}#define __NR_{{$c.Name}} {{$c.NR}}
{{end}}
static call_t syscalls[] = {
diff --git a/syz-fuzzer/fuzzer.go b/syz-fuzzer/fuzzer.go
index f41296c9b..8c94c7d49 100644
--- a/syz-fuzzer/fuzzer.go
+++ b/syz-fuzzer/fuzzer.go
@@ -29,6 +29,7 @@ import (
"github.com/google/syzkaller/pkg/osutil"
. "github.com/google/syzkaller/pkg/rpctype"
"github.com/google/syzkaller/prog"
+ "github.com/google/syzkaller/sys"
"github.com/google/syzkaller/sys/linux"
)
@@ -175,9 +176,22 @@ func main() {
kcov, compsSupported := checkCompsSupported()
Logf(1, "KCOV_CHECK: compsSupported=%v", compsSupported)
if r.NeedCheck {
+ out, err := osutil.RunCmd(time.Minute, "", *flagExecutor, "version")
+ if err != nil {
+ panic(err)
+ }
+ vers := strings.Split(strings.TrimSpace(string(out)), " ")
+ if len(vers) != 4 {
+ panic(fmt.Sprintf("bad executor version: %q", string(out)))
+ }
a := &CheckArgs{
Name: *flagName,
UserNamespaces: osutil.IsExist("/proc/self/ns/user"),
+ FuzzerGitRev: sys.GitRevision,
+ FuzzerSyzRev: target.Revision,
+ ExecutorGitRev: vers[3],
+ ExecutorSyzRev: vers[2],
+ ExecutorArch: vers[1],
}
a.Kcov = kcov
if fd, err := syscall.Open("/sys/kernel/debug/kmemleak", syscall.O_RDWR, 0); err == nil {
diff --git a/syz-manager/manager.go b/syz-manager/manager.go
index 368ca2e8f..d20048130 100644
--- a/syz-manager/manager.go
+++ b/syz-manager/manager.go
@@ -29,7 +29,7 @@ import (
"github.com/google/syzkaller/pkg/repro"
. "github.com/google/syzkaller/pkg/rpctype"
"github.com/google/syzkaller/prog"
- _ "github.com/google/syzkaller/sys"
+ "github.com/google/syzkaller/sys"
"github.com/google/syzkaller/syz-manager/mgrconfig"
"github.com/google/syzkaller/vm"
)
@@ -870,6 +870,18 @@ func (mgr *Manager) Check(a *CheckArgs, r *int) error {
if mgr.cfg.Sandbox == "namespace" && !a.UserNamespaces {
Fatalf("/proc/self/ns/user is missing or permission is denied. Requested namespace sandbox but user namespaces are not enabled. Enable CONFIG_USER_NS")
}
+ if mgr.target.Arch != a.ExecutorArch {
+ Fatalf("mismatching target/executor arch: target=%v executor=%v",
+ mgr.target.Arch, a.ExecutorArch)
+ }
+ if sys.GitRevision != a.FuzzerGitRev || sys.GitRevision != a.ExecutorGitRev {
+ Fatalf("mismatching git revisions:\nmanager= %v\nfuzzer= %v\nexecutor=%v",
+ sys.GitRevision, a.FuzzerGitRev, a.ExecutorGitRev)
+ }
+ if mgr.target.Revision != a.FuzzerSyzRev || mgr.target.Revision != a.ExecutorSyzRev {
+ Fatalf("mismatching syscall descriptions:\nmanager= %v\nfuzzer= %v\nexecutor=%v",
+ mgr.target.Revision, a.FuzzerSyzRev, a.ExecutorSyzRev)
+ }
mgr.vmChecked = true
mgr.enabledCalls = a.Calls
return nil