Skip to content

Commit

Permalink
syzbot-repro.ktest: Run syzbot reproducers in a single command
Browse files Browse the repository at this point in the history
Example usage, to reproduce locally the bug https://syzkaller.appspot.com/bug?extid=f074d2e31d8d35a6a38c
  build-test-kernel run -I ~/ktest/tests/syzbot-repro.ktest f074d2e31d8d35a6a38c
or, with an optionl crash index:
  build-test-kernel run -I ~/ktest/tests/syzbot-repro.ktest f074d2e31d8d35a6a38c 3

The syzbot-get tool needs to first be built and installed, run
  cargo install --path "path to ktest"

Signed-off-by: Kent Overstreet <[email protected]>
  • Loading branch information
Kent Overstreet committed Nov 7, 2024
1 parent e1001fe commit 3c30e50
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 2 deletions.
6 changes: 5 additions & 1 deletion build-test-kernel
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,11 @@ build_kernel()
mv "$kconfig" "$kconfig".bak
fi

new_config
if [[ -z $ktest_kconfig_base ]]; then
new_config
else
cp "$ktest_kconfig_base" "$kconfig"
fi

log_verbose "kernel_config_require: ${ktest_kernel_config_require[@]} ${ktest_kernel_config_require_soft[@]}"

Expand Down
4 changes: 3 additions & 1 deletion lib/parse-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
parse_test_deps()
{
export ktest_crashdump
eval $("$ktest_test" deps)
export ktest_out

eval $( "$ktest_test" deps $ktest_testargs )

parse_arch "$ktest_arch"

Expand Down
91 changes: 91 additions & 0 deletions src/bin/syzbot-get.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
use std::path::PathBuf;
use clap::Parser;
use serde_derive::Deserialize;

#[derive(Parser)]
#[command(author, version, about, long_about = None)]
struct Args {
#[arg(short, long)]
id: String,
#[arg(short, long)]
idx: Option<usize>,
#[arg(short, long)]
output: PathBuf,
#[arg(short, long)]
verbose: bool,
}

#[allow(dead_code)]
#[derive(Deserialize, Debug)]
struct SyzCrash {
title: String,
#[serde(rename = "syz-reproducer")]
syz_reproducer: Option<String>,
#[serde(rename = "c-reproducer")]
c_reproducer: Option<String>,
#[serde(rename = "kernel-config")]
kernel_config: String,
#[serde(rename = "kernel-source-git")]
kernel_source_git: String,
#[serde(rename = "kernel-source-commit")]
kernel_source_commit: String,
#[serde(rename = "syzkaller-git")]
syzkaller_git: String,
#[serde(rename = "syzkaller-commit")]
syzkaller_commit: String,
#[serde(rename = "crash-report-link")]
crash_report_link: String,
}

#[allow(dead_code)]
#[derive(Deserialize, Debug)]
struct SyzBug {
version: usize,
title: String,
id: String,
discussions: Vec<String>,
crashes: Vec<SyzCrash>,
}

fn get_syz_url(url: &String) -> String {
let url = format!("https://syzkaller.appspot.com{}", url);
reqwest::blocking::get(url).unwrap().text().unwrap()
}

fn fetch_syz_url(args: &Args, url: &String, fname: &String) {
let fname = args.output.join(fname);
if !fname.exists() {
if args.verbose { eprintln!("fetching {} => {:?}", &url, &fname); }

std::fs::write(fname, get_syz_url(url)).ok();
} else {
if args.verbose { eprintln!("have {} => {:?}", &url, &fname); }
}
}

fn fetch_syz_crash(args: &Args, crash: &SyzCrash, idx: usize) {
fetch_syz_url(&args, &crash.kernel_config, &format!("{}.{}.kconfig", args.id, idx));

if let Some(r) = &crash.c_reproducer.as_ref() {
fetch_syz_url(&args, r, &format!("{}.{}.repro.c", args.id, idx));
}
}

fn main() {
let args = Args::parse();

let bug_json = get_syz_url(&format!("/bug?json=1&extid={}", args.id));
let bug: SyzBug = serde_json::from_str(&bug_json).unwrap();

if args.verbose { eprintln!("{:?}", &bug); }

std::fs::create_dir_all(&args.output).ok();

if let Some(idx) = args.idx {
fetch_syz_crash(&args, &bug.crashes[idx], idx);
} else {
for (idx, crash) in bug.crashes.iter().enumerate() {
fetch_syz_crash(&args, &crash, idx);
}
}
}
3 changes: 3 additions & 0 deletions tests/prelude.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ if [[ ! -v ktest_cpus ]]; then
ktest_qemu_append=()
ktest_compiler=gcc
ktest_allow_taint=false

ktest_tests_unknown=false
ktest_kconfig_base=

BUILD_ON_HOST=""
fi
Expand Down Expand Up @@ -355,6 +357,7 @@ main()
echo "ktest_qemu_append=(${ktest_qemu_append[@]})"
echo "ktest_allow_taint=$ktest_allow_taint"
echo "ktest_tests_unknown=$ktest_tests_unknown"
echo "ktest_kconfig_base=$ktest_kconfig_base"
;;
init)
create_ktest_user
Expand Down
34 changes: 34 additions & 0 deletions tests/syzbot-repro.ktest
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/usr/bin/env bash
#
# Run syzbot reproducers:
#
# Example usage, to reproduce locally the bug https://syzkaller.appspot.com/bug?extid=f074d2e31d8d35a6a38c
# build-test-kernel run -I ~/ktest/tests/syzbot-repro.ktest f074d2e31d8d35a6a38c
# or, with an optionl crash index:
# build-test-kernel run -I ~/ktest/tests/syzbot-repro.ktest f074d2e31d8d35a6a38c 3
#
# The syzbot-get tool first needs to be built and installed, run
# cargo install --path "path to ktest"

. $(dirname $(readlink -e "${BASH_SOURCE[0]}"))/test-libs.sh

ktest_tests_unknown=true

if [[ $1 == "deps" ]]; then
syz_id=$2
crash_idx=${3:-"0"}

syzbot-get --output "$ktest_out/syzbot" --id $syz_id --idx $crash_idx
ktest_kconfig_base="$ktest_out/syzbot/$syz_id.$crash_idx.kconfig"
fi

run_test()
{
syz_id=$1
crash_idx=${2:-"0"}

gcc -O2 -Wall -o /tmp/syz-repro "$ktest_out/syzbot/$syz_id.$crash_idx.repro.c"
/tmp/syz-repro
}

main "$@"

0 comments on commit 3c30e50

Please sign in to comment.