Skip to content

Commit

Permalink
Add syzkaller testcase
Browse files Browse the repository at this point in the history
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
Satheesh Rajendran committed Mar 25, 2019
1 parent 2a42a60 commit 34923a4
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 0 deletions.
20 changes: 20 additions & 0 deletions generic/tests/cfg/syzkaller.cfg
@@ -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
102 changes: 102 additions & 0 deletions generic/tests/syzkaller.py
@@ -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)
fp = open(syz_config_path, "w")
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
}

json.dump(syz_config, fp)
fp.close()

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 34923a4

Please sign in to comment.