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