aboutsummaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2017-09-14 19:25:01 +0200
committerDmitry Vyukov <dvyukov@google.com>2017-09-15 16:02:37 +0200
commit52a33fd516102a98d3753bf69417235b655a68dc (patch)
tree351ab73db934d3b4e4babbe27e8801c659f2631b /pkg
parent25f4fe0662f7f3b390d16b2e786f2ba0aa0293f1 (diff)
prog: remove default target and all global state
Now each prog function accepts the desired target explicitly. No global, implicit state involved. This is much cleaner and allows cross-OS/arch testing, etc.
Diffstat (limited to 'pkg')
-rw-r--r--pkg/csource/csource.go6
-rw-r--r--pkg/csource/csource_test.go24
-rw-r--r--pkg/host/host.go4
-rw-r--r--pkg/host/host_test.go24
-rw-r--r--pkg/ipc/ipc_test.go11
-rw-r--r--pkg/repro/repro.go6
6 files changed, 42 insertions, 33 deletions
diff --git a/pkg/csource/csource.go b/pkg/csource/csource.go
index e1b32e752..8b7c84ad3 100644
--- a/pkg/csource/csource.go
+++ b/pkg/csource/csource.go
@@ -101,7 +101,7 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) {
fmt.Fprint(w, hdr)
fmt.Fprint(w, "\n")
- calls, nvar := generateCalls(exec, opts)
+ calls, nvar := generateCalls(p.Target, exec, opts)
fmt.Fprintf(w, "long r[%v];\n", nvar)
if !opts.Repeat {
@@ -258,7 +258,7 @@ func generateTestFunc(w io.Writer, opts Options, calls []string, name string) {
}
}
-func generateCalls(exec []byte, opts Options) ([]string, int) {
+func generateCalls(target *prog.Target, exec []byte, opts Options) ([]string, int) {
read := func() uint64 {
if len(exec) < 8 {
panic("exec program overflow")
@@ -367,7 +367,7 @@ loop:
fmt.Fprintf(w, "\twrite_file(\"/sys/kernel/debug/fail_futex/ignore-private\", \"N\");\n")
fmt.Fprintf(w, "\tinject_fault(%v);\n", opts.FaultNth)
}
- meta := prog.Syscalls[instr]
+ meta := target.Syscalls[instr]
emitCall := true
if meta.CallName == "syz_test" {
emitCall = false
diff --git a/pkg/csource/csource_test.go b/pkg/csource/csource_test.go
index 941274cb9..c192566e3 100644
--- a/pkg/csource/csource_test.go
+++ b/pkg/csource/csource_test.go
@@ -17,17 +17,17 @@ import (
_ "github.com/google/syzkaller/sys"
)
-func init() {
- prog.SetDefaultTarget("linux", runtime.GOARCH)
-}
-
-func initTest(t *testing.T) (rand.Source, int) {
+func initTest(t *testing.T) (*prog.Target, rand.Source, int) {
t.Parallel()
iters := 1
seed := int64(time.Now().UnixNano())
rs := rand.NewSource(seed)
t.Logf("seed=%v", seed)
- return rs, iters
+ target, err := prog.GetTarget("linux", runtime.GOARCH)
+ if err != nil {
+ t.Fatal(err)
+ }
+ return target, rs, iters
}
func enumerateField(opt Options, field int) []Options {
@@ -89,7 +89,7 @@ func allOptionsPermutations() []Options {
}
func TestOne(t *testing.T) {
- rs, _ := initTest(t)
+ target, rs, _ := initTest(t)
opts := Options{
Threaded: true,
Collide: true,
@@ -99,13 +99,13 @@ func TestOne(t *testing.T) {
Repro: true,
UseTmpDir: true,
}
- p := prog.GenerateAllSyzProg(rs)
+ p := target.GenerateAllSyzProg(rs)
testOne(t, p, opts)
}
func TestOptions(t *testing.T) {
- rs, _ := initTest(t)
- syzProg := prog.GenerateAllSyzProg(rs)
+ target, rs, _ := initTest(t)
+ syzProg := target.GenerateAllSyzProg(rs)
t.Logf("syz program:\n%s\n", syzProg.Serialize())
permutations := allOptionsSingle()
allPermutations := allOptionsPermutations()
@@ -119,10 +119,10 @@ func TestOptions(t *testing.T) {
}
for i, opts := range permutations {
t.Run(fmt.Sprintf("%v", i), func(t *testing.T) {
- rs, iters := initTest(t)
+ target, rs, iters := initTest(t)
t.Logf("opts: %+v", opts)
for i := 0; i < iters; i++ {
- p := prog.Generate(rs, 10, nil)
+ p := target.Generate(rs, 10, nil)
testOne(t, p, opts)
}
testOne(t, syzProg, opts)
diff --git a/pkg/host/host.go b/pkg/host/host.go
index 0fa66dfa4..993db175b 100644
--- a/pkg/host/host.go
+++ b/pkg/host/host.go
@@ -16,7 +16,7 @@ import (
)
// DetectSupportedSyscalls returns list on supported syscalls on host.
-func DetectSupportedSyscalls() (map[*prog.Syscall]bool, error) {
+func DetectSupportedSyscalls(target *prog.Target) (map[*prog.Syscall]bool, error) {
// There are 3 possible strategies:
// 1. Executes all syscalls with presumably invalid arguments and check for ENOprog.
// But not all syscalls are safe to execute. For example, pause will hang,
@@ -29,7 +29,7 @@ func DetectSupportedSyscalls() (map[*prog.Syscall]bool, error) {
kallsyms, _ := ioutil.ReadFile("/proc/kallsyms")
supported := make(map[*prog.Syscall]bool)
- for _, c := range prog.Syscalls {
+ for _, c := range target.Syscalls {
if isSupported(kallsyms, c) {
supported[c] = true
}
diff --git a/pkg/host/host_test.go b/pkg/host/host_test.go
index a9130c094..1c40335d7 100644
--- a/pkg/host/host_test.go
+++ b/pkg/host/host_test.go
@@ -12,19 +12,19 @@ import (
_ "github.com/google/syzkaller/sys"
)
-func init() {
- prog.SetDefaultTarget("linux", runtime.GOARCH)
-}
-
func TestLog(t *testing.T) {
t.Parallel()
+ target, err := prog.GetTarget("linux", runtime.GOARCH)
+ if err != nil {
+ t.Fatal(err)
+ }
// Dump for manual inspection.
- supp, err := DetectSupportedSyscalls()
+ supp, err := DetectSupportedSyscalls(target)
if err != nil {
t.Skipf("skipping: %v", err)
}
t.Logf("unsupported:")
- for _, c := range prog.Syscalls {
+ for _, c := range target.Syscalls {
s, ok := supp[c]
if ok && !s {
t.Fatalf("map contains false value")
@@ -33,9 +33,9 @@ func TestLog(t *testing.T) {
t.Logf("\t%v", c.Name)
}
}
- trans := prog.TransitivelyEnabledCalls(supp)
+ trans := target.TransitivelyEnabledCalls(supp)
t.Logf("transitively unsupported:")
- for _, c := range prog.Syscalls {
+ for _, c := range target.Syscalls {
s, ok := trans[c]
if ok && !s {
t.Fatalf("map contains false value")
@@ -48,7 +48,11 @@ func TestLog(t *testing.T) {
func TestSupportedSyscalls(t *testing.T) {
t.Parallel()
- supp, err := DetectSupportedSyscalls()
+ target, err := prog.GetTarget("linux", runtime.GOARCH)
+ if err != nil {
+ t.Fatal(err)
+ }
+ supp, err := DetectSupportedSyscalls(target)
if err != nil {
t.Skipf("skipping: %v", err)
}
@@ -64,7 +68,7 @@ func TestSupportedSyscalls(t *testing.T) {
"stat",
}
for _, name := range safe {
- c := prog.SyscallMap[name]
+ c := target.SyscallMap[name]
if c == nil {
t.Fatalf("can't find syscall '%v'", name)
}
diff --git a/pkg/ipc/ipc_test.go b/pkg/ipc/ipc_test.go
index ce04a7540..263e94032 100644
--- a/pkg/ipc/ipc_test.go
+++ b/pkg/ipc/ipc_test.go
@@ -19,10 +19,6 @@ import (
const timeout = 10 * time.Second
-func init() {
- prog.SetDefaultTarget("linux", runtime.GOARCH)
-}
-
func buildExecutor(t *testing.T) string {
return buildProgram(t, filepath.FromSlash("../../executor/executor.cc"))
}
@@ -87,6 +83,11 @@ func TestExecute(t *testing.T) {
rs, iters := initTest(t)
flags := []uint64{0, FlagThreaded, FlagThreaded | FlagCollide}
+ target, err := prog.GetTarget("linux", runtime.GOARCH)
+ if err != nil {
+ t.Fatal(err)
+ }
+
bin := buildExecutor(t)
defer os.Remove(bin)
@@ -103,7 +104,7 @@ func TestExecute(t *testing.T) {
defer env.Close()
for i := 0; i < iters/len(flags); i++ {
- p := prog.Generate(rs, 10, nil)
+ p := target.Generate(rs, 10, nil)
opts := &ExecOpts{}
output, _, _, _, err := env.Exec(opts, p)
if err != nil {
diff --git a/pkg/repro/repro.go b/pkg/repro/repro.go
index c3aaa8a22..4787b0262 100644
--- a/pkg/repro/repro.go
+++ b/pkg/repro/repro.go
@@ -65,7 +65,11 @@ func Run(crashLog []byte, cfg *mgrconfig.Config, vmPool *vm.Pool, vmIndexes []in
if len(vmIndexes) == 0 {
return nil, fmt.Errorf("no VMs provided")
}
- entries := prog.ParseLog(crashLog)
+ target, err := prog.GetTarget(cfg.TargetOS, cfg.TargetArch)
+ if err != nil {
+ return nil, err
+ }
+ entries := target.ParseLog(crashLog)
if len(entries) == 0 {
return nil, fmt.Errorf("crash log does not contain any programs")
}