[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v2 14/15] scripts/oss-fuzz: Add script to reorder a general-f
From: |
Darren Kenny |
Subject: |
Re: [PATCH v2 14/15] scripts/oss-fuzz: Add script to reorder a general-fuzzer trace |
Date: |
Thu, 03 Sep 2020 10:20:35 +0100 |
On Wednesday, 2020-08-19 at 02:11:09 -04, Alexander Bulekov wrote:
> The general-fuzzer uses hooks to fulfill DMA requests just-in-time.
> This means that if we try to use QTEST_LOG=1 to build a reproducer, the
> DMA writes will be logged _after_ the in/out/read/write that triggered
> the DMA read. To work work around this, the general-fuzzer annotates
> these just-in time DMA fulfilments with a tag that we can use to
> discern them. This script simply iterates over a raw qtest
> trace (including log messages, errors, timestamps etc), filters it and
> re-orders it so that DMA fulfillments are placed directly _before_ the
> qtest command that will cause the DMA access.
>
> Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
> ---
> .../oss-fuzz/reorder_fuzzer_qtest_trace.py | 94 +++++++++++++++++++
> 1 file changed, 94 insertions(+)
> create mode 100755 scripts/oss-fuzz/reorder_fuzzer_qtest_trace.py
>
> diff --git a/scripts/oss-fuzz/reorder_fuzzer_qtest_trace.py
> b/scripts/oss-fuzz/reorder_fuzzer_qtest_trace.py
> new file mode 100755
> index 0000000000..9fb7edb6ee
> --- /dev/null
> +++ b/scripts/oss-fuzz/reorder_fuzzer_qtest_trace.py
> @@ -0,0 +1,94 @@
> +#!/usr/bin/env python3
> +# -*- coding: utf-8 -*-
> +
> +"""
> +Use this to convert qtest log info from a generic fuzzer input into a qtest
> +trace that you can feed into a standard qemu-system process. Example usage:
> +
> +QEMU_FUZZ_ARGS="-machine q35,accel=qtest" QEMU_FUZZ_OBJECTS="*" \
> + ./i386-softmmu/qemu-fuzz-i386 --fuzz-target=general-pci-fuzz
> +# .. Finds some crash
> +QTEST_LOG=1 FUZZ_SERIALIZE_QTEST=1 \
> +QEMU_FUZZ_ARGS="-machine q35,accel=qtest" QEMU_FUZZ_OBJECTS="*" \
> + ./i386-softmmu/qemu-fuzz-i386 --fuzz-target=general-pci-fuzz
> + /path/to/crash 2> qtest_log_output
> +scripts/oss-fuzz/reorder_fuzzer_qtest_trace.py qtest_log_output > qtest_trace
> +./i386-softmmu/qemu-fuzz-i386 -machine q35,accel=qtest \
> + -qtest stdin < qtest_trace
> +
> +### Details ###
> +
> +Some fuzzer make use of hooks that allow us to populate some memory range,
> just
> +before a DMA read from that range. This means that the fuzzer can produce
> +activity that looks like:
> + [start] read from mmio addr
> + [end] read from mmio addr
> + [start] write to pio addr
> + [start] fill a DMA buffer just in time
> + [end] fill a DMA buffer just in time
> + [start] fill a DMA buffer just in time
> + [end] fill a DMA buffer just in time
> + [end] write to pio addr
> + [start] read from mmio addr
> + [end] read from mmio addr
> +
> +We annotate these "nested" DMA writes, so with QTEST_LOG=1 the QTest trace
> +might look something like:
> +[R +0.028431] readw 0x10000
> +[R +0.028434] outl 0xc000 0xbeef # Triggers a DMA read from 0xbeef and
> 0xbf00
> +[DMA][R +0.034639] write 0xbeef 0x2 0xAAAA
> +[DMA][R +0.034639] write 0xbf00 0x2 0xBBBB
> +[R +0.028431] readw 0xfc000
> +
> +This script would reorder the above trace so it becomes:
> +readw 0x10000
> +write 0xbeef 0x2 0xAAAA
> +write 0xbf00 0x2 0xBBBB
> +outl 0xc000 0xbeef
> +readw 0xfc000
> +
> +I.e. by the time, 0xc000 tries to read from DMA, those DMA buffers have
> already
> +been set up, removing the need for the DMA hooks. We can simply provide this
> +reordered trace via -qtest stdio to reproduce the input
> +
> +Note: this won't work for traces where the device tries to read from the same
> +DMA region twice in between MMIO/PIO commands. E.g:
> + [R +0.028434] outl 0xc000 0xbeef
> + [DMA][R +0.034639] write 0xbeef 0x2 0xAAAA
> + [DMA][R +0.034639] write 0xbeef 0x2 0xBBBB
> +"""
> +
> +import sys
> +
> +__author__ = "Alexander Bulekov <alxndr@bu.edu>"
> +__copyright__ = "Copyright (C) 2020, Red Hat, Inc."
> +__license__ = "GPL version 2 or (at your option) any later version"
> +
> +__maintainer__ = "Alexander Bulekov"
> +__email__ = "alxndr@bu.edu"
> +
> +
> +def usage():
> + sys.exit("Usage: {} /path/to/qtest_log_output".format((sys.argv[0])))
> +
> +
> +def main(filename):
> + with open(filename, "r") as f:
> + trace = f.readlines()
> +
> + # Leave only lines that look like logged qtest commands
> + trace[:] = [x.strip() for x in trace if "[R +" in x
> + or "[S +" in x and "CLOSED" not in x]
> +
> + for i in range(len(trace)):
> + if i+1 < len(trace):
> + if "[DMA]" in trace[i+1]:
> + trace[i], trace[i+1] = trace[i+1], trace[i]
> + for line in trace:
> + print(line.split("]")[-1].strip())
> +
> +
> +if __name__ == '__main__':
> + if len(sys.argv) == 1:
> + usage()
> + main(sys.argv[1])
> --
> 2.27.0
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: [PATCH v2 14/15] scripts/oss-fuzz: Add script to reorder a general-fuzzer trace,
Darren Kenny <=