libreoffice-online/fuzzer/ClientSession.cpp

59 lines
1.8 KiB
C++
Raw Normal View History

Add an initial libfuzzer based fuzzer - 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>
2020-02-21 08:52:20 -06:00
#include <iostream>
#include "config.h"
Add an initial libfuzzer based fuzzer - 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>
2020-02-21 08:52:20 -06:00
#include "ClientSession.hpp"
#include <fuzzer/Common.hpp>
Add an initial libfuzzer based fuzzer - 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>
2020-02-21 08:52:20 -06:00
bool DoInitialization()
{
COOLWSD::ChildRoot = "/fuzz/child-root";
UnitBase::init(UnitBase::UnitType::Wsd, std::string());
fuzzer::DoInitialization();
Add an initial libfuzzer based fuzzer - 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>
2020-02-21 08:52:20 -06:00
return true;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
static bool initialized = DoInitialization();
(void)initialized;
std::string uri;
Poco::URI uriPublic;
std::string docKey = "/fuzz/fuzz.odt";
auto docBroker = std::make_shared<DocumentBroker>(DocumentBroker::ChildType::Interactive, uri,
uriPublic, docKey, 0, nullptr);
Add an initial libfuzzer based fuzzer - 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>
2020-02-21 08:52:20 -06:00
std::shared_ptr<ProtocolHandlerInterface> ws;
Add an initial libfuzzer based fuzzer - 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>
2020-02-21 08:52:20 -06:00
std::string id;
bool isReadOnly = false;
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, uri,
Poco::Net::HTTPMessage::HTTP_1_1);
request.setHost("localhost:9980");
const RequestDetails requestDetails(request, "");
Add an initial libfuzzer based fuzzer - 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>
2020-02-21 08:52:20 -06:00
auto session
= std::make_shared<ClientSession>(ws, id, docBroker, uriPublic, isReadOnly, requestDetails);
Add an initial libfuzzer based fuzzer - 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>
2020-02-21 08:52:20 -06:00
std::string input(reinterpret_cast<const char*>(data), size);
std::stringstream ss(input);
std::string line;
while (std::getline(ss, line, '\n'))
{
std::vector<char> lineVector(line.data(), line.data() + line.size());
session->handleMessage(lineVector);
Add an initial libfuzzer based fuzzer - 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>
2020-02-21 08:52:20 -06:00
}
// The DocumentBroker dtor grows SocketPoll::_newCallbacks.
docBroker.reset();
// Make sure SocketPoll::_newCallbacks does not grow forever, leading to OOM.
Admin::instance().poll(std::chrono::microseconds(0));
// Make sure the anon map does not grow forever, leading to OOM.
Util::clearAnonymized();
Add an initial libfuzzer based fuzzer - 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>
2020-02-21 08:52:20 -06:00
return 0;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */