[Libreoffice-commits] online.git: 2 commits - common/Session.cpp common/Unit.hpp test/UnitFuzz.cpp wsd/LOOLWSD.cpp
Michael Meeks
michael.meeks at collabora.com
Thu Dec 8 14:53:19 UTC 2016
common/Session.cpp | 17 ++++++--
common/Unit.hpp | 15 +++++++
test/UnitFuzz.cpp | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++---
wsd/LOOLWSD.cpp | 6 ++-
4 files changed, 130 insertions(+), 10 deletions(-)
New commits:
commit 4c2e59c1f22bdf74167e7fad97e7aa9549d03d3e
Author: Michael Meeks <michael.meeks at collabora.com>
Date: Thu Dec 8 14:52:31 2016 +0000
Don't take down WSD with an assert on a badly formed URI.
diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp
index 277ace6..16802e1 100644
--- a/wsd/LOOLWSD.cpp
+++ b/wsd/LOOLWSD.cpp
@@ -1256,7 +1256,11 @@ public:
{
LOG_TRC("Child connection with URI [" << request.getURI() << "].");
assert(request.serverAddress().port() == MasterPortNumber);
- assert(request.getURI().find(NEW_CHILD_URI) == 0);
+ if (request.getURI().find(NEW_CHILD_URI) != 0)
+ {
+ LOG_ERR("Invalid incoming URI.");
+ return;
+ }
// New Child is spawned.
const auto params = Poco::URI(request.getURI()).getQueryParameters();
commit 7cf77c26f7c923a2ea4f34410f0b83f84c37dde6
Author: Michael Meeks <michael.meeks at collabora.com>
Date: Wed Dec 7 21:32:08 2016 +0000
Improved fuzzer - to fuzz input.
Pass --unitlib=test/.libs/unit-fuzz.so to loolwsd to enable.
diff --git a/common/Session.cpp b/common/Session.cpp
index e1a3f36..5ead325 100644
--- a/common/Session.cpp
+++ b/common/Session.cpp
@@ -39,6 +39,7 @@
#include "Log.hpp"
#include "TileCache.hpp"
#include "Util.hpp"
+#include "Unit.hpp"
using namespace LOOLProtocol;
@@ -222,22 +223,30 @@ bool LOOLSession::handleInput(const char *buffer, int length)
{
assert(buffer != nullptr);
- const auto summary = getAbbreviatedMessage(buffer, length);
try
{
- LOG_TRC(getName() << ": Recv: " << summary);
+ std::unique_ptr< std::vector<char> > replace;
+ if (UnitBase::get().filterSessionInput(this, buffer, length, replace))
+ {
+ buffer = replace->data();
+ length = replace->size();
+ }
+
+ LOG_TRC(getName() << ": Recv: " << getAbbreviatedMessage(buffer, length));
return _handleInput(buffer, length);
}
catch (const Exception& exc)
{
- LOG_ERR("LOOLSession::handleInput: Exception while handling [" << summary <<
+ LOG_ERR("LOOLSession::handleInput: Exception while handling [" <<
+ getAbbreviatedMessage(buffer, length) <<
"] in " << getName() << ": " << exc.displayText() <<
(exc.nested() ? " (" + exc.nested()->displayText() + ")" : ""));
}
catch (const std::exception& exc)
{
- LOG_ERR("LOOLSession::handleInput: Exception while handling [" << summary << "]: " << exc.what());
+ LOG_ERR("LOOLSession::handleInput: Exception while handling [" <<
+ getAbbreviatedMessage(buffer, length) << "]: " << exc.what());
}
return false;
diff --git a/common/Unit.hpp b/common/Unit.hpp
index 7b6c6f8..40f20b3 100644
--- a/common/Unit.hpp
+++ b/common/Unit.hpp
@@ -38,6 +38,7 @@ namespace Poco
}
}
+class LOOLSession;
class StorageBase;
typedef UnitBase *(CreateUnitHooksFunction)();
@@ -88,6 +89,20 @@ public:
/// Tweak the return value from the process.
virtual void returnValue(int& /* retValue */);
+ /// Input message either for WSD or Kit
+ virtual bool filterSessionInput(LOOLSession *, const char */* buffer */,
+ int /* length */,
+ std::unique_ptr< std::vector<char> > & /* replace */)
+ {
+ return false;
+ }
+
+ static UnitBase& get()
+ {
+ assert(Global);
+ return *static_cast<UnitBase *>(Global);
+ }
+
private:
void setHandle(void *dlHandle) { _dlHandle = dlHandle; }
static UnitBase *linkAndCreateUnit(UnitType type, const std::string& unitLibPath);
diff --git a/test/UnitFuzz.cpp b/test/UnitFuzz.cpp
index fba1d73..1363ae7 100644
--- a/test/UnitFuzz.cpp
+++ b/test/UnitFuzz.cpp
@@ -13,6 +13,7 @@
#include <iostream>
#include <sys/types.h>
#include <dirent.h>
+#include <random>
#include "Common.hpp"
#include "IoUtil.hpp"
@@ -23,22 +24,113 @@
#include <Poco/Timestamp.h>
#include <Poco/StringTokenizer.h>
+#include <Poco/Net/HTTPServerRequest.h>
// Inside the WSD process
class UnitFuzz : public UnitWSD
{
+ std::random_device _rd;
+ std::mt19937 _mt;
+ std::uniform_int_distribution<> _dist;
public:
- UnitFuzz()
+ UnitFuzz() :
+ _mt(_rd()),
+ _dist(0, 1000)
{
- std::cerr << "UnitFuzz startup\n";
+ std::cerr << "\n\nYour WSD process is being randomly fuzzed\n\n\n";
setHasKitHooks();
+ setTimeout(3600 * 1000); /* one hour */
+ }
+
+ std::string corruptString(const std::string &str)
+ {
+ std::string ret;
+ for ( auto it = str.begin(); it != str.end(); ++it)
+ {
+ int op = _dist(_mt);
+ if (op < 10) {
+ switch (op) {
+ case 0:
+ ret += 0xff;
+ break;
+ case 1:
+ case 3:
+ ret += *it & 0x80;
+ break;
+ default:
+ ret += *it ^ _dist(_mt);
+ break;
+ }
+ }
+ }
+ return ret;
+ }
+
+ /*
+ * Note: Fuzzers are fragile and their performance is rather
+ * sensitive. Please avoid random code tweaking in this method.
+ */
+ virtual bool filterSessionInput(LOOLSession *, const char *buffer,
+ int length,
+ std::unique_ptr< std::vector<char> > &replace) override
+ {
+ // Avoid fuzzing most messages
+ if (_dist(_mt) < 875)
+ return false;
+
+ auto fuzzed = new std::vector<char>();
+ fuzzed->assign(buffer, buffer+length);
+
+ int resize = _dist(_mt);
+ if (resize < 50) { // truncate
+ size_t shrink = (fuzzed->size() * _dist(_mt))/1000;
+ fuzzed->resize(shrink);
+
+ } else if (resize < 200) {
+ bool prepend = resize < 100;
+ bool middle = resize < 150;
+ size_t count = 1 + _dist(_mt)/100;
+ for (size_t i = 0; i < count; ++i)
+ {
+ char c = (_dist(_mt) * 256 / 1000);
+ if (prepend)
+ fuzzed->insert(fuzzed->begin(), c);
+ else if (middle)
+ fuzzed->insert(fuzzed->begin() + fuzzed->size()/2, c);
+ else
+ fuzzed->push_back(c);
+ }
+ }
+
+ int numCorrupt = (_dist(_mt) / 100) - 75;
+ for (int i = 0; i < numCorrupt; ++i)
+ {
+ size_t offset = (_dist(_mt) * fuzzed->size() - 1) / 1000;
+ char c = (*fuzzed)[offset];
+ int change = _dist(_mt);
+ if (change < 256)
+ c ^= change;
+ else if (c >= '0' && c <= '9')
+ c = '0' + (change - 256)/100;
+ else
+ c |= 0x80;
+ }
+
+ replace.reset(fuzzed);
+
+ return true;
}
virtual bool filterHandleRequest(
TestRequest /* type */,
- Poco::Net::HTTPServerRequest& /* request */,
+ Poco::Net::HTTPServerRequest& request,
Poco::Net::HTTPServerResponse& /* response */) override
{
+ if (_dist(_mt) < 10) // 1%
+ {
+ std::cerr << "Mangle request URI\n";
+ request.setURI(corruptString(request.getURI()));
+ }
return false;
}
};
@@ -49,12 +141,12 @@ class UnitKitFuzz : public UnitKit
public:
UnitKitFuzz()
{
- std::cerr << "UnitKit Fuzz init !\n";
+ std::cerr << "\n\nYour KIT process has fuzzing hooks\n\n\n";
+ setTimeout(3600 * 1000); /* one hour */
}
~UnitKitFuzz()
{
}
-
virtual bool filterKitMessage(const std::shared_ptr<LOOLWebSocket> & /* ws */,
std::string & /* message */) override
{
More information about the Libreoffice-commits
mailing list