From fba338cd51aa2894bdd97b6943c27236df6b98d9 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Fri, 17 Nov 2017 17:57:02 +0100 Subject: pkg/csource: add function to parse serialized options Also move options and options tests into a separate file, add serialization function. --- pkg/csource/options.go | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 pkg/csource/options.go (limited to 'pkg/csource/options.go') diff --git a/pkg/csource/options.go b/pkg/csource/options.go new file mode 100644 index 000000000..e253b3cdf --- /dev/null +++ b/pkg/csource/options.go @@ -0,0 +1,82 @@ +// Copyright 2017 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 csource + +import ( + "bytes" + "errors" + "fmt" +) + +// Options control various aspects of source generation. +// Dashboard also provides serialized Options along with syzkaller reproducers. +type Options struct { + Threaded bool + Collide bool + Repeat bool + Procs int + Sandbox string + + Fault bool // inject fault into FaultCall/FaultNth + FaultCall int + FaultNth int + + // These options allow for a more fine-tuned control over the generated C code. + EnableTun bool + UseTmpDir bool + HandleSegv bool + WaitRepeat bool + Debug bool + + // Generate code for use with repro package to prints log messages, + // which allows to distinguish between a hang and an absent crash. + Repro bool +} + +// Check checks if the opts combination is valid or not. +// For example, Collide without Threaded is not valid. +// Invalid combinations must not be passed to Write. +func (opts Options) Check() error { + if !opts.Threaded && opts.Collide { + // Collide requires threaded. + return errors.New("Collide without Threaded") + } + if !opts.Repeat && opts.Procs > 1 { + // This does not affect generated code. + return errors.New("Procs>1 without Repeat") + } + if opts.Sandbox == "namespace" && !opts.UseTmpDir { + // This is borken and never worked. + // This tries to create syz-tmp dir in cwd, + // which will fail if procs>1 and on second run of the program. + return errors.New("Sandbox=namespace without UseTmpDir") + } + return nil +} + +func (opts Options) Serialize() []byte { + return []byte(fmt.Sprintf("%+v", opts)) +} + +func DeserializeOptions(data []byte) (Options, error) { + data = bytes.Replace(data, []byte("Sandbox: "), []byte("Sandbox:empty "), -1) + var opts Options + n, err := fmt.Sscanf(string(data), + "{Threaded:%t Collide:%t Repeat:%t Procs:%d Sandbox:%s"+ + " Fault:%t FaultCall:%d FaultNth:%d EnableTun:%t UseTmpDir:%t"+ + " HandleSegv:%t WaitRepeat:%t Debug:%t Repro:%t}", + &opts.Threaded, &opts.Collide, &opts.Repeat, &opts.Procs, &opts.Sandbox, + &opts.Fault, &opts.FaultCall, &opts.FaultNth, &opts.EnableTun, &opts.UseTmpDir, + &opts.HandleSegv, &opts.WaitRepeat, &opts.Debug, &opts.Repro) + if err != nil { + return opts, fmt.Errorf("failed to parse repro options: %v", err) + } + if want := 14; n != want { + return opts, fmt.Errorf("failed to parse repro options: got %v fields, want %v", n, want) + } + if opts.Sandbox == "empty" { + opts.Sandbox = "" + } + return opts, nil +} -- cgit mrf-deployment