From c5d0b7578c0f06e20bd7c2bca39a3a21acb17ddc Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Mon, 13 Jan 2020 15:20:01 -0500 Subject: [PATCH] bgpd: cleanup suboptimal AFL paths after libFuzzer The AFL path through LLVMFuzzerTestOneInput is running a bit slow because we are initializing BGP twice. Fix this. Also, since we know at compile time whether we need to create a peer (libFuzzer) or use one created already (AFL fork() case) we can save a branch in the hot path, so let's do that. Signed-off-by: Quentin Young --- bgpd/bgp_main.c | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index 711be1fbb6..590c2f5637 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -461,27 +461,38 @@ static struct peer *FuzzingCreatePeer() return p; } +#ifndef FUZZING_LIBFUZZER static struct peer *FuzzingPeer; +#endif + +static bool FuzzingInitialized; int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - static bool initialized; - - if (!initialized) - initialized = FuzzingInit(); + if (!FuzzingInitialized) { + FuzzingInit(); + FuzzingInitialized = true; + } /* * In the AFL standalone case, the peer will already be created for us * before __AFL_INIT() is called to speed things up. We can't pass it * as an argument because the function signature must match libFuzzer's - * expectations. + * expectations, so it's saved in a global variable. Even though we'll + * be exiting the program after each run, we still destroy the peer + * because that increases our coverage and is likely to find memory + * leaks when pointers are nulled that would otherwise be "in-use at + * exit". * - * In the libFuzzer case, we need to create it each time. - * - * In both cases the peer must be destroyed before we return.. + * In the libFuzzer case, we need to create it each time, and destroy + * it when done. */ - struct peer *p = (FuzzingPeer) ? FuzzingPeer : FuzzingCreatePeer(); - + struct peer *p; +#ifdef FUZZING_LIBFUZZER + p = FuzzingCreatePeer(); +#else + p = FuzzingPeer; +#endif /* FUZZING_LIBFUZZER */ ringbuf_put(p->ibuf_work, data, size); @@ -518,11 +529,10 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) done: peer_delete(p); - FuzzingPeer = NULL; return 0; }; -#endif +#endif /* FUZZING */ #ifndef FUZZING_LIBFUZZER /* Main routine of bgpd. Treatment of argument and start bgp finite @@ -545,6 +555,7 @@ int main(int argc, char **argv) #ifdef FUZZING FuzzingInit(); FuzzingPeer = FuzzingCreatePeer(); + FuzzingInitialized = true; #ifdef __AFL_HAVE_MANUAL_CONTROL __AFL_INIT(); -- 2.39.5