The max input size is 16384, so in case the input is saved after each
run, then this can allocate ~300MB of memory. This is considerable
amount, given that the upper limit of the fuzzer process is 2GB.
Signed-off-by: Miklos Vajna <vmiklos@collabora.com>
Change-Id: Ieedb6a537d5b539255ed8bacd79ff23db3c15e9f
This improves the performance of fuzzing
and removes the checks that can't be guaranteed.
And fixes a test failure.
Change-Id: I987fe15b098c00d9a3d60077f0581d2ef35e306c
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
This is a full round-trip http fuzzer.
It can achieve >1000 iterations per second
on a single 2 Ghz core, even while going
through the network loopback layer.
The advantage is that more networking code
is fuzzed this way, including not just
the http code, but also the sockets.
Change-Id: I75d21bd0e25221ee6621097a2605d62c4bb2ae4d
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
The DocumentBroker dtor adds a callback:
#0 SocketPoll::addCallback(std::function<void ()> const&) (this=0x377dce0 <Admin::instance()::admin>, fn=...) at ./net/Socket.hpp:773
#1 0x0000000000947db5 in Admin::rmDoc (this=<optimized out>, docKey=...) at wsd/Admin.cpp:544
#2 0x0000000000bb8192 in DocumentBroker::~DocumentBroker (this=0x61900000e690) at wsd/DocumentBroker.cpp:579
So even if the fuzzer called Admin::instance().poll() on shutdown, there
was one more callback inserted to the list later, leading to OOM in the
long run.
Signed-off-by: Miklos Vajna <vmiklos@collabora.com>
Change-Id: I0832d839b098407fa9e8aadb6f84388a85d62323
An alternative would be to tweak online-fuzz/wsd/DocumentBroker.cpp:534
to check for Util::isFuzzing(), but this is probably a better & more
generic way.
'./clientsession_fuzzer fuzzer/data/load' now works again.
Signed-off-by: Miklos Vajna <vmiklos@collabora.com>
Change-Id: I4d9fa387597695ff0802b268bc4d86be51dbabb2
HttpResponse covers http::Response::readData(), HttpStatus covered
http::StatusLine::parse(). The first calls the second, so remove the
second.
Signed-off-by: Miklos Vajna <vmiklos@collabora.com>
Change-Id: I163819ca470b766a7bc4694a9c6cfe4919e17963
And remove the httpheader one, which is not useful, since it uses Poco
for the actual parsing, it did not find anything. (If we switch away
from Poco there in the future, it's easy enough to restore it.)
Also fix some problems found by the fuzzer.
Signed-off-by: Miklos Vajna <vmiklos@collabora.com>
Change-Id: I254247c46ecc78c9c3e75aac4f10c441b0e10fb3
And fix an unhandled std::length_error it found.
Signed-off-by: Miklos Vajna <vmiklos@collabora.com>
Change-Id: I571cdd71caeda84820f2c64088966936637ce2bf
Run the actual fuzzer like this:
./httpheader_fuzzer -max_len=16384 fuzzer/httpheader-data/
Signed-off-by: Miklos Vajna <vmiklos@collabora.com>
Change-Id: I91afe44a632826cc15bd1c338bcc5234582e9674
fuzzers build was failing with:
In file included from fuzzer/Admin.cpp:3:
In file included from ./wsd/Admin.hpp:12:
In file included from ./wsd/AdminModel.hpp:20:
In file included from ./net/WebSocketHandler.hpp:18:
./net/HttpRequest.hpp:667:31: error: expected ')'
_header.add("Server", HTTP_SERVER_STRING);
^
./common/Common.hpp:62:51: note: expanded from macro 'HTTP_SERVER_STRING'
#define HTTP_SERVER_STRING "LOOLWSD HTTP Server " LOOLWSD_VERSION
^
./net/HttpRequest.hpp:667:20: note: to match this '('
_header.add("Server", HTTP_SERVER_STRING);
^
Signed-off-by: Miklos Vajna <vmiklos@collabora.com>
Change-Id: Ibc3905e3e62e0eb9788b750971916ff4a4937f12
Happens when renderfont is called without first loading a document.
Signed-off-by: Miklos Vajna <vmiklos@collabora.com>
Change-Id: I1152d1f4b3f610364e22c406cda5494672f20aed
The fuzzer ran out of memory, 955443527 bytes (79%) of the used memory
was this map.
Change-Id: I2dd84a094d3dd3d98618667e3c78591e2193bce2
Signed-off-by: Miklos Vajna <vmiklos@collabora.com>
This can happen on a 'savetostorage' which is after a failed load.
Change-Id: Iad26bf6415c772c8646a119b0454c202873d6860
Signed-off-by: Miklos Vajna <vmiklos@collabora.com>
Also decrease the poll timeout to 0, otherwise testing each input would
now take 5 sec, rather than ~3 ms.
Change-Id: I1a4f347e5ec08a62d40131bfec3c504a19727323
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/95437
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
This avoids depending on LOOLWSD's statics, which
makes adding unit-tests much more difficult due to
the high number of dependencies LOOLWSD pulls.
Adds a number of unit-tests for RequestDetails.
Change-Id: I9f1d56f80a633505c7ff548ec0e33ffe61f59f53
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/95290
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Tested-by: Jenkins
Reviewed-by: Ashod Nakashian <ashnakash@gmail.com>
So that one does not have to search back the commit messages to get the
commandlines to run these.
Change-Id: I3acfc0fa5b38577f22f6248a8ae0705e6af68940
And bypass configuration access at two new places, so the fuzzer can
find more interesting failures.
Change-Id: I4c09172e781a7c6120b8c4befe1a84fdd74f2ddc
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/93617
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Also adds ServiceRoot handling for clipboard.
Change-Id: I7bc6591130fcc7d693e59ab8561fb9e99f4e93d5
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/93578
Tested-by: Michael Meeks <michael.meeks@collabora.com>
Reviewed-by: Michael Meeks <michael.meeks@collabora.com>
Don't pop an empty container, also use stol() so it does not throw
std::out_of_range.
Change-Id: Id81cb00ccfb0ecc234b8f6fa89edf5a0d8c6d353
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/92524
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
This is no longer a huge problem, but it's still a good idea to return
early in that case.
Found with the recently added admin_fuzzer, when I locally disabled the
StringVector safety checks for test purposes.
(If you view the diff with -U30, then you see that we access tokens[2]
later, so if size is < 3, we should give up.)
Change-Id: I46fc531fb042cc1485a17a9e994ad37e9ff0cd80
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/91587
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
==15956==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x0000007cd2f7 bp 0x7ffe96c7cd70 sp 0x7ffe96c7c4e8 T0)
...
#7 0x11a9d31 in ClientSession::filterMessage(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const wsd/ClientSession.cpp:977:27
#8 0x11925d6 in ClientSession::_handleInput(char const*, int) wsd/ClientSession.cpp:741:14
#9 0x19395d0 in Session::handleMessage(bool, WSOpCode, std::vector<char, std::allocator<char> >&) common/Session.cpp:230:13
This seems to be a recurring pattern, I'll consider reworking
LOOLProtocol::tokenize() in a follow-up commit to have a return value
that is safer than std::vector<std::string>.
Change-Id: I0e71214a55af2e71e4787cb0dba0ddf7825bf9d9
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/89637
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Admin::instance().dumpState(std::cerr) at the end of a run shows:
Poll [0] - wakeup r: 11 w: 12
callbacks: 103
fd events rsize wsize
This is more a problem in the fuzzer itself than in the code, the
unprocessed callbacks reached the intentionally set 2GB limit in about
20 mins, so process them at the end of each run.
Change-Id: Ic12d3e8555417371f4ca44228fc1ff515d704592
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/89632
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
- target ClientSession::_handleInput(), since crashing there would bring
down the whole loolwsd (not just a kit process), and it deals with
input from untrusted users (browsers)
- add a --enable-fuzzers configure switch to build with
-fsanitize=fuzzer (compared to normal sanitizers build, this is the only
special flag needed)
- configuring other sanitizers is not done automatically, either use
--with-sanitizer=... or the environment variables from LODE's sanitizer
config
- run the actual fuzzer like this:
./clientsession_fuzzer -max_len=16384 fuzzer/data/
- note that at least openSUSE Leap 15.1 sadly ships with a clang with
libfuzzer static libs removed from the package, so you need a
self-built clang to run the fuzzer (either manual build or one from
LODE)
- <https://chromium.googlesource.com/chromium/src/testing/libfuzzer/+/refs/heads/master/efficient_fuzzing.md#execution-speed>
suggests that "You should aim for at least 1,000 exec/s from your fuzz
target locally" (i.e. one run should not take more than 1 ms), so try
this minimal approach first. The alternative would be to start from the
existing loolwsd_fuzzer binary, then step by step cut it down to not
fork(), not do any network traffic, etc -- till it's fast enough that
the fuzzer can find interesting input
- the various configurations start to be really complex (the matrix is
just very large), so try to use Util::isFuzzing() for fuzzer-specific
changes (this is what core.git does as well), and only resort to ifdefs
for the Util::isFuzzing() itself
Change-Id: I72dc1193b34c93eacb5d8e39cef42387d42bd72f
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/89226
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-by: Michael Meeks <michael.meeks@collabora.com>
==13901==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000000904678 bp 0x7ffdb9e21580 sp 0x7ffdb9e21340 T0)
==13901==The signal is caused by a READ memory access.
==13901==Hint: address points to the zero page.
#0 0x904677 in LOOLProtocol::tokenize[abi:cxx11](char const*, unsigned long, char) common/Protocol.hpp:113:40
#1 0x898c52 in LOOLProtocol::tokenize(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char) common/Protocol.hpp:141:16
#2 0x18dc2d9 in LOOLProtocol::ParseVersion(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) common/Protocol.cpp:35:51
#3 0x1148824 in ClientSession::_handleInput(char const*, int) wsd/ClientSession.cpp:358:64
#4 0x18efcb8 in Session::handleMessage(bool, WSOpCode, std::vector<char, std::allocator<char> >&) common/Session.cpp:232:13
Next commit will add the actual simple fuzzer that found this.
Change-Id: I8623b4451a57390f6f84c11084c5a1120a11fcc5
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/89225
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-by: Michael Meeks <michael.meeks@collabora.com>