blob: 64fc864bf8000b1d3bd06b1de6e3135fa4c9c9e9 [file] [log] [blame]
Patrick Williams2390b1b2022-11-03 13:47:49 -05001#
2# SPDX-License-Identifier: MIT
3#
4
5from oeqa.selftest.case import OESelftestTestCase
6from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_bb_vars
7from oeqa.utils.network import get_free_port
8
9class TestSyzkaller(OESelftestTestCase):
10 def setUpSyzkallerConfig(self, os_arch, qemu_postfix):
11 syz_target_sysroot = get_bb_var('PKGD', 'syzkaller')
12 syz_target = os.path.join(syz_target_sysroot, 'usr')
13
14 qemu_native_bin = os.path.join(self.syz_native_sysroot, 'usr/bin/qemu-system-' + qemu_postfix)
15 kernel_cmdline = "ip=dhcp rootfs=/dev/sda dummy_hcd.num=%s" % (self.dummy_hcd_num)
16 kernel_objdir = self.deploy_dir_image
17 port = get_free_port()
18
19 if not os.path.exists(self.syz_workdir):
20 os.mkdir(self.syz_workdir)
21
22 with open(self.syz_cfg, 'w') as f:
23 f.write(
24"""
25{
26 "target": "%s",
27 "http": "127.0.0.1:%s",
28 "workdir": "%s",
29 "kernel_obj": "%s",
30 "kernel_src": "%s",
31 "image": "%s",
32 "syzkaller": "%s",
33 "type": "qemu",
34 "reproduce" : false,
35 "sandbox": "none",
36 "vm": {
37 "count": %s,
38 "kernel": "%s",
39 "cmdline": "%s",
40 "cpu": %s,
41 "mem": %s,
42 "qemu": "%s",
43 "qemu_args": "-device virtio-scsi-pci,id=scsi -device scsi-hd,drive=rootfs -enable-kvm -cpu host,migratable=off",
44 "image_device": "drive index=0,id=rootfs,if=none,media=disk,file="
45 }
46}
47"""
48% (os_arch, port, self.syz_workdir, kernel_objdir, self.kernel_src,
49 self.rootfs, syz_target, self.syz_qemu_vms, self.kernel, kernel_cmdline,
50 self.syz_qemu_cpus, self.syz_qemu_mem, qemu_native_bin))
51
52 def test_syzkallerFuzzingQemux86_64(self):
53 self.image = 'core-image-minimal'
54 self.machine = 'qemux86-64'
55 self.fstype = "ext4"
56
57 self.write_config(
58"""
59MACHINE = "%s"
60IMAGE_FSTYPES = "%s"
61KERNEL_IMAGETYPES += "vmlinux"
62EXTRA_IMAGE_FEATURES += " ssh-server-openssh"
63IMAGE_ROOTFS_EXTRA_SPACE = "512000"
64KERNEL_EXTRA_FEATURES += " \
65 cfg/debug/syzkaller/debug-syzkaller.scc \
66"
67IMAGE_INSTALL:append = " syzkaller"
68"""
69% (self.machine, self.fstype))
70
71 build_vars = ['TOPDIR', 'DEPLOY_DIR_IMAGE', 'STAGING_KERNEL_DIR']
72 syz_fuzz_vars = ['SYZ_WORKDIR', 'SYZ_FUZZTIME', 'SYZ_QEMU_MEM', 'SYZ_QEMU_CPUS', 'SYZ_QEMU_VM_COUNT']
73 syz_aux_vars = ['SYZ_DUMMY_HCD_NUM']
74
75 needed_vars = build_vars + syz_fuzz_vars + syz_aux_vars
76 bb_vars = get_bb_vars(needed_vars)
77
78 for var in syz_fuzz_vars:
79 if not bb_vars[var]:
80 self.skipTest(
81"""
82%s variable not set.
83Please configure %s fuzzing parameters to run this test.
84
85Example local.conf config:
86SYZ_WORKDIR="<path>" # syzkaller workdir location (must be persistent across os-selftest runs)
87SYZ_FUZZTIME="30" # fuzzing time in minutes
88SYZ_QEMU_VM_COUNT="1" # number of qemu VMs to be used for fuzzing
89SYZ_QEMU_MEM="2048"' # memory used by each qemu VM
90SYZ_QEMU_CPUS="2"' # number of cpus used by each qemu VM
91"""
92% (var, ', '.join(syz_fuzz_vars)))
93
94 self.topdir = bb_vars['TOPDIR']
95 self.deploy_dir_image = bb_vars['DEPLOY_DIR_IMAGE']
96 self.kernel_src = bb_vars['STAGING_KERNEL_DIR']
97
98 """
99 SYZ_WORKDIR must be set to an absolute path where syzkaller will store
100 the corpus database, config, runtime and crash data generated during
101 fuzzing. It must be persistent between oe-selftest runs, so the fuzzer
102 does not start over again on each run.
103 """
104 self.syz_workdir = bb_vars['SYZ_WORKDIR']
105 self.syz_fuzztime = int(bb_vars['SYZ_FUZZTIME']) * 60
106 self.syz_qemu_mem = int(bb_vars['SYZ_QEMU_MEM'])
107 self.syz_qemu_cpus = int(bb_vars['SYZ_QEMU_CPUS'])
108 self.syz_qemu_vms = int(bb_vars['SYZ_QEMU_VM_COUNT'])
109 self.dummy_hcd_num = int(bb_vars['SYZ_DUMMY_HCD_NUM'] or 8)
110
111 self.syz_cfg = os.path.join(self.syz_workdir, 'syzkaller.cfg')
112 self.kernel = os.path.join(self.deploy_dir_image, 'bzImage')
113 self.rootfs = os.path.join(self.deploy_dir_image, '%s-%s.%s' % (self.image, self.machine, self.fstype))
114
115 self.syz_native_sysroot = get_bb_var('RECIPE_SYSROOT_NATIVE', 'syzkaller-native')
116
117 self.setUpSyzkallerConfig("linux/amd64", "x86_64")
118
119 bitbake(self.image)
120 bitbake('syzkaller')
121 bitbake('syzkaller-native -c addto_recipe_sysroot')
122
123 cmd = "syz-manager -config %s" % self.syz_cfg
124 runCmd(cmd, native_sysroot = self.syz_native_sysroot, timeout=self.syz_fuzztime, output_log=self.logger, ignore_status=True, shell=True)