aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-06-21 17:58:12 +0200
committerDmitry Vyukov <dvyukov@google.com>2018-06-22 16:40:45 +0200
commitc97f0d7a863bbb63de5dca44ad75c5ae7b4a154d (patch)
tree75f9f638714eaab50b73250bdceadd860e48556b
parent91f52697d10d451839cd60ffcd6323e99af14011 (diff)
pkg/build: add gvisor support
-rw-r--r--pkg/build/gvisor.go19
-rw-r--r--pkg/osutil/osutil.go21
-rw-r--r--syz-ci/manager.go45
-rw-r--r--syz-ci/syzupdater.go6
4 files changed, 63 insertions, 28 deletions
diff --git a/pkg/build/gvisor.go b/pkg/build/gvisor.go
index 8649e7e65..b96d55cf0 100644
--- a/pkg/build/gvisor.go
+++ b/pkg/build/gvisor.go
@@ -3,13 +3,32 @@
package build
+import (
+ "path/filepath"
+ "time"
+
+ "github.com/google/syzkaller/pkg/osutil"
+)
+
type gvisor struct{}
func (gvisor) build(targetArch, vmType, kernelDir, outputDir, compiler, userspaceDir,
cmdlineFile, sysctlFile string, config []byte) error {
+ if err := osutil.MkdirAll(outputDir); err != nil {
+ return err
+ }
+ if _, err := osutil.RunCmd(20*time.Minute, kernelDir, compiler, "build", "--verbose_failures", "--sandbox_debug", "runsc"); err != nil {
+ return err
+ }
+ runsc := filepath.Join(kernelDir, "bazel-bin", "runsc", "linux_amd64_pure_stripped", "runsc")
+ if err := osutil.CopyFile(runsc, filepath.Join(outputDir, "image")); err != nil {
+ return err
+ }
+ osutil.RunCmd(10*time.Minute, kernelDir, compiler, "shutdown")
return nil
}
func (gvisor) clean(kernelDir string) error {
+ // Let's assume that bazel always properly handles build without cleaning (until proven otherwise).
return nil
}
diff --git a/pkg/osutil/osutil.go b/pkg/osutil/osutil.go
index e41ad7ec1..42b65d36a 100644
--- a/pkg/osutil/osutil.go
+++ b/pkg/osutil/osutil.go
@@ -89,8 +89,11 @@ func IsExist(name string) bool {
// FilesExist returns true if all files exist in dir.
// Files are assumed to be relative names in slash notation.
-func FilesExist(dir string, files []string) bool {
- for _, f := range files {
+func FilesExist(dir string, files map[string]bool) bool {
+ for f, required := range files {
+ if !required {
+ continue
+ }
if !IsExist(filepath.Join(dir, filepath.FromSlash(f))) {
return false
}
@@ -101,7 +104,7 @@ func FilesExist(dir string, files []string) bool {
// CopyFiles copies files from srcDir to dstDir as atomically as possible.
// Files are assumed to be relative names in slash notation.
// All other files in dstDir are removed.
-func CopyFiles(srcDir, dstDir string, files []string) error {
+func CopyFiles(srcDir, dstDir string, files map[string]bool) error {
// Linux does not support atomic dir replace, so we copy to tmp dir first.
// Then remove dst dir and rename tmp to dst (as atomic as can get on Linux).
tmpDir := dstDir + ".tmp"
@@ -111,8 +114,11 @@ func CopyFiles(srcDir, dstDir string, files []string) error {
if err := MkdirAll(tmpDir); err != nil {
return err
}
- for _, f := range files {
+ for f, required := range files {
src := filepath.Join(srcDir, filepath.FromSlash(f))
+ if !required && !IsExist(src) {
+ continue
+ }
dst := filepath.Join(tmpDir, filepath.FromSlash(f))
if err := MkdirAll(filepath.Dir(dst)); err != nil {
return err
@@ -130,15 +136,18 @@ func CopyFiles(srcDir, dstDir string, files []string) error {
// LinkFiles creates hard links for files from dstDir to srcDir.
// Files are assumed to be relative names in slash notation.
// All other files in dstDir are removed.
-func LinkFiles(srcDir, dstDir string, files []string) error {
+func LinkFiles(srcDir, dstDir string, files map[string]bool) error {
if err := os.RemoveAll(dstDir); err != nil {
return err
}
if err := MkdirAll(dstDir); err != nil {
return err
}
- for _, f := range files {
+ for f, required := range files {
src := filepath.Join(srcDir, filepath.FromSlash(f))
+ if !required && !IsExist(src) {
+ continue
+ }
dst := filepath.Join(dstDir, filepath.FromSlash(f))
if err := MkdirAll(filepath.Dir(dst)); err != nil {
return err
diff --git a/syz-ci/manager.go b/syz-ci/manager.go
index fe9808dd2..e487c35f8 100644
--- a/syz-ci/manager.go
+++ b/syz-ci/manager.go
@@ -30,12 +30,12 @@ import (
const kernelRebuildPeriod = syzkallerRebuildPeriod + time.Hour
// List of required files in kernel build (contents of latest/current dirs).
-var imageFiles = []string{
- "tag", // serialized BuildInfo
- "kernel.config", // kernel config used for build
- "image", // kernel image
- "key", // root ssh key for the image
- "obj/vmlinux", // vmlinux with debug info
+var imageFiles = map[string]bool{
+ "tag": true, // serialized BuildInfo
+ "kernel.config": false, // kernel config used for build
+ "image": true, // kernel image
+ "key": false, // root ssh key for the image
+ "obj/vmlinux": false, // vmlinux with debug info
}
// Manager represents a single syz-manager instance.
@@ -52,6 +52,7 @@ type Manager struct {
compilerID string
syzkallerCommit string
configTag string
+ configData []byte
cfg *Config
mgrcfg *ManagerConfig
managercfg *mgrconfig.Config
@@ -79,9 +80,11 @@ func createManager(cfg *Config, mgrcfg *ManagerConfig, stop chan struct{}) *Mana
if err != nil {
log.Fatal(err)
}
- configData, err := ioutil.ReadFile(mgrcfg.KernelConfig)
- if err != nil {
- log.Fatal(err)
+ var configData []byte
+ if mgrcfg.KernelConfig != "" {
+ if configData, err = ioutil.ReadFile(mgrcfg.KernelConfig); err != nil {
+ log.Fatal(err)
+ }
}
syzkallerCommit, _ := readTag(filepath.FromSlash("syzkaller/current/tag"))
if syzkallerCommit == "" {
@@ -105,6 +108,7 @@ func createManager(cfg *Config, mgrcfg *ManagerConfig, stop chan struct{}) *Mana
compilerID: compilerID,
syzkallerCommit: syzkallerCommit,
configTag: hash.String(configData),
+ configData: configData,
cfg: cfg,
mgrcfg: mgrcfg,
managercfg: managercfg,
@@ -263,16 +267,12 @@ func (mgr *Manager) build() error {
if err := osutil.MkdirAll(tmpDir); err != nil {
return fmt.Errorf("failed to create tmp dir: %v", err)
}
- kernelConfigData, err := ioutil.ReadFile(mgr.mgrcfg.KernelConfig)
- if err != nil {
- return err
- }
if err := config.SaveFile(filepath.Join(tmpDir, "tag"), info); err != nil {
return fmt.Errorf("failed to write tag file: %v", err)
}
if err := build.Image(mgr.managercfg.TargetOS, mgr.managercfg.TargetVMArch, mgr.managercfg.Type,
mgr.kernelDir, tmpDir, mgr.mgrcfg.Compiler, mgr.mgrcfg.Userspace,
- mgr.mgrcfg.KernelCmdline, mgr.mgrcfg.KernelSysctl, kernelConfigData); err != nil {
+ mgr.mgrcfg.KernelCmdline, mgr.mgrcfg.KernelSysctl, mgr.configData); err != nil {
if _, ok := err.(build.KernelBuildError); ok {
rep := &report.Report{
Title: fmt.Sprintf("%v build error", mgr.mgrcfg.RepoAlias),
@@ -420,7 +420,9 @@ func (mgr *Manager) createTestConfig(imageDir string, info *BuildInfo) (*mgrconf
mgrcfg.Tag = info.KernelCommit
mgrcfg.Workdir = filepath.Join(imageDir, "workdir")
mgrcfg.Image = filepath.Join(imageDir, "image")
- mgrcfg.SSHKey = filepath.Join(imageDir, "key")
+ if keyFile := filepath.Join(imageDir, "key"); osutil.IsExist(keyFile) {
+ mgrcfg.SSHKey = keyFile
+ }
mgrcfg.KernelObj = filepath.Join(imageDir, "obj")
mgrcfg.KernelSrc = mgr.kernelDir
if err := mgrconfig.Complete(mgrcfg); err != nil {
@@ -451,7 +453,9 @@ func (mgr *Manager) writeConfig(buildTag string) (string, error) {
// problems, we need to make a copy of sources after build.
mgrcfg.KernelSrc = mgr.kernelDir
mgrcfg.Image = filepath.Join(mgr.currentDir, "image")
- mgrcfg.SSHKey = filepath.Join(mgr.currentDir, "key")
+ if keyFile := filepath.Join(mgr.currentDir, "key"); osutil.IsExist(keyFile) {
+ mgrcfg.SSHKey = keyFile
+ }
if err := mgrconfig.Complete(mgrcfg); err != nil {
return "", fmt.Errorf("bad manager config: %v", err)
}
@@ -490,9 +494,12 @@ func (mgr *Manager) uploadBuild(info *BuildInfo, imageDir string) (string, error
}
func (mgr *Manager) createDashboardBuild(info *BuildInfo, imageDir, typ string) (*dashapi.Build, error) {
- kernelConfig, err := ioutil.ReadFile(filepath.Join(imageDir, "kernel.config"))
- if err != nil {
- return nil, fmt.Errorf("failed to read kernel.config: %v", err)
+ var kernelConfig []byte
+ if kernelConfigFile := filepath.Join(imageDir, "kernel.config"); osutil.IsExist(kernelConfigFile) {
+ var err error
+ if kernelConfig, err = ioutil.ReadFile(kernelConfigFile); err != nil {
+ return nil, fmt.Errorf("failed to read kernel.config: %v", err)
+ }
}
// Resulting build depends on both kernel build tag and syzkaller commmit.
// Also mix in build type, so that image error builds are not merged into normal builds.
diff --git a/syz-ci/syzupdater.go b/syz-ci/syzupdater.go
index 4df6337ff..d1f9842ef 100644
--- a/syz-ci/syzupdater.go
+++ b/syz-ci/syzupdater.go
@@ -38,7 +38,7 @@ type SyzUpdater struct {
syzkallerDir string
latestDir string
currentDir string
- syzFiles []string
+ syzFiles map[string]bool
targets map[string]bool
}
@@ -82,9 +82,9 @@ func NewSyzUpdater(cfg *Config) *SyzUpdater {
files[fmt.Sprintf("bin/%v_%v/syz-execprog", os, vmarch)] = true
files[fmt.Sprintf("bin/%v_%v/syz-executor", os, arch)] = true
}
- var syzFiles []string
+ syzFiles := make(map[string]bool)
for f := range files {
- syzFiles = append(syzFiles, f)
+ syzFiles[f] = true
}
return &SyzUpdater{