Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Tool Trace2Syz #767

Merged
merged 22 commits into from Dec 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
4521e88
fixing weird merge error
shankarapailoor Nov 23, 2018
1899543
fixing presubmit
shankarapailoor Nov 23, 2018
1525a32
fixing presubmit
shankarapailoor Nov 23, 2018
a2a40c4
removing parsing code because of -Xraw option
shankarapailoor Nov 23, 2018
c30e678
fix presubmit
shankarapailoor Nov 23, 2018
947a5e0
update
shankarapailoor Nov 23, 2018
0a3522c
deleting vma_call_handlers as we are currently skipping most vma call…
shankarapailoor Nov 24, 2018
859d97c
removing custom handling of bpf_instruction union
shankarapailoor Nov 24, 2018
05ef592
removing ifconf parsing
shankarapailoor Nov 24, 2018
ba14439
update
shankarapailoor Nov 24, 2018
facd622
removed all expression types and replaced them with constant types. r…
shankarapailoor Nov 27, 2018
e4e1a79
removing ipv6 parsing
shankarapailoor Nov 27, 2018
854b348
presubmit
shankarapailoor Nov 27, 2018
ba32e5c
moving direction check from ipv4_addr out to genUnion
shankarapailoor Nov 27, 2018
e047ac4
removing code that parses kcov
shankarapailoor Nov 27, 2018
6b2d61b
removing redundant test
shankarapailoor Nov 27, 2018
aa74ed3
removing custom code in generate unions to fill ipv4_addr
shankarapailoor Nov 30, 2018
7546bb8
proggen: changing order of imports to make external packages import f…
shankarapailoor Dec 3, 2018
82eb8a3
changing log messages to lower case to be consistent with other packa…
shankarapailoor Dec 3, 2018
662c27c
removing pointer type and simplifying memory_tracker
shankarapailoor Dec 3, 2018
30968ce
moving context and return_cache to seaparate files
shankarapailoor Dec 4, 2018
a82337a
deleting default argument generation when we should probably throw an…
shankarapailoor Dec 4, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .gometalinter.json
Expand Up @@ -39,6 +39,7 @@
],
"exclude": [
"(sys/.*/init.*|sys/targets/common.go).* don't use ALL_CAPS in Go names",
"(tools/syz-trace2syz/parser/(lex|strace).go)",
"exported .* should have comment",
"comment on .* should be of the form",
"declaration of \"err\" shadows",
Expand Down
11 changes: 10 additions & 1 deletion Makefile
Expand Up @@ -86,7 +86,7 @@ endif
.PHONY: all host target \
manager runtest fuzzer executor \
ci hub \
execprog mutate prog2c stress repro upgrade db \
execprog mutate prog2c trace2syz stress repro upgrade db \
bin/syz-sysgen bin/syz-extract bin/syz-fmt \
extract generate generate_go generate_sys \
format format_go format_cpp format_sys \
Expand Down Expand Up @@ -157,6 +157,9 @@ db:
upgrade:
GOOS=$(HOSTOS) GOARCH=$(HOSTARCH) $(HOSTGO) build $(GOHOSTFLAGS) -o ./bin/syz-upgrade github.com/google/syzkaller/tools/syz-upgrade

trace2syz:
GOOS=$(HOSTOS) GOARCH=$(HOSTARCH) $(HOSTGO) build $(GOHOSTFLAGS) -o ./bin/syz-trace2syz github.com/google/syzkaller/tools/syz-trace2syz

# `extract` extracts const files from various kernel sources, and may only
# re-generate parts of files.
extract: bin/syz-extract
Expand Down Expand Up @@ -187,6 +190,10 @@ ifeq ($(TARGETOS),fuchsia)
else
endif

generate_trace2syz:
(cd tools/syz-trace2syz/parser; ragel -Z -G2 -o lex.go straceLex.rl)
(cd tools/syz-trace2syz/parser; goyacc -o strace.go -p Strace -v="" strace.y)

bin/syz-sysgen:
$(GO) build $(GOHOSTFLAGS) -o $@ ./sys/syz-sysgen

Expand Down Expand Up @@ -317,6 +324,8 @@ install_prerequisites:
sudo apt-get install -y -q g++-aarch64-linux-gnu || true
sudo apt-get install -y -q g++-powerpc64le-linux-gnu || true
sudo apt-get install -y -q g++-arm-linux-gnueabihf || true
sudo apt-get install -y -q ragel
go get -u golang.org/x/tools/cmd/goyacc
go get -u gopkg.in/alecthomas/gometalinter.v2
gometalinter.v2 --install

Expand Down
4 changes: 4 additions & 0 deletions prog/size.go
Expand Up @@ -112,6 +112,10 @@ func (target *Target) assignSizesArray(args []Arg) {
}
}

func (target *Target) AssignSizesCall(c *Call) {
target.assignSizesCall(c)
}

func (target *Target) assignSizesCall(c *Call) {
target.assignSizesArray(c.Args)
}
Expand Down
4 changes: 4 additions & 0 deletions prog/types.go
Expand Up @@ -67,6 +67,10 @@ type Type interface {
minimize(ctx *minimizeArgsCtx, arg Arg, path string) bool
}

func DefaultArg(t Type) Arg {
return t.makeDefaultArg()
}

func IsPad(t Type) bool {
if ct, ok := t.(*ConstType); ok && ct.IsPad {
return true
Expand Down
4 changes: 4 additions & 0 deletions prog/validation.go
Expand Up @@ -23,6 +23,10 @@ type validCtx struct {
uses map[Arg]Arg
}

func (p *Prog) Validate() error {
return p.validate()
}

func (p *Prog) validate() error {
ctx := &validCtx{
target: p.Target,
Expand Down
41 changes: 41 additions & 0 deletions tools/syz-trace2syz/config/unsupported_calls.go
@@ -0,0 +1,41 @@
// 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.

package config

var (
// ShouldSkip lists system calls that we should skip when parsing
// Some of these are unsupported or not worth executing
ShouldSkip = map[string]bool{
// While we have system call descriptions for execve it is not worth adding
// the ones in traces. Every trace has an execve at the beginning which means
// all the system calls afterwards will not execute
"execve": true,
// Unsafe to set the addr argument to some random argument. Needs more care
"arch_prctl": true,
// Don't produce multithreaded programs.
"wait4": true,
"wait": true,
"futex": true,
// Cannot obtain coverage from the forks.
"clone": true,
// Can support these calls but need to identify the ones in the trace that are worth keeping
"mmap": true,
"msync": true,
"mremap": true,
"mprotect": true,
"madvise": true,
"munmap": true,
// Not interesting coverage
"getcwd": true,
"getcpu": true,
// Cannot evaluate sigset
"rt_sigprocmask": true,
"rt_sigtimedwait": true,
"rt_sigreturn": true,
"rt_sigqueueinfo": true,
"rt_sigsuspend": true,
// Require function pointers which are not recovered by strace
"rt_sigaction": true,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we also need to ignore set_robust_list and set_tid_address. They are executed by glibc on process/thread start and are present in just any program in the beginning, but normal programs usually don't use them and we probably won't be able to build interesting programs with set_robust_list.

}
)
155 changes: 155 additions & 0 deletions tools/syz-trace2syz/parser/intermediate_types.go
@@ -0,0 +1,155 @@
// 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.

package parser

import (
"bytes"
"fmt"
)

// TraceTree struct contains intermediate representation of trace
// If a trace is multiprocess it constructs a trace for each type
type TraceTree struct {
TraceMap map[int64]*Trace
Ptree map[int64][]int64
RootPid int64
Filename string
}

// NewTraceTree initializes a TraceTree
func NewTraceTree() (tree *TraceTree) {
tree = &TraceTree{
TraceMap: make(map[int64]*Trace),
Ptree: make(map[int64][]int64),
RootPid: -1,
}
return
}

func (tree *TraceTree) add(call *Syscall) {
if tree.RootPid < 0 {
tree.RootPid = call.Pid
}

if !call.Resumed {
if tree.TraceMap[call.Pid] == nil {
tree.TraceMap[call.Pid] = new(Trace)
tree.Ptree[call.Pid] = make([]int64, 0)
}
}
c := tree.TraceMap[call.Pid].add(call)
if c.CallName == "clone" && !c.Paused {
tree.Ptree[c.Pid] = append(tree.Ptree[c.Pid], c.Ret)
}
}

// Trace is just a list of system calls
type Trace struct {
Calls []*Syscall
}

func (trace *Trace) add(call *Syscall) (ret *Syscall) {
if !call.Resumed {
trace.Calls = append(trace.Calls, call)
ret = call
return
}
lastCall := trace.Calls[len(trace.Calls)-1]
lastCall.Args = append(lastCall.Args, call.Args...)
lastCall.Paused = false
lastCall.Ret = call.Ret
ret = lastCall
return
}

// IrType is the intermediate representation of the strace output
// Every argument of a system call should be represented in an intermediate type
type IrType interface {
String() string
}

// Syscall struct is the IR type for any system call
type Syscall struct {
CallName string
Args []IrType
Pid int64
Ret int64
Paused bool
Resumed bool
}

// NewSyscall - constructor
func NewSyscall(pid int64, name string, args []IrType, ret int64, paused, resumed bool) (sys *Syscall) {
return &Syscall{
CallName: name,
Args: args,
Pid: pid,
Ret: ret,
Paused: paused,
Resumed: resumed,
}
}

// String
func (s *Syscall) String() string {
buf := new(bytes.Buffer)

fmt.Fprintf(buf, "Pid: -%v-", s.Pid)
fmt.Fprintf(buf, "Name: -%v-", s.CallName)
for _, typ := range s.Args {
buf.WriteString("-")
buf.WriteString(typ.String())
buf.WriteString("-")
}
buf.WriteString(fmt.Sprintf("-Ret: %d\n", s.Ret))
return buf.String()
}

// GroupType contains arrays and structs
type GroupType struct {
Elems []IrType
}

func newGroupType(elems []IrType) (typ *GroupType) {
return &GroupType{Elems: elems}
}

// String implements IrType String()
func (a *GroupType) String() string {
var buf bytes.Buffer

buf.WriteString("[")
for _, elem := range a.Elems {
buf.WriteString(elem.String())
buf.WriteString(",")
}
buf.WriteString("]")
return buf.String()
}

// Constant represents all evaluated expressions produced by strace
// Constant types are evaluated at parse time
type Constant uint64

func (c Constant) String() string {
return fmt.Sprintf("%#v", c)
}

func (c Constant) Val() uint64 {
return uint64(c)
}

// BufferType contains strings
type BufferType struct {
Val string
}

func newBufferType(val string) *BufferType {
return &BufferType{Val: val}
}

// String implements IrType String()
func (b *BufferType) String() string {
return fmt.Sprintf("Buffer: %s with length: %d\n", b.Val, len(b.Val))
}