afl: add support for AFL PERSISTANT_MODE

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.
pull/2002/merge
Mats Klepsland 9 years ago committed by Victor Julien
parent 8111eb934f
commit 45d87d66c0

@ -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
@ -259,20 +284,6 @@
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])

@ -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 *****/

@ -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 */
/**
* @}

@ -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)
{

@ -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

Loading…
Cancel
Save