fuzz: Don't spawn threads prior to __AFL_INIT #28469

issue dergoegge opened this issue on September 13, 2023
  1. dergoegge commented at 11:11 AM on September 13, 2023: member

    Spawning threads prior to __AFL_INIT is not supported as the afl++ fork server can't clone threads, see afl++ docs.

    We however have chosen to do this in several of our targets (e.g. process_message, process_messages) and as a result those targets can not be fuzzed using afl++ (resulting in timeouts). Afaict this is only a problem if the spawned threads are also used (e.g. join) in the target.

    A potential fix would be to call initialize after __AFL_INIT but prior to __AFL_LOOP, which will however lead to slower fuzzing for all targets.

    (I'm uncertain why oss-fuzz does not report the timeouts to us but that seems like an issue on their end)

  2. maflcko commented at 11:25 AM on September 13, 2023: member

    A potential fix would be to call initialize after __AFL_INIT but prior to __AFL_LOOP, which will however lead to slower fuzzing for all targets.

    Why? It would just switch the order of the two statements, not move them in or out of a loop?

  3. maflcko added the label Tests on Sep 13, 2023
  4. dergoegge commented at 11:59 AM on September 13, 2023: member

    Why? It would just switch the order of the two statements, not move them in or out of a loop?

    I think __AFL_INIT marks the point where afl++ will call fork, that's why calling initialize after wouldn't suffer from the same issue.

  5. maflcko commented at 12:25 PM on September 13, 2023: member

    Ok, so if the only goal is to fix correctness of the program, then moving __AFL_INIT up by one line should do it.

    If the goal is to be maximally performant, the fork would need to happen for each fuzz target specifically. I guess it can be achieved by wrapping __AFL_INIT(); into a helper function and then require all fuzz target initialize() to call it?

  6. maflcko commented at 12:26 PM on September 13, 2023: member

    Actually, we don't need a fork, because libFuzzer doesn't fork either, so why not just remove __AFL_INIT completely?

  7. dergoegge commented at 12:36 PM on September 13, 2023: member

    Actually, we don't need a fork, because libFuzzer doesn't fork either, so why not just remove __AFL_INIT completely?

    __AFL_INIT is nice for targets that have expensive initialization that does not include e.g. spawning threads, so we should keep it.

  8. maflcko commented at 12:40 PM on September 13, 2023: member

    No, I mean afl should just provide a way to behave exactly like libFuzzer. (It is possible to do expensive initialization in libFuzzer in LLVMFuzzerInitialize).

    Simply retaining the global state from LLVMFuzzerInitialize for the persistent process for the whole time and not doing any clone or fork should always be the fastest, no?

  9. dergoegge commented at 1:37 PM on September 13, 2023: member

    No, I mean afl should just provide a way to behave exactly like libFuzzer.

    (based on my understanding of how afl++ works) This is unlikely to happen because afl++ is not a in-process fuzzing engine like libFuzzer. The persistent mode and deferred initialization is supposed to make up for that though.

    I think if we call initialize after __AFL_INIT and then increase the __AFL_LOOP count: https://github.com/bitcoin/bitcoin/blob/adc0921ea19f3b06878df6b22393fec519ed8f91/src/test/fuzz/fuzz.cpp#L200 the performance hit should be less. Increasing the count should be possible without consequences if the body of the loop is ~stateless.

  10. maflcko commented at 2:02 PM on September 13, 2023: member

    Sgtm to increase the loop count, because it is already required for the loop to not change global, persistet state. Is there any reason the loop can't be increased to 1000000 (or whatever is the maximum allowed value)?

    Also, I wonder if we can move the __AFL_INIT call inside the __AFL_LOOP compile guard at the same time. There shouldn't be a version of afl that supports __AFL_LOOP, but not __AFL_INIT?

  11. fanquake referenced this in commit f608a409f7 on Sep 15, 2023
  12. fanquake closed this on Sep 15, 2023

  13. Frank-GER referenced this in commit 0102f2a871 on Sep 19, 2023
  14. bitcoin locked this on Sep 14, 2024

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-04-28 03:13 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me