]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: cleanup suboptimal AFL paths after libFuzzer
authorQuentin Young <qlyoung@cumulusnetworks.com>
Mon, 13 Jan 2020 20:20:01 +0000 (15:20 -0500)
committerQuentin Young <qlyoung@nvidia.com>
Mon, 15 Nov 2021 19:52:42 +0000 (14:52 -0500)
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 <qlyoung@cumulusnetworks.com>
bgpd/bgp_main.c

index 711be1fbb66ee2f2398577565f1fa6b57951ae6d..590c2f563700afd335810b0b2f50463894ae505f 100644 (file)
@@ -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();