aboutsummaryrefslogtreecommitdiff
path: root/tests/qtest/fuzz/generic_fuzz.c
AgeCommit message (Collapse)Author
2022-06-15vfio-user: handle PCI BAR accessesJagannathan Raman
Determine the BARs used by the PCI device and register handlers to manage the access to the same. Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com> Signed-off-by: John G Johnson <john.g.johnson@oracle.com> Signed-off-by: Jagannathan Raman <jag.raman@oracle.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Message-id: 3373e10b5be5f42846f0632d4382466e1698c505.1655151679.git.jag.raman@oracle.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2022-05-03tests: move libqtest.h back under qtest/Marc-André Lureau
Since commit a2ce7dbd917 ("meson: convert tests/qtest to meson"), libqtest.h is under libqos/ directory, while libqtest.c is still in qtest/. Move back to its original location to avoid mixing with libqos/. Suggested-by: Thomas Huth <thuth@redhat.com> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Thomas Huth <thuth@redhat.com> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
2022-04-21tests/fuzz: fix warningMarc-André Lureau
../tests/qtest/fuzz/generic_fuzz.c:746:17: warning: variable 'name' set but not used [-Wunused-but-set-variable] Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Thomas Huth <thuth@redhat.com> Message-Id: <20220420132624.2439741-42-marcandre.lureau@redhat.com>
2021-09-01fuzz: unblock SIGALRM so the timeout worksAlexander Bulekov
The timeout mechanism won't work if SIGALRM is blocked. This changes unmasks SIGALRM when the timer is installed. This doesn't completely solve the problem, as the fuzzer could trigger some device activity that re-masks SIGALRM. However, there are currently no inputs on OSS-Fuzz that re-mask SIGALRM and timeout. If that turns out to be a real issue, we could try to hook sigmask-type calls, or use a separate timer thread. Based-on: <20210713150037.9297-1-alxndr@bu.edu> Signed-off-by: Alexander Bulekov <alxndr@bu.edu> Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
2021-09-01fuzz: use ITIMER_REAL for timeoutsAlexander Bulekov
Using ITIMER_VIRTUAL is a bad idea, if the fuzzer hits a blocking syscall - e.g. ppoll with a NULL timespec. This causes timeout issues while fuzzing some block-device code. Fix that by using wall-clock time. This might cause inputs to timeout sometimes due to scheduling effects/ambient load, but it is better than bringing the entire fuzzing process to a halt. Based-on: <20210713150037.9297-1-alxndr@bu.edu> Signed-off-by: Alexander Bulekov <alxndr@bu.edu> Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
2021-09-01fuzz: make object-name matching case-insensitiveAlexander Bulekov
We have some configs for devices such as the AC97 and ES1370 that were not matching memory-regions correctly, because the configs provided lowercase names. To resolve these problems and prevent them from occurring again in the future, convert both the pattern and names to lower-case, prior to checking for a match. Suggested-by: Darren Kenny <darren.kenny@oracle.com> Reviewed-by: Darren Kenny <darren.kenny@oracle.com> Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
2021-09-01fuzz: adjust timeout to allow for longer inputsAlexander Bulekov
Using a custom timeout is useful to continue fuzzing complex devices, even after we run into some slow code-path. However, simply adding a fixed timeout to each input effectively caps the maximum input length/number of operations at some artificial value. There are two major problems with this: 1. Some code might only be reachable through long IO sequences. 2. Longer inputs can actually be _better_ for performance. While the raw number of fuzzer executions decreases with larger inputs, the number of MMIO/PIO/DMA operation/second actually increases, since were are speding proportionately less time fork()ing. With this change, we keep the custom-timeout, but we renew it, prior to each MMIO/PIO/DMA operation. Thus, we time-out only when a specific operation takes a long time. Reviewed-by: Darren Kenny <darren.kenny@oracle.com> Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
2021-09-01fuzz: fix sparse memory access in the DMA callbackAlexander Bulekov
The code mistakenly relied on address_space_translate to store the length remaining until the next memory-region. We care about this because when there is RAM or sparse-memory neighboring on an MMIO region, we should only write up to the border, to prevent inadvertently invoking MMIO handlers within the DMA callback. However address_space_translate_internal only stores the length until the end of the MemoryRegion if memory_region_is_ram(mr). Otherwise the *len is left unmodified. This caused some false-positive issues, where the fuzzer found a way to perform a nested MMIO write through a DMA callback on an [address, length] that started within sparse memory and spanned some device MMIO regions. To fix this, write to sparse memory in small chunks of memory_access_size (similar to the underlying address_space_write code), which will prevent accidentally hitting MMIO handlers through large writes. Signed-off-by: Alexander Bulekov <alxndr@bu.edu> Reviewed-by: Darren Kenny <darren.kenny@oracle.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
2021-06-21fuzz: Display hexadecimal value with '0x' prefixPhilippe Mathieu-Daudé
Use memory_region_size() to get the MemoryRegion size, and display it with the '0x' prefix. Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Alexander Bulekov <alxndr@bu.edu> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Reviewed-by: Thomas Huth <thuth@redhat.com> Message-Id: <20210612195842.1595999-1-f4bug@amsat.org> Signed-off-by: Thomas Huth <thuth@redhat.com>
2021-05-02Do not include exec/address-spaces.h if it's not really necessaryThomas Huth
Stop including exec/address-spaces.h in files that don't need it. Signed-off-by: Thomas Huth <thuth@redhat.com> Message-Id: <20210416171314.2074665-5-thuth@redhat.com> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
2021-03-23memory: Add offset_in_region to flatview_cb argumentsPeter Maydell
The function flatview_for_each_range() calls a callback for each range in a FlatView. Currently the callback gets the start and length of the range and the MemoryRegion involved, but not the offset within the MemoryRegion. Add this to the callback's arguments; we're going to want it for a new use in the next commit. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-id: 20210318174823.18066-4-peter.maydell@linaro.org
2021-03-23memory: Make flatview_cb return bool, not intPeter Maydell
The return value of the flatview_cb callback passed to the flatview_for_each_range() function is zero if the iteration through the ranges should continue, or non-zero to break out of it. Use a bool for this rather than int. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-id: 20210318174823.18066-2-peter.maydell@linaro.org
2021-03-16fuzz: configure a sparse-mem device, by defaultAlexander Bulekov
The generic-fuzzer often provides randomized DMA addresses to virtual-devices. For a 64-bit address-space, the chance of these randomized addresses coinciding with RAM regions, is fairly small. Even though the fuzzer's instrumentation eventually finds valid addresses, this can take some-time, and slows-down fuzzing progress (especially, when multiple DMA buffers are involved). To work around this, create "fake" sparse-memory that spans all of the 64-bit address-space. Adjust the DMA call-back to populate this sparse memory, correspondingly Signed-off-by: Alexander Bulekov <alxndr@bu.edu> Reviewed-by: Darren Kenny <darren.kenny@oracle.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-03-16fuzz: don't leave orphan llvm-symbolizers aroundAlexander Bulekov
I noticed that with a sufficiently small timeout, the fuzzer fork-server sometimes locks up. On closer inspection, the issue appeared to be caused by entering our SIGALRM handler, while libfuzzer is in it's crash handlers. Because libfuzzer relies on pipe communication with an external child process to print out stack-traces, we shouldn't exit early, and leave an orphan child. Check for children in the SIGALRM handler to avoid this issue. Signed-off-by: Alexander Bulekov <alxndr@bu.edu> Acked-by: Thomas Huth <thuth@redhat.com> Reviewed-by: Darren Kenny <darren.kenny@oracle.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-02-08fuzz: enable dynamic args for generic-fuzz configsAlexander Bulekov
For some device configurations, it is useful to configure some resources, and adjust QEMU arguments at runtime, prior to fuzzing. This patch adds an "argfunc" to generic the generic_fuzz_config. When specified, it is responsible for configuring the resources and returning a string containing the corresponding QEMU arguments. This can be useful for targets that rely on e.g.: * a temporary qcow2 image * a temporary directory * an unused TCP port used to bind the VNC server Signed-off-by: Alexander Bulekov <alxndr@bu.edu> Reviewed-by: Thomas Huth <thuth@redhat.com> Message-Id: <20210117230924.449676-2-alxndr@bu.edu>
2021-02-08fuzz: ignore address_space_map is_write flagAlexander Bulekov
We passed an is_write flag to the fuzz_dma_read_cb function to differentiate between the mapped DMA regions that need to be populated with fuzzed data, and those that don't. We simply passed through the address_space_map is_write parameter. The goal was to cut down on unnecessarily populating mapped DMA regions, when they are not read from. Unfortunately, nothing precludes code from reading from regions mapped with is_write=true. For example, see: https://lists.gnu.org/archive/html/qemu-devel/2021-01/msg04729.html This patch removes the is_write parameter to fuzz_dma_read_cb. As a result, we will fill all mapped DMA regions with fuzzed data, ignoring the specified transfer direction. Signed-off-by: Alexander Bulekov <alxndr@bu.edu> Reviewed-by: Darren Kenny <darren.kenny@oracle.com> Message-Id: <20210120060255.558535-1-alxndr@bu.edu>
2021-01-11fuzz: map all BARs and enable PCI devicesAlexander Bulekov
Prior to this patch, the fuzzer found inputs to map PCI device BARs and enable the device. While it is nice that the fuzzer can do this, it added significant overhead, since the fuzzer needs to map all the BARs (regenerating the memory topology), at the start of each input. With this patch, we do this once, before fuzzing, mitigating some of this overhead. Signed-off-by: Alexander Bulekov <alxndr@bu.edu> Reviewed-by: Darren Kenny <darren.kenny@oracle.com> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Message-Id: <20201221181203.1853-1-alxndr@bu.edu> Signed-off-by: Thomas Huth <thuth@redhat.com>
2020-12-09fuzz: avoid double-fetches by defaultAlexander Bulekov
The generic fuzzer can find double-fetch bugs. However: * We currently have no good way of producing qemu-system reproducers for double-fetch bugs. Even if we can get developers to run the binary-blob reproducers with the qemu-fuzz builds, we currently don't have a minimizer for these reproducers, so they are usually not easy to follow. * Often times the fuzzer will provide a reproducer containing a double-fetch for a bug that can be reproduced without double-fetching. Until we find a way to build nice double-fetch reproducers that developers are willing to look at, lets tell OSS-Fuzz to avoid double-fetches. Signed-off-by: Alexander Bulekov <alxndr@bu.edu> Reviewed-by: Darren Kenny <darren.kenny@oracle.com> Message-Id: <20201202164214.93867-1-alxndr@bu.edu> Signed-off-by: Thomas Huth <thuth@redhat.com>
2020-11-03fuzz: fuzz offsets within pio/mmio regionsAlexander Bulekov
The code did not add offsets to FlatRange bases, so we did not fuzz offsets within device MemoryRegions. Signed-off-by: Alexander Bulekov <alxndr@bu.edu> Reviewed-by: Darren Kenny <darren.kenny@oracle.com> Message-Id: <20201029172901.534442-4-alxndr@bu.edu> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2020-11-03fuzz: check the MR in the DMA callbackAlexander Bulekov
We should be checking that the device is trying to read from RAM, before filling the region with data. Otherwise, we will try to populate nonsensical addresses in RAM for callbacks on PIO/MMIO reads. We did this originally, however the final version I sent had the line commented out.. Signed-off-by: Alexander Bulekov <alxndr@bu.edu> Reviewed-by: Darren Kenny <darren.kenny@oracle.com> Message-Id: <20201029172901.534442-3-alxndr@bu.edu> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2020-11-03fuzz: fix writing DMA patternsAlexander Bulekov
This code had all sorts of issues. We used a loop similar to address_space_write_rom, but I did not remove a "break" that only made sense in the context of the switch statement in the original code. Then, after the loop, we did a separate qtest_memwrite over the entire DMA access range, defeating the purpose of the loop. Additionally, we increment the buf pointer, and then try to g_free() it. Fix these problems. Reported-by: OSS-Fuzz (Issue 26725) Signed-off-by: Alexander Bulekov <alxndr@bu.edu> Reported-by: OSS-Fuzz (Issue 26691) Reviewed-by: Darren Kenny <darren.kenny@oracle.com> Message-Id: <20201029172901.534442-2-alxndr@bu.edu> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2020-10-26fuzz: register predefined generic-fuzz configsAlexander Bulekov
We call get_generic_fuzz_configs, which fills an array with predefined {name, args, objects} triples. For each of these, we add a new FuzzTarget, that uses a small wrapper to set QEMU_FUZZ_{ARGS,OBJECTS} to the corresponding predefined values. Reviewed-by: Darren Kenny <darren.kenny@oracle.com> Signed-off-by: Alexander Bulekov <alxndr@bu.edu> Message-Id: <20201023150746.107063-16-alxndr@bu.edu> Signed-off-by: Thomas Huth <thuth@redhat.com>
2020-10-26fuzz: add a crossover function to generic-fuzzerAlexander Bulekov
Reviewed-by: Darren Kenny <darren.kenny@oracle.com> Signed-off-by: Alexander Bulekov <alxndr@bu.edu> Message-Id: <20201023150746.107063-10-alxndr@bu.edu> Signed-off-by: Thomas Huth <thuth@redhat.com>
2020-10-26fuzz: add a DISABLE_PCI op to generic-fuzzerAlexander Bulekov
This new operation is used in the next commit, which concatenates two fuzzer-generated inputs. With this operation, we can prevent the second input from clobbering the PCI configuration performed by the first. Signed-off-by: Alexander Bulekov <alxndr@bu.edu> Reviewed-by: Darren Kenny <darren.kenny@oracle.com> Message-Id: <20201023150746.107063-9-alxndr@bu.edu> Signed-off-by: Thomas Huth <thuth@redhat.com>
2020-10-26fuzz: Add DMA support to the generic-fuzzerAlexander Bulekov
When a virtual-device tries to access some buffer in memory over DMA, we add call-backs into the fuzzer(next commit). The fuzzer checks verifies that the DMA request maps to a physical RAM address and fills the memory with fuzzer-provided data. The patterns that we use to fill this memory are specified using add_dma_pattern and clear_dma_patterns operations. Signed-off-by: Alexander Bulekov <alxndr@bu.edu> Reviewed-by: Darren Kenny <darren.kenny@oracle.com> Message-Id: <20201023150746.107063-5-alxndr@bu.edu> [thuth: Reformatted one comment according to the QEMU coding style] Signed-off-by: Thomas Huth <thuth@redhat.com>
2020-10-24fuzz: Add PCI features to the generic fuzzerAlexander Bulekov
This patch compares TYPE_PCI_DEVICE objects against the user-provided matching pattern. If there is a match, we use some hacks and leverage QOS to map each possible BAR for that device. Now fuzzed inputs might be converted to pci_read/write commands which target specific. This means that we can fuzz a particular device's PCI configuration space, Signed-off-by: Alexander Bulekov <alxndr@bu.edu> Reviewed-by: Darren Kenny <darren.kenny@oracle.com> Message-Id: <20201023150746.107063-4-alxndr@bu.edu> Signed-off-by: Thomas Huth <thuth@redhat.com>
2020-10-24fuzz: Add generic virtual-device fuzzerAlexander Bulekov
This is a generic fuzzer designed to fuzz a virtual device's MemoryRegions, as long as they exist within the Memory or Port IO (if it exists) AddressSpaces. The fuzzer's input is interpreted into a sequence of qtest commands (outb, readw, etc). The interpreted commands are separated by a magic seaparator, which should be easy for the fuzzer to guess. Without ASan, the separator can be specified as a "dictionary value" using the -dict argument (see libFuzzer documentation). Reviewed-by: Darren Kenny <darren.kenny@oracle.com> Signed-off-by: Alexander Bulekov <alxndr@bu.edu> Message-Id: <20201023150746.107063-3-alxndr@bu.edu> Signed-off-by: Thomas Huth <thuth@redhat.com>