Add a fuzzer for http::StatusLine::parse()

And fix an unhandled std::length_error it found.

Signed-off-by: Miklos Vajna <vmiklos@collabora.com>
Change-Id: I571cdd71caeda84820f2c64088966936637ce2bf
pull/2109/head
Miklos Vajna 2021-04-22 11:58:28 +02:00
parent 647e2bbdd2
commit 80c6562e59
6 changed files with 49 additions and 2 deletions

View File

@ -145,7 +145,8 @@ if ENABLE_LIBFUZZER
noinst_PROGRAMS += \
admin_fuzzer \
clientsession_fuzzer \
httpheader_fuzzer
httpheader_fuzzer \
httpstatus_fuzzer
else
noinst_PROGRAMS += loolwsd_fuzzer
endif
@ -206,6 +207,16 @@ httpheader_fuzzer_SOURCES = \
fuzzer/HttpHeader.cpp
httpheader_fuzzer_LDFLAGS = -fsanitize=fuzzer $(AM_LDFLAGS)
httpstatus_fuzzer_CPPFLAGS = \
-DKIT_IN_PROCESS=1 \
$(AM_CPPFLAGS)
httpstatus_fuzzer_SOURCES = \
$(loolwsd_sources) \
$(loolforkit_sources) \
$(shared_sources) \
fuzzer/HttpStatus.cpp
httpstatus_fuzzer_LDFLAGS = -fsanitize=fuzzer $(AM_LDFLAGS)
clientnb_SOURCES = net/clientnb.cpp \
common/Log.cpp \
common/StringVector.cpp \

View File

@ -0,0 +1,15 @@
#include <iostream>
#include "config.h"
#include <net/HttpRequest.hpp>
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
http::StatusLine statusLine;
int64_t length = size;
statusLine.parse(reinterpret_cast<const char*>(data), length);
return 0;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View File

@ -18,3 +18,15 @@ Run the fuzzers like this:
----
./clientsession_fuzzer -max_len=16384 fuzzer/data/
----
- HttpHeader (less useful, found no problems so far):
----
./httpheader_fuzzer -max_len=16384 fuzzer/httpheader-data/
----
- HttpStatus:
----
./httpstatus_fuzzer -max_len=16384 fuzzer/httpstatus-data/
----

View File

@ -0,0 +1,2 @@
HTTP/1.1 101
t

View File

@ -0,0 +1 @@
HTTP/1.1 101 Something Something

View File

@ -259,7 +259,13 @@ FieldParseState StatusLine::parse(const char* p, int64_t& len)
}
}
_reasonPhrase = std::string(&p[reasonOff], off - reasonOff - 1); // Exclude '\r'.
int64_t stringSize = off - reasonOff - 1; // Exclude '\r'.
if (stringSize < 0)
{
LOG_ERR("StatusLine::parse: missing line break");
return FieldParseState::Invalid;
}
_reasonPhrase = std::string(&p[reasonOff], stringSize);
// Consume the line breaks.
for (; off < len; ++off)