1// Copyright 2018 syzkaller project authors. All rights reserved. 2// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. 3 4package build 5 6import ( 7 "fmt" 8 "os" 9 "path/filepath" 10 "runtime" 11 "strconv" 12 "time" 13 14 "github.com/google/syzkaller/pkg/osutil" 15) 16 17type akaros struct{} 18 19func (ctx akaros) build(targetArch, vmType, kernelDir, outputDir, compiler, userspaceDir, 20 cmdlineFile, sysctlFile string, config []byte) error { 21 configFile := filepath.Join(kernelDir, ".config") 22 if err := osutil.WriteFile(configFile, config); err != nil { 23 return fmt.Errorf("failed to write config file: %v", err) 24 } 25 if err := osutil.SandboxChown(configFile); err != nil { 26 return err 27 } 28 sshkey := filepath.Join(kernelDir, "key") 29 sshkeyPub := sshkey + ".pub" 30 os.Remove(sshkey) 31 os.Remove(sshkeyPub) 32 if _, err := osutil.RunCmd(10*time.Minute, "", "ssh-keygen", "-t", "rsa", "-b", "2048", 33 "-N", "", "-C", "", "-f", sshkey); err != nil { 34 return err 35 } 36 if err := osutil.SandboxChown(sshkeyPub); err != nil { 37 return err 38 } 39 if err := ctx.make(kernelDir, "", "olddefconfig", "ARCH=x86"); err != nil { 40 return err 41 } 42 if err := ctx.make(kernelDir, "", "xcc"); err != nil { 43 return err 44 } 45 if err := ctx.make(kernelDir, "tools/dev-libs/elfutils", "install"); err != nil { 46 return err 47 } 48 if err := ctx.make(kernelDir, "", "apps-install"); err != nil { 49 return err 50 } 51 if err := ctx.make(kernelDir, "", "fill-kfs"); err != nil { 52 return err 53 } 54 targetKey := filepath.Join(kernelDir, "kern", "kfs", ".ssh", "authorized_keys") 55 if err := os.Rename(sshkeyPub, targetKey); err != nil { 56 return err 57 } 58 const init = `#!/bin/bash 59/ifconfig 60dropbear -F 2>db_out & 61bash 62` 63 initFile := filepath.Join(kernelDir, "kern", "kfs", "init.sh") 64 if err := osutil.WriteFile(initFile, []byte(init)); err != nil { 65 return fmt.Errorf("failed to write init script: %v", err) 66 } 67 if err := osutil.SandboxChown(initFile); err != nil { 68 return err 69 } 70 if err := os.Chmod(initFile, 0770); err != nil { 71 return err 72 } 73 if err := ctx.cmd(kernelDir, "dropbear", "./CONFIGURE_AKAROS"); err != nil { 74 return err 75 } 76 if err := ctx.make(kernelDir, "dropbear/build"); err != nil { 77 return err 78 } 79 if err := ctx.make(kernelDir, "dropbear/build", "install"); err != nil { 80 return err 81 } 82 if err := ctx.make(kernelDir, ""); err != nil { 83 return err 84 } 85 if err := osutil.WriteFile(filepath.Join(outputDir, "image"), nil); err != nil { 86 return fmt.Errorf("failed to write image file: %v", err) 87 } 88 for src, dst := range map[string]string{ 89 ".config": "kernel.config", 90 "key": "key", 91 "obj/kern/akaros-kernel": "kernel", 92 "obj/kern/akaros-kernel-64b": "obj/akaros-kernel-64b", 93 } { 94 fullSrc := filepath.Join(kernelDir, filepath.FromSlash(src)) 95 fullDst := filepath.Join(outputDir, filepath.FromSlash(dst)) 96 if err := osutil.CopyFile(fullSrc, fullDst); err != nil { 97 return fmt.Errorf("faied to copy %v: %v", src, err) 98 } 99 } 100 return nil 101} 102 103func (ctx akaros) clean(kernelDir string) error { 104 // Note: this does not clean toolchain and elfutils. 105 return ctx.make(kernelDir, "", "realclean") 106} 107 108func (ctx akaros) make(kernelDir, runDir string, args ...string) error { 109 args = append([]string{"-j", strconv.Itoa(runtime.NumCPU())}, args...) 110 return ctx.cmd(kernelDir, runDir, "make", args...) 111} 112 113func (ctx akaros) cmd(kernelDir, runDir string, bin string, args ...string) error { 114 cmd := osutil.Command(bin, args...) 115 if err := osutil.Sandbox(cmd, true, false); err != nil { 116 return err 117 } 118 cmd.Dir = kernelDir 119 if runDir != "" { 120 cmd.Dir = filepath.Join(kernelDir, filepath.FromSlash(runDir)) 121 } 122 cmd.Env = append([]string{}, os.Environ()...) 123 cmd.Env = append(cmd.Env, []string{ 124 "MAKE_JOBS=" + strconv.Itoa(runtime.NumCPU()), 125 "AKAROS_ROOT=" + kernelDir, 126 "AKAROS_XCC_ROOT=" + filepath.Join(kernelDir, "toolchain", "x86_64-ucb-akaros-gcc"), 127 "X86_64_INSTDIR=" + filepath.Join(kernelDir, "toolchain", "x86_64-ucb-akaros-gcc"), 128 "PATH=" + filepath.Join(kernelDir, "toolchain", "x86_64-ucb-akaros-gcc", "bin") + 129 string(filepath.ListSeparator) + os.Getenv("PATH"), 130 }...) 131 _, err := osutil.Run(time.Hour, cmd) 132 return err 133} 134