// 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 build import ( "fmt" "path/filepath" "strconv" "time" "github.com/google/syzkaller/pkg/osutil" ) type openbsd struct{} func (ctx openbsd) build(params Params) (ImageDetails, error) { const kernelName = "SYZKALLER" confDir := fmt.Sprintf("%v/sys/arch/%v/conf", params.KernelDir, params.TargetArch) compileDir := fmt.Sprintf("%v/sys/arch/%v/compile/%v", params.KernelDir, params.TargetArch, kernelName) if err := osutil.WriteFile(filepath.Join(confDir, kernelName), params.Config); err != nil { return ImageDetails{}, err } if err := osutil.MkdirAll(compileDir); err != nil { return ImageDetails{}, err } makefile := []byte(".include \"../Makefile.inc\"\n") if err := osutil.WriteFile(filepath.Join(compileDir, "Makefile"), makefile); err != nil { return ImageDetails{}, err } for _, tgt := range []string{"clean", "obj", "config", "all"} { if err := ctx.make(compileDir, params.BuildCPUs, tgt); err != nil { return ImageDetails{}, err } } for _, s := range []struct{ dir, src, dst string }{ {compileDir, "obj/bsd", "kernel"}, {compileDir, "obj/bsd.gdb", "obj/bsd.gdb"}, {params.UserspaceDir, "image", "image"}, {params.UserspaceDir, "key", "key"}, } { fullSrc := filepath.Join(s.dir, s.src) fullDst := filepath.Join(params.OutputDir, s.dst) if err := osutil.CopyFile(fullSrc, fullDst); err != nil { return ImageDetails{}, fmt.Errorf("failed to copy %v -> %v: %w", fullSrc, fullDst, err) } } if params.VMType == "gce" { return ImageDetails{}, ctx.copyFilesToImage( filepath.Join(params.UserspaceDir, "overlay"), params.OutputDir) } return ImageDetails{}, nil } func (ctx openbsd) clean(params Params) error { // Building clean is fast enough and incremental builds in face of // changing config files don't work. Instead of optimizing for the // case where humans have to think, let's bludgeon it with a // machine. return nil } func (ctx openbsd) make(kernelDir string, jobs int, args ...string) error { args = append([]string{"-j", strconv.Itoa(jobs)}, args...) _, err := osutil.RunCmd(10*time.Minute, kernelDir, "make", args...) return err } // copyFilesToImage populates the filesystem image in outputDir with // run-specific files. The kernel is copied as /bsd and if overlayDir // exists, its contents are copied into corresponding files in the // image. // // Ideally a user space tool capable of understanding FFS should // interpret FFS inside the image file, but vnd(4) device would do in // a pinch. func (ctx openbsd) copyFilesToImage(overlayDir, outputDir string) error { script := fmt.Sprintf(`set -eux OVERLAY="%s" # Cleanup in case something failed before. sync doas umount /altroot || true doas vnconfig -u vnd0 || true doas /sbin/vnconfig vnd0 image doas mount /dev/vnd0a /altroot doas cp kernel /altroot/bsd test -d "$OVERLAY" && doas cp -Rf "$OVERLAY"/. /altroot sync doas umount /altroot doas vnconfig -u vnd0 `, overlayDir) _, err := osutil.RunCmd(10*time.Minute, outputDir, "/bin/sh", "-c", script) return err }