mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-11 03:24:58 -06:00
fuzz: adjust timeout to allow for longer inputs
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>
This commit is contained in:
parent
af16990a1b
commit
993f52f4d4
1 changed files with 9 additions and 4 deletions
|
@ -668,15 +668,16 @@ static void generic_fuzz(QTestState *s, const unsigned char *Data, size_t Size)
|
||||||
uint8_t op;
|
uint8_t op;
|
||||||
|
|
||||||
if (fork() == 0) {
|
if (fork() == 0) {
|
||||||
|
struct sigaction sact;
|
||||||
|
struct itimerval timer;
|
||||||
/*
|
/*
|
||||||
* Sometimes the fuzzer will find inputs that take quite a long time to
|
* Sometimes the fuzzer will find inputs that take quite a long time to
|
||||||
* process. Often times, these inputs do not result in new coverage.
|
* process. Often times, these inputs do not result in new coverage.
|
||||||
* Even if these inputs might be interesting, they can slow down the
|
* Even if these inputs might be interesting, they can slow down the
|
||||||
* fuzzer, overall. Set a timeout to avoid hurting performance, too much
|
* fuzzer, overall. Set a timeout for each command to avoid hurting
|
||||||
|
* performance, too much
|
||||||
*/
|
*/
|
||||||
if (timeout) {
|
if (timeout) {
|
||||||
struct sigaction sact;
|
|
||||||
struct itimerval timer;
|
|
||||||
|
|
||||||
sigemptyset(&sact.sa_mask);
|
sigemptyset(&sact.sa_mask);
|
||||||
sact.sa_flags = SA_NODEFER;
|
sact.sa_flags = SA_NODEFER;
|
||||||
|
@ -686,13 +687,17 @@ static void generic_fuzz(QTestState *s, const unsigned char *Data, size_t Size)
|
||||||
memset(&timer, 0, sizeof(timer));
|
memset(&timer, 0, sizeof(timer));
|
||||||
timer.it_value.tv_sec = timeout / USEC_IN_SEC;
|
timer.it_value.tv_sec = timeout / USEC_IN_SEC;
|
||||||
timer.it_value.tv_usec = timeout % USEC_IN_SEC;
|
timer.it_value.tv_usec = timeout % USEC_IN_SEC;
|
||||||
setitimer(ITIMER_VIRTUAL, &timer, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
op_clear_dma_patterns(s, NULL, 0);
|
op_clear_dma_patterns(s, NULL, 0);
|
||||||
pci_disabled = false;
|
pci_disabled = false;
|
||||||
|
|
||||||
while (cmd && Size) {
|
while (cmd && Size) {
|
||||||
|
/* Reset the timeout, each time we run a new command */
|
||||||
|
if (timeout) {
|
||||||
|
setitimer(ITIMER_VIRTUAL, &timer, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* Get the length until the next command or end of input */
|
/* Get the length until the next command or end of input */
|
||||||
nextcmd = memmem(cmd, Size, SEPARATOR, strlen(SEPARATOR));
|
nextcmd = memmem(cmd, Size, SEPARATOR, strlen(SEPARATOR));
|
||||||
cmd_len = nextcmd ? nextcmd - cmd : Size;
|
cmd_len = nextcmd ? nextcmd - cmd : Size;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue