github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/pkg/build/freebsd.go (about) 1 // Copyright 2019 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 4 package build 5 6 import ( 7 "fmt" 8 "path/filepath" 9 "runtime" 10 "strconv" 11 "strings" 12 "time" 13 14 "github.com/google/syzkaller/pkg/osutil" 15 ) 16 17 type freebsd struct{} 18 19 func (ctx freebsd) build(params Params) (ImageDetails, error) { 20 confDir := fmt.Sprintf("%v/sys/%v/conf/", params.KernelDir, params.TargetArch) 21 confFile := "SYZKALLER" 22 23 config := params.Config 24 if config == nil { 25 config = []byte(` 26 include "./GENERIC" 27 28 ident SYZKALLER 29 options COVERAGE 30 options KCOV 31 options KASAN 32 33 options TCPHPTS 34 options RATELIMIT 35 36 options DEBUG_VFS_LOCKS 37 options DIAGNOSTIC 38 `) 39 } 40 if err := osutil.WriteFile(filepath.Join(confDir, confFile), config); err != nil { 41 return ImageDetails{}, err 42 } 43 44 if _, err := osutil.RunCmd(10*time.Minute, params.KernelDir, "rm", "-rf", "obj"); err != nil { 45 return ImageDetails{}, err 46 } 47 objPrefix := filepath.Join(params.KernelDir, "obj") 48 output, err := ctx.make(params.KernelDir, objPrefix, "kernel-toolchain") 49 if err != nil { 50 return ImageDetails{}, err 51 } 52 if _, err := ctx.make(params.KernelDir, objPrefix, "buildkernel", "WITH_EXTRA_TCP_STACKS=", 53 fmt.Sprintf("KERNCONF=%v", confFile)); err != nil { 54 // The kernel-toolchain make target has to be built separately 55 // because FreeBSD's build doesn't correctly order the two 56 // targets. Its output is useful for debugging though, so 57 // include it here. 58 return ImageDetails{}, osutil.PrependContext(string(output), err) 59 } 60 61 kernelObjDir := filepath.Join(objPrefix, params.KernelDir, 62 fmt.Sprintf("%v.%v", params.TargetArch, params.TargetArch), "sys", confFile) 63 for _, s := range []struct{ dir, src, dst string }{ 64 {params.UserspaceDir, "image", "image"}, 65 {params.UserspaceDir, "key", "key"}, 66 {kernelObjDir, "kernel.full", "obj/kernel.full"}, 67 } { 68 fullSrc := filepath.Join(s.dir, s.src) 69 fullDst := filepath.Join(params.OutputDir, s.dst) 70 if err := osutil.CopyFile(fullSrc, fullDst); err != nil { 71 return ImageDetails{}, fmt.Errorf("failed to copy %v -> %v: %w", fullSrc, fullDst, err) 72 } 73 } 74 75 script := fmt.Sprintf(` 76 set -eux 77 md=$(sudo mdconfig -a -t vnode image) 78 partn=$(gpart show /dev/${md} | awk '/freebsd-ufs/{print $3}' | head -n 1) 79 tmpdir=$(mktemp -d) 80 sudo mount /dev/${md}p${partn} $tmpdir 81 82 sudo MAKEOBJDIRPREFIX=%s make -C %s installkernel WITH_EXTRA_TCP_STACKS= KERNCONF=%s DESTDIR=$tmpdir 83 84 cat | sudo tee ${tmpdir}/boot/loader.conf.local <<__EOF__ 85 ipsec_load="YES" 86 pf_load="YES" 87 sctp_load="YES" 88 tcp_bbr_load="YES" 89 tcp_rack_load="YES" 90 sem_load="YES" 91 mqueuefs_load="YES" 92 cryptodev_load="YES" 93 cc_cdg_load="YES" 94 cc_chd_load="YES" 95 cc_cubic_load="YES" 96 cc_dctcp_load="YES" 97 cc_hd_load="YES" 98 cc_htcp_load="YES" 99 cc_vegas_load="YES" 100 filemon_load="YES" 101 102 kern.ipc.tls.enable="1" 103 vm.panic_on_oom="1" 104 __EOF__ 105 106 cat | sudo tee -a ${tmpdir}/etc/sysctl.conf <<__EOF__ 107 net.inet.sctp.udp_tunneling_port=9899 108 net.inet.tcp.udp_tunneling_port=9811 109 vm.redzone.panic=1 110 __EOF__ 111 112 sudo umount $tmpdir 113 sudo mdconfig -d -u ${md#md} 114 `, objPrefix, params.KernelDir, confFile) 115 116 if debugOut, err := osutil.RunCmd(10*time.Minute, params.OutputDir, "/bin/sh", "-c", script); err != nil { 117 return ImageDetails{}, fmt.Errorf("error copying kernel: %w\n%v", err, debugOut) 118 } 119 return ImageDetails{}, nil 120 } 121 122 func (ctx freebsd) clean(kernelDir, targetArch string) error { 123 objPrefix := filepath.Join(kernelDir, "obj") 124 _, err := ctx.make(kernelDir, objPrefix, "cleanworld") 125 return err 126 } 127 128 func (ctx freebsd) make(kernelDir, objPrefix string, makeArgs ...string) ([]byte, error) { 129 args := append([]string{ 130 fmt.Sprintf("MAKEOBJDIRPREFIX=%v", objPrefix), 131 "make", 132 "-C", kernelDir, 133 "-j", strconv.Itoa(runtime.NumCPU()), 134 }, makeArgs...) 135 output, err := osutil.RunCmd(3*time.Hour, kernelDir, "sh", "-c", strings.Join(args, " ")) 136 return output, err 137 }