From 9fb3ae4dfd75706d58488fdc13f10fd7e9a8839c Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Mon, 14 May 2018 11:17:23 +0200 Subject: pkg/osutil: introduce TempFile helper Introduce TempFile helper and use it in several packages. --- pkg/csource/build.go | 20 +++++++++----------- pkg/db/db_test.go | 10 +++++----- pkg/osutil/osutil.go | 11 +++++++++++ sys/syz-extract/fetch.go | 32 +++++++++----------------------- 4 files changed, 34 insertions(+), 39 deletions(-) diff --git a/pkg/csource/build.go b/pkg/csource/build.go index c0fc86078..cd67aa4f3 100644 --- a/pkg/csource/build.go +++ b/pkg/csource/build.go @@ -19,21 +19,19 @@ import ( // Build builds a C/C++ program from source src and returns name of the resulting binary. // lang can be "c" or "c++". func Build(target *prog.Target, lang, src string) (string, error) { - // We call the binary syz-executor because it sometimes shows in bug titles, - // and we don't want 2 different bugs for when a crash is triggered during fuzzing and during repro. - bin, err := ioutil.TempFile("", "syz-executor") - if err != nil { - return "", fmt.Errorf("failed to create temp file: %v", err) - } - bin.Close() sysTarget := targets.List[target.OS][target.Arch] compiler := sysTarget.CCompilerPrefix + "gcc" if _, err := exec.LookPath(compiler); err != nil { return "", ErrNoCompiler } + // We call the binary syz-executor because it sometimes shows in bug titles, + // and we don't want 2 different bugs for when a crash is triggered during fuzzing and during repro. + bin, err := osutil.TempFile("syz-executor") + if err != nil { + return "", err + } flags := []string{ - "-x", lang, "-Wall", "-Werror", "-O1", "-g", "-o", bin.Name(), - src, "-pthread", + "-x", lang, "-Wall", "-Werror", "-O1", "-g", "-o", bin, src, "-pthread", } flags = append(flags, sysTarget.CrossCFlags...) if sysTarget.PtrSize == 4 { @@ -46,12 +44,12 @@ func Build(target *prog.Target, lang, src string) (string, error) { out, err = osutil.Command(compiler, flags...).CombinedOutput() } if err != nil { - os.Remove(bin.Name()) + os.Remove(bin) data, _ := ioutil.ReadFile(src) return "", fmt.Errorf("failed to build program:\n%s\n%s\ncompiler invocation: %v %v", data, out, compiler, flags) } - return bin.Name(), nil + return bin, nil } var ErrNoCompiler = errors.New("no target compiler") diff --git a/pkg/db/db_test.go b/pkg/db/db_test.go index 538544c60..38456eb17 100644 --- a/pkg/db/db_test.go +++ b/pkg/db/db_test.go @@ -5,11 +5,12 @@ package db import ( "fmt" - "io/ioutil" "math/rand" "os" "reflect" "testing" + + "github.com/google/syzkaller/pkg/osutil" ) func TestBasic(t *testing.T) { @@ -118,10 +119,9 @@ func TestLarge(t *testing.T) { } func tempFile(t *testing.T) string { - f, err := ioutil.TempFile("", "syzkaller.test.db") + fn, err := osutil.TempFile("syzkaller.test.db") if err != nil { - t.Fatalf("failed to create temp file: %v", err) + t.Fatal(err) } - f.Close() - return f.Name() + return fn } diff --git a/pkg/osutil/osutil.go b/pkg/osutil/osutil.go index 6f06fb4a4..a1d65e835 100644 --- a/pkg/osutil/osutil.go +++ b/pkg/osutil/osutil.go @@ -141,6 +141,17 @@ func WriteExecFile(filename string, data []byte) error { return ioutil.WriteFile(filename, data, DefaultExecPerm) } +// TempFile creates a unique temp filename. +// Note: the file already exists when the function returns. +func TempFile(prefix string) (string, error) { + f, err := ioutil.TempFile("", prefix) + if err != nil { + return "", fmt.Errorf("failed to create temp file: %v", err) + } + f.Close() + return f.Name(), nil +} + // Return all files in a directory. func ListDir(dir string) ([]string, error) { f, err := os.Open(dir) diff --git a/sys/syz-extract/fetch.go b/sys/syz-extract/fetch.go index 47b6db8d3..db37fe4ab 100644 --- a/sys/syz-extract/fetch.go +++ b/sys/syz-extract/fetch.go @@ -6,7 +6,6 @@ package main import ( "bytes" "fmt" - "io/ioutil" "os" "regexp" "strconv" @@ -98,39 +97,26 @@ type CompileData struct { } func compile(cc string, args []string, data *CompileData) (bin string, out []byte, err error) { - srcFile, err := ioutil.TempFile("", "") - if err != nil { - return "", nil, fmt.Errorf("failed to create temp file: %v", err) - } - srcFile.Close() - os.Remove(srcFile.Name()) - srcName := srcFile.Name() + ".c" - defer os.Remove(srcName) src := new(bytes.Buffer) if err := srcTemplate.Execute(src, data); err != nil { return "", nil, fmt.Errorf("failed to generate source: %v", err) } - if err := ioutil.WriteFile(srcName, src.Bytes(), 0600); err != nil { - return "", nil, fmt.Errorf("failed to write source file: %v", err) - } - - binFile, err := ioutil.TempFile("", "") + binFile, err := osutil.TempFile("syz-extract-bin") if err != nil { - return "", nil, fmt.Errorf("failed to create temp file: %v", err) + return "", nil, err } - binFile.Close() - args = append(args, []string{ - srcName, - "-o", binFile.Name(), + "-x", "c", "-", + "-o", binFile, "-w", }...) - out, err = osutil.Command(cc, args...).CombinedOutput() - if err != nil { - os.Remove(binFile.Name()) + cmd := osutil.Command(cc, args...) + cmd.Stdin = src + if out, err := cmd.CombinedOutput(); err != nil { + os.Remove(binFile) return "", out, err } - return binFile.Name(), nil, nil + return binFile, nil, nil } var srcTemplate = template.Must(template.New("").Parse(` -- cgit mrf-deployment