qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Questiones About MORPHUZZ (the generic-fuzzer)


From: Alexander Bulekov
Subject: Re: Questiones About MORPHUZZ (the generic-fuzzer)
Date: Wed, 1 Dec 2021 12:02:01 -0500

On 211201 1537, dhbbb wrote:
> Hello Alex,
> Thanks for your kind reply,it really helped me a lot! I am more
> familiar with AFL than libfuzzer,and i noticed that you said "This
> minimal init/exec interface is also supported by other fuzzers, such
> as AFL[++]".But your project seems to be highly integrated with
> QEMU,so if I want to use other fuzzers as QMORPHUZZ's
>  fuzzing-backend , could you please tell me where to start?
 
Sure. (I am cc-ing the qemu-mailing list, as others are interested in
this as well.)

Here's how the execution looks for something like
./qemu-fuzz- --fuzz_target=generic-fuzz -jobs=2 -workers=2

  LLVMFuzzerInitialize
        |
        |
        |
        v
    qemu_init

        |
        +-------------- fork ----------+
      fork                             |
        v                              v
     worker1                        worker2
        |                              |
        |                              |
        v                              v
      RunOne                         RunOne
        |                              |
        |                              |
        v                              v
     pre_fuzz                       pre_fuzz
(init shared memory)           (init shared memory)
        |                              |
        |                              |
        v                              v
  generic_fuzz ---fork-+         generic_fuzz ---fork-+
        |              |               |              |
        |              |               |              |
        |              v               |              v
        |       (run the input)        |       (run the input)
        |              |               |              |
        v              v               v              v
      wait           exit            wait           exit
        |                              |
        |                              |
        v                              v
     RunOne                         RunOne
       |                              |
       |                              |
       v                              v
 generic_fuzz ---fork-+         generic_fuzz ---fork-+
       |              |               |              |
       |              |               |              |
       |              v               |              v
     ...             ...            ...             ...

LibFuzzer essentially provides two main interfaces that we use.
The first, LLVMFuzzerInitialize, runs a single time when you first run
./qemu-fuzz-...
It is defined in tests/qtest/fuzz/fuzz.c
Most of the code is there so we can specify which --fuzz-target we want
to run, and select the corresponding qemu arguments that we would
normally pass to ./qemu-system-i386. Then we call qemu_init, which
initializes the VM correspondingly. None of this should be very
libfuzzer specific.

The second interface, LLVMFuzzerTestOneInput, is the one that LibFuzzer
calls for every single input. This is also defined in fuzz.c.
Importantly, in between FuzzerInitialize and FuzzerTestOneInput,
libFuzzer might fork the process multiple times in order to create
additional workers (if --jobs and --workers arguments are specified).
Since we hacked on our own forkserver onto LibFuzzer, and this requires
separate shared memory for each worker, we also run some initialization
code a single time in each worker. This is the "!pre_fuzz_done &&
fuzz_target->pre_fuzz" part. For the generic fuzzer, here we also do all
of the generic-fuzz-specific initialization (such as finding all of the
MemoryRegions we want to fuzz). I think the only thing specific to
LibFuzzer here should be the call to counter_shm_init(), which we use to
establish the LibFuzzer-specific shared memory regions (since LibFuzzer
has no built-in fork-server feature).

The final important libFuzzer-specific part is that in the actual fuzz()
function (aka generic_fuzz for the generic-fuzzer, which is called for
each input), we manually fork() the process and re-establish timers for
the timeout. For other fuzzers, which have built-in forkservers,
presumably, we wouldn't need this.

I think AFL++ provides interoperability with the
LLVMFuzzerInitialize/LLVMFuzzerTestOneInput interface. So in order to
use AFL++ we would need to strip out the libfuzzer-specific shm and
fork-server parts, and see how we can integrate AFL++' built-in
forkserver. I am happy to help more with this if you are interested in
adding AFL++ support, upstream.

-Alex



reply via email to

[Prev in Thread] Current Thread [Next in Thread]