Skip to content
Permalink
Browse files

Add syzkaller testcase

This adds a syzkaller fuzzing testcase for powerpc
and it does the below steps
    1. Install/Setup syzkaller in host
    2. Setup Guest for passwordless ssh from host
    3. Prepare and compile Guest kernel
    4. Prepare syzkaller config with qemu params and guest params
    5. Start sykaller with above config and run for specified time(test_timeout)
    6. Test fails out incase of any host issues

More details about syzkaller can be found here https://github.com/google/syzkaller

Signed-off-by: Satheesh Rajendran <sathnaga@linux.vnet.ibm.com>
  • Loading branch information...
sathnaga committed Mar 19, 2019
1 parent 54dba53 commit db186f3b38717bf299e48c0cd6110d9396aed375
Showing with 122 additions and 0 deletions.
  1. +20 −0 generic/tests/cfg/syzkaller.cfg
  2. +102 −0 generic/tests/syzkaller.py
@@ -0,0 +1,20 @@
- syzkaller:
virt_test_type = qemu libvirt
type = syzkaller
# Test runs till the test timeout, make sure to adjust below param
test_timeout = 2000
variants:
- power:
only pseries
verify_guest_dmesg = no
verify_host_dmesg = yes
kernel_args = "root=/dev/sda2 rw console=tty0 console=ttyS0,115200 init=/sbin/init initcall_debug selinux=0"
syz_qemu_args = "-enable-kvm -M pseries -net nic,model=virtio"
syz_kernel_repo = "https://github.com/linuxppc/linux.git"
syz_kernel_branch = "merge"
syz_kernel_config = "ppc64le_guest_defconfig"
syz_target = "linux/ppc64le"
syz_cmd_params = "-debug -v 10"
syz_http = "0.0.0.0:56741"
syz_count = 1
syz_procs = 4
@@ -0,0 +1,102 @@
import os
import json
import time
import shutil

from avocado.utils import software_manager
from avocado.utils import process

from virttest import utils_misc
from virttest import ssh_key
from virttest import storage
from virttest import data_dir


def run(test, params, env):
"""
Setup and run syzkaller (https://github.com/google/syzkaller)
1. Install/Setup syzkaller in host
2. Setup Guest for passwordless ssh from host
3. Prepare and compile Guest kernel
4. Prepare syzkaller config with qemu params and guest params
5. Start sykaller with above config and run for specified time(test_timeout)
6. Test fails out incase of any host issues
"""
start_time = time.time()
# Step 1: Install/Setup syzkaller in host
sm = software_manager.SoftwareManager()
if not sm.check_installed("go") and not sm.install("go"):
test.cancel("golang package install failed")
home = os.environ["HOME"]
if not ("goroot/bin" in os.environ["PATH"] and "go/bin" in os.environ["PATH"]):
process.run('echo "PATH=%s/goroot/bin:%s/go/bin:$PATH" >> %s/.bashrc' % (home, home, home), shell=True)
process.run("source %s/.bashrc" % home, shell=True)
process.run("go get -u -d github.com/google/syzkaller/...", shell=True)
process.run("cd %s/go/src/github.com/google/syzkaller;make" % home, shell=True)
syzkaller_path = "%s/go/src/github.com/google/syzkaller" % home

# Step 2: Setup Guest for passwordless ssh from host
vm = env.get_vm(params["main_vm"])
session = vm.wait_for_login()
ssh_key.setup_ssh_key(vm.get_address(),
params.get("username"),
params.get("password"))
session.close()
vm.destroy()

# Step 3: Prepare Guest kernel
guest_kernel_repo = params.get("syz_kernel_repo")
guest_kernel_branch = params.get("syz_kernel_branch")
guest_kernel_config = params.get("syz_kernel_config")
guest_kernel_build_path = utils_misc.get_path(test.debugdir, "linux")
process.run("git clone --depth 1 %s -b %s %s" % (guest_kernel_repo, guest_kernel_branch, guest_kernel_build_path), shell=True)
process.run("cd %s;git log -1;make %s" % (guest_kernel_build_path, guest_kernel_config), shell=True)
process.run('cd %s; echo "CONFIG_KCOV=y\nCONFIG_GCC_PLUGINS=y" >> .config; make olddefconfig' % guest_kernel_build_path, shell=True)
process.run("cd %s;make -j 40" % guest_kernel_build_path, shell=True)

# Step 4: Prepare syzkaller config with qemu params and guest params
syz_config_path = utils_misc.get_path(test.debugdir, "syzkaller_config")
os.makedirs("%s/syzkaller" % test.debugdir)
workdir = "%s/syzkaller" % test.debugdir
sshkey = "%s/.ssh/id_rsa" % os.environ["HOME"]
kernel_path = "%s/vmlinux" % guest_kernel_build_path

vm_config = {
"count": int(params.get("syz_count")),
"cpu": int(params.get("smp")),
"mem": int(params.get("mem")),
"kernel": kernel_path,
"cmdline": params.get("kernel_args"),
"qemu_args": params.get("syz_qemu_args")
}

syz_config = {
'target': params.get("syz_target"),
'workdir': workdir,
"http": params.get("syz_http"),
"image": storage.get_image_filename(params, data_dir.get_data_dir()),
"syzkaller": syzkaller_path,
"procs": int(params.get("syz_procs")),
"type": "qemu",
"sshkey": sshkey,
"vm": vm_config
}
try:
with open(syz_config_path, "w") as fp:
json.dump(syz_config, fp)
except IOError as err:
test.error("Unable to update syzkaller config: %s", err)
end_time = time.time()
# Step 5: Start sykaller config with specified time
# Let's calculate the syzkaller timeout from
# test timeout excluding current elapsed time + buffer
testtimeout = int(params.get("test_timeout")) - (int(end_time - start_time) + 10)
cmd = "%s/bin/syz-manager -config %s %s" % (syzkaller_path, syz_config_path, params.get("syz_cmd_params"))
process.run(cmd, timeout=testtimeout,
allow_output_check="combined",
ignore_status=True, shell=True)
# Let's delete linux kernel folder from test-results as it would
# consume lot of space and test log have all the information about
# it incase to retrieve it back.
if os.path.isdir(guest_kernel_build_path):
shutil.rmtree(guest_kernel_build_path)

0 comments on commit db186f3

Please sign in to comment.
You can’t perform that action at this time.