]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
afl: add support for AFL PERSISTANT_MODE
authorMats Klepsland <mats.klepsland@gmail.com>
Tue, 12 Apr 2016 10:07:43 +0000 (12:07 +0200)
committerVictor Julien <victor@inliniac.net>
Tue, 12 Apr 2016 13:20:00 +0000 (15:20 +0200)
Add support for AFL PERSISTANT_MODE when Suricata is compiled with
a supported compiler (only afl-clang-fast for now).

This gives a ~10x performance boost when fuzzing.

configure.ac
src/app-layer-parser.c
src/decode.c
src/util-decode-der.c
src/util-decode-mime.c

index a6c3f3aa8cda0b1cda44e49739f8f49191dd35e8..2c294fdbe32dfbbc6c47c78527adfd3862a05a29 100644 (file)
@@ -8,6 +8,31 @@
 
     AC_LANG_C
     AC_PROG_CC_C99
+
+    # enable modifications for AFL fuzzing
+    AC_ARG_ENABLE(afl,
+           AS_HELP_STRING([--enable-afl], Enable AFL fuzzing logic[])], [enable_afl="$enableval"],[enable_afl=no])
+
+    AS_IF([test "x$enable_afl" = "xyes"], [
+        AC_DISABLE_SHARED
+        AC_DEFINE([AFLFUZZ_NO_RANDOM], [1], [Disable all use of random functions])
+        AC_DEFINE([AFLFUZZ_DISABLE_MGTTHREADS], [1], [Disable all management threads])
+        AC_DEFINE([AFLFUZZ_PCAP_RUNMODE], [1], [Enable special AFL 'single' runmode])
+        AC_DEFINE([AFLFUZZ_CONF_TEST], [1], [Enable special --afl-parse-rules commandline option])
+        AC_DEFINE([AFLFUZZ_APPLAYER], [1], [Enable --afl-$proto-request commandline option])
+        AC_DEFINE([AFLFUZZ_MIME], [1], [Enable --afl-mime commandline option])
+        AC_DEFINE([AFLFUZZ_DECODER], [1], [Enable --afl-decoder-$proto commandline option])
+        AC_DEFINE([AFLFUZZ_DER], [1], [Enable --afl-der commandline option])
+
+        # test for AFL PERSISTANT_MODE support
+        CFLAGS_ORIG=$CFLAGS
+        CFLAGS="-Werror"
+        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[while (__AFL_LOOP(1000))]])],
+                [AC_DEFINE([AFLFUZZ_PERSISTANT_MODE], [1], [Enable AFL PERSISTANT_MODE])],
+                [])
+        CFLAGS=$CFLAGS_ORIG
+    ])
+
     AC_PROG_LIBTOOL
     PKG_PROG_PKG_CONFIG(0.21) # 0.21 is the CentOS 5.11 version
 
     esac
     AC_MSG_RESULT(ok)
 
-  # enable modifications for AFL fuzzing
-    AC_ARG_ENABLE(afl,
-           AS_HELP_STRING([--enable-afl], Enable AFL fuzzing logic[])], [enable_afl="$enableval"],[enable_afl=no])
-    AS_IF([test "x$enable_afl" = "xyes"], [
-            AC_DEFINE([AFLFUZZ_NO_RANDOM], [1], [Disable all use of random functions])
-            AC_DEFINE([AFLFUZZ_DISABLE_MGTTHREADS], [1], [Disable all management threads])
-            AC_DEFINE([AFLFUZZ_PCAP_RUNMODE], [1], [Enable special AFL 'single' runmode])
-            AC_DEFINE([AFLFUZZ_CONF_TEST], [1], [Enable special --afl-parse-rules commandline option])
-            AC_DEFINE([AFLFUZZ_APPLAYER], [1], [Enable --afl-$proto-request commandline option])
-            AC_DEFINE([AFLFUZZ_MIME], [1], [Enable --afl-mime commandline option])
-            AC_DEFINE([AFLFUZZ_DECODER], [1], [Enable --afl-decoder-$proto commandline option])
-            AC_DEFINE([AFLFUZZ_DER], [1], [Enable --afl-der commandline option])
-    ])
-
   # disable TLS on user request
     AC_ARG_ENABLE(threading-tls,
            AS_HELP_STRING([--disable-threading-tls], [Disable TLS (thread local storage)]), [enable_tls="$enableval"],[enable_tls=yes])
index 51efa30d402830a33a543dbe300e0a2786cd67f2..d7aeb81cc177f14aa42f6f9e03ca0a33a2b64e31 100644 (file)
@@ -1213,37 +1213,49 @@ int AppLayerParserRequestFromFile(AppProto alproto, char *filename)
     f->proto = IPPROTO_TCP;
     f->alproto = alproto;
 
-    FILE *fp = fopen(filename, "r");
-    BUG_ON(fp == NULL);
+    uint8_t buffer[64];
 
-    uint8_t buffer[256];
+#ifdef AFLFUZZ_PERSISTANT_MODE
+    while (__AFL_LOOP(1000)) {
+        /* reset state */
+        memset(buffer, 0, sizeof(buffer));
+#endif /* AFLFUZZ_PERSISTANT_MODE */
 
-    int start = 1;
-    while (1) {
-        int done = 0;
-        size_t result = fread(&buffer, 1, sizeof(buffer), fp);
-        if (result < sizeof(buffer))
-            done = 1;
+        FILE *fp = fopen(filename, "r");
+        BUG_ON(fp == NULL);
 
-        //SCLogInfo("result %u done %d start %d", (uint)result, done, start);
+        int start = 1;
+        while (1) {
+            int done = 0;
+            size_t result = fread(&buffer, 1, sizeof(buffer), fp);
+            if (result < sizeof(buffer))
+                done = 1;
 
-        uint8_t flags = STREAM_TOSERVER;
+            //SCLogInfo("result %u done %d start %d", (uint)result, done, start);
 
-        if (start--) {
-            flags |= STREAM_START;
-        }
-        if (done) {
-            flags |= STREAM_EOF;
+            uint8_t flags = STREAM_TOSERVER;
+
+            if (start--) {
+                flags |= STREAM_START;
+            }
+            if (done) {
+                flags |= STREAM_EOF;
+            }
+            //PrintRawDataFp(stdout, buffer, result);
+
+            (void)AppLayerParserParse(alp_tctx, f, alproto, flags, buffer, result);
+            if (done)
+                break;
         }
-        //PrintRawDataFp(stdout, buffer, result);
 
-        (void)AppLayerParserParse(alp_tctx, f, alproto, flags, buffer, result);
-        if (done)
-            break;
+        fclose(fp);
+
+#ifdef AFLFUZZ_PERSISTANT_MODE
     }
+#endif /* AFLFUZZ_PERSISTANT_MODE */
 
     result = 0;
-    fclose(fp);
+
 end:
     if (alp_tctx != NULL)
         AppLayerParserThreadCtxFree(alp_tctx);
@@ -1276,45 +1288,56 @@ int AppLayerParserFromFile(AppProto alproto, char *filename)
     f->proto = IPPROTO_TCP;
     f->alproto = alproto;
 
-    FILE *fp = fopen(filename, "r");
-    BUG_ON(fp == NULL);
-
     uint8_t buffer[64];
 
-    int start = 1;
-    int flip = 0;
-    while (1) {
-        int done = 0;
-        size_t result = fread(&buffer, 1, sizeof(buffer), fp);
-        if (result < sizeof(buffer))
-            done = 1;
+#ifdef AFLFUZZ_PERSISTANT_MODE
+    while (__AFL_LOOP(1000)) {
+        /* reset state */
+        memset(buffer, 0, sizeof(buffer));
+#endif /* AFLFUZZ_PERSISTANT_MODE */
+
+        FILE *fp = fopen(filename, "r");
+        BUG_ON(fp == NULL);
+
+        int start = 1;
+        int flip = 0;
+        while (1) {
+            int done = 0;
+            size_t result = fread(&buffer, 1, sizeof(buffer), fp);
+            if (result < sizeof(buffer))
+                done = 1;
+
+            //SCLogInfo("result %u done %d start %d", (uint)result, done, start);
+
+            uint8_t flags = 0;
+            if (flip) {
+                flags = STREAM_TOCLIENT;
+                flip = 0;
+            } else {
+                flags = STREAM_TOSERVER;
+                flip = 1;
+            }
 
-        //SCLogInfo("result %u done %d start %d", (uint)result, done, start);
+            if (start--) {
+                flags |= STREAM_START;
+            }
+            if (done) {
+                flags |= STREAM_EOF;
+            }
+            //PrintRawDataFp(stdout, buffer, result);
 
-        uint8_t flags = 0;
-        if (flip) {
-            flags = STREAM_TOCLIENT;
-            flip = 0;
-        } else {
-            flags = STREAM_TOSERVER;
-            flip = 1;
+            (void)AppLayerParserParse(alp_tctx, f, alproto, flags, buffer, result);
+            if (done)
+                break;
         }
 
-        if (start--) {
-            flags |= STREAM_START;
-        }
-        if (done) {
-            flags |= STREAM_EOF;
-        }
-        //PrintRawDataFp(stdout, buffer, result);
+        fclose(fp);
 
-        (void)AppLayerParserParse(alp_tctx, f, alproto, flags, buffer, result);
-        if (done)
-            break;
+#ifdef AFLFUZZ_PERSISTANT_MODE
     }
+#endif /* AFLFUZZ_PERSISTANT_MODE */
 
     result = 0;
-    fclose(fp);
 end:
     if (alp_tctx != NULL)
         AppLayerParserThreadCtxFree(alp_tctx);
@@ -1323,7 +1346,7 @@ end:
     }
     return result;
 }
-#endif
+#endif /* AFLFUZZ_APPLAYER */
 
 /***** Unittests *****/
 
index 75159f6f32f754870fce3cba6226b48b51f09781..1b73722e3ab1188ff7fe43acf41da869ef5ec924 100644 (file)
@@ -582,40 +582,52 @@ void CaptureStatsSetup(ThreadVars *tv, CaptureStats *s)
 
 #ifdef AFLFUZZ_DECODER
 int DecoderParseDataFromFile(char *filename, DecoderFunc Decoder) {
-    int result = 1;
-    FILE *fp = fopen(filename, "r");
-    BUG_ON(fp == NULL);
     uint8_t buffer[65536];
+    int result = 1;
+
+#ifdef AFLFUZZ_PERSISTANT_MODE
+    while (__AFL_LOOP(1000)) {
+        /* reset state */
+        memset(buffer, 0, sizeof(buffer));
+#endif /* AFLFUZZ_PERSISTANT_MODE */
+
+        FILE *fp = fopen(filename, "r");
+        BUG_ON(fp == NULL);
+
+        ThreadVars tv;
+        memset(&tv, 0, sizeof(tv));
+        DecodeThreadVars *dtv = DecodeThreadVarsAlloc(&tv);
+        DecodeRegisterPerfCounters(dtv, &tv);
+        StatsSetupPrivate(&tv);
+
+        while (1) {
+            int done = 0;
+            size_t result = fread(&buffer, 1, sizeof(buffer), fp);
+            if (result < sizeof(buffer))
+                 done = 1;
+
+            Packet *p = PacketGetFromAlloc();
+            if (p != NULL) {
+                (void) Decoder (&tv, dtv, p, buffer, result, NULL);
+                PacketFree(p);
+            }
 
-    ThreadVars tv;
-    memset(&tv, 0, sizeof(tv));
-    DecodeThreadVars *dtv = DecodeThreadVarsAlloc(&tv);
-    DecodeRegisterPerfCounters(dtv, &tv);
-    StatsSetupPrivate(&tv);
-
-    while (1) {
-        int done = 0;
-        size_t result = fread(&buffer, 1, sizeof(buffer), fp);
-        if (result < sizeof(buffer))
-            done = 1;
-
-        Packet *p = PacketGetFromAlloc();
-        if (p != NULL) {
-            (void) Decoder (&tv, dtv, p, buffer, result, NULL);
-            PacketFree(p);
+            if (done)
+                break;
         }
+        DecodeThreadVarsFree(&tv, dtv);
 
-        if (done)
-            break;
+        fclose(fp);
+
+#ifdef AFLFUZZ_PERSISTANT_MODE
     }
-    DecodeThreadVarsFree(&tv, dtv);
+#endif /* AFLFUZZ_PERSISTANT_MODE */
 
     result = 0;
-    fclose(fp);
     return result;
 
 }
-#endif
+#endif /* AFLFUZZ_DECODER */
 
 /**
  * @}
index c080cefd9353b958d2416c43d32889b896e8df6b..00c1bccaef07567df066caa67b4d3a95c1757bcc 100644 (file)
@@ -901,30 +901,29 @@ Asn1Generic * DecodeDer(const unsigned char *buffer, uint32_t size,
 #ifdef AFLFUZZ_DER
 int DerParseDataFromFile(char *filename)
 {
-    int result = 1;
-    FILE *fp = fopen(filename, "r");
-    BUG_ON(fp == NULL);
     uint8_t buffer[65536];
-
     uint32_t errcode = 0;
 
-    while (1) {
-        int done = 0;
-        size_t result = fread(&buffer, 1, sizeof(buffer), fp);
-        if (result < sizeof(buffer))
-            done = 1;
+#ifdef AFLFUZZ_PERSISTANT_MODE
+    while (__AFL_LOOP(1000)) {
+        /* reset state */
+        memset(buffer, 0, sizeof(buffer));
+#endif /* AFLFUZZ_PERSISTANT_MODE */
+
+        FILE *fp = fopen(filename, "r");
+        BUG_ON(fp == NULL);
 
+        size_t result = fread(&buffer, 1, sizeof(buffer), fp);
         DecodeDer(buffer, result, &errcode);
+        fclose(fp);
 
-        if (done)
-            break;
+#ifdef AFLFUZZ_PERSISTANT_MODE
     }
+#endif /* AFLFUZZ_PERSISTANT_MODE */
 
-    result = 0;
-    fclose(fp);
-    return result;
+    return 0;
 }
-#endif
+#endif /* AFLFUZZ_DER */
 
 void DerFree(Asn1Generic *a)
 {
index 7d8e888437807e82872f10550e7b68f69afc6d54..81d8bc720bd14e8c96aa7532c90fbdca01001485 100644 (file)
@@ -2624,41 +2624,54 @@ static int MimeParserDataFromFileCB(const uint8_t *chunk, uint32_t len,
 int MimeParserDataFromFile(char *filename)
 {
     int result = 1;
-    FILE *fp = fopen(filename, "r");
-    BUG_ON(fp == NULL);
     uint8_t buffer[256];
 
-    uint32_t line_count = 0;
+#ifdef AFLFUZZ_PERSISTANT_MODE
+    while (__AFL_LOOP(1000)) {
+        /* reset state */
+        memset(buffer, 0, sizeof(buffer));
+#endif /* AFLFUZZ_PERSISTANT_MODE */
 
-    MimeDecParseState *state = MimeDecInitParser(&line_count,
-            MimeParserDataFromFileCB);
+        FILE *fp = fopen(filename, "r");
+        BUG_ON(fp == NULL);
 
-    while (1) {
-        int done = 0;
-        size_t result = fread(&buffer, 1, sizeof(buffer), fp);
-        if (result < sizeof(buffer))
-            done = 1;
+        uint32_t line_count = 0;
 
-        (void) MimeDecParseLine(buffer, result, 1, state);
+        MimeDecParseState *state = MimeDecInitParser(&line_count,
+                MimeParserDataFromFileCB);
 
-        if (done)
-            break;
-    }
+        while (1) {
+            int done = 0;
+            size_t result = fread(&buffer, 1, sizeof(buffer), fp);
+            if (result < sizeof(buffer))
+                done = 1;
 
-    /* Completed */
-    (void)MimeDecParseComplete(state);
+            (void) MimeDecParseLine(buffer, result, 1, state);
+
+            if (done)
+                break;
+        }
 
-    if (state->msg) {
-        MimeDecFreeEntity(state->msg);
+        /* Completed */
+        (void)MimeDecParseComplete(state);
+
+        if (state->msg) {
+            MimeDecFreeEntity(state->msg);
+        }
+
+        /* De Init parser */
+        MimeDecDeInitParser(state);
+
+        fclose(fp);
+
+#ifdef AFLFUZZ_PERSISTANT_MODE
     }
-    /* De Init parser */
-    MimeDecDeInitParser(state);
+#endif /* AFLFUZZ_PERSISTANT_MODE */
 
     result = 0;
-    fclose(fp);
     return result;
 }
-#endif
+#endif /* AFLFUZZ_MIME */
 
 #ifdef UNITTESTS