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  }