Wow that was painful
libFuzzer replaces main(), so while we can compile with
-fsanitize=fuzzer, we can't link with it unless we have a way to
undefine main(). So I've added a #define, FUZZING_LIBFUZZER, that
daemons who want to support libfuzzer need to guard their main() with.
This also means we can't use the SAN_FLAGS automake variable, since that
is included in both AM_CFLAGS and AM_LDFLAGS, to add -fsanitize=fuzzer
to. We need new daemon specific flags. Actually, we can add
-fsanitize=fuzzer-no-link to SAN_FLAGS, but we need daemon specific
LDFLAGS so we can control who links with -fsanitize=fuzzer. Aside from
replacing main(), LibFuzzer.a also needs to link to a user-defined
function called `LLVMFuzzerTestOneInput` which is the fuzzer entrypoint.
For bgpd, because libfuzzer is in-process, we now need to actuall clean
up after ourselves each fuzz run to avoid leaking memory. We also can't
touch global state. This also means we run slower because we have to
create and destroy a peer struct every iteration.
Finally I've almost certainly broken afl for now, will fix later.
AC_MSG_ERROR([$CC does not support ASAN / libFuzzer.])
], [
AC_MSG_NOTICE([WARNING - libFuzzer only enabled on supported daemons])
- AC_MSG_NOTICE([WARNING - libFuzzer implies ASAN for all daemons])
SAN_FLAGS="$SAN_FLAGS -fsanitize=address"
BGPD_SAN_FLAGS="-fsanitize=fuzzer"
AC_DEFINE([FUZZING_LIBFUZZER], [1], [Compiling and linking with libFuzzer])