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  }