From 183f509f094020f3a30810a99108623e16863c6d Mon Sep 17 00:00:00 2001 From: Peter Surda Date: Mon, 15 May 2017 12:23:16 +0200 Subject: [PATCH] Decompression limit - there is now a configurable decompression limit, default at 1MB. Oversize messages are trated as if they never arrived, just a log entry --- src/class_objectProcessor.py | 3 ++- src/helper_msgcoding.py | 26 ++++++++++++++++++++++---- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/class_objectProcessor.py b/src/class_objectProcessor.py index ad78bd87..253e6808 100644 --- a/src/class_objectProcessor.py +++ b/src/class_objectProcessor.py @@ -28,7 +28,6 @@ import tr from debug import logger import l10n - class objectProcessor(threading.Thread): """ The objectProcessor thread, of which there is only one, receives network @@ -71,6 +70,8 @@ class objectProcessor(threading.Thread): pass else: logger.critical('Error! Bug! The class_objectProcessor was passed an object type it doesn\'t recognize: %s' % str(objectType)) + except helper_msgcoding.DecompressionSizeException as e: + logger.error("The object is too big after decompression (stopped decompressing at %ib, your configured limit %ib). Ignoring", e.size, BMConfigParser().safeGetInt("zlib", "maxsize")) except varintDecodeError as e: logger.debug("There was a problem with a varint while processing an object. Some details: %s" % e) except Exception as e: diff --git a/src/helper_msgcoding.py b/src/helper_msgcoding.py index 2acdd6a4..a507685e 100644 --- a/src/helper_msgcoding.py +++ b/src/helper_msgcoding.py @@ -7,6 +7,7 @@ except ImportError: import string import zlib +from bmconfigparser import BMConfigParser import shared from debug import logger import messagetypes @@ -17,6 +18,10 @@ BITMESSAGE_ENCODING_TRIVIAL = 1 BITMESSAGE_ENCODING_SIMPLE = 2 BITMESSAGE_ENCODING_EXTENDED = 3 +class DecompressionSizeException(Exception): + def __init__(self, size): + self.size = size + class MsgEncode(object): def __init__(self, message, encoding=BITMESSAGE_ENCODING_SIMPLE): @@ -65,11 +70,24 @@ class MsgDecode(object): self.subject = _translate("MsgDecode", "Unknown encoding") def decodeExtended(self, data): + dc = zlib.decompressobj() + tmp = "" + while len(tmp) <= BMConfigParser().safeGetInt("zlib", "maxsize"): + try: + got = dc.decompress(data, BMConfigParser().safeGetInt("zlib", "maxsize") + 1 - len(tmp)) + # EOF + if got == "": + break + tmp += got + data = dc.unconsumed_tail + except zlib.error: + logger.error("Error decompressing message") + raise + else: + raise DecompressionSizeException(len(tmp)) + try: - tmp = msgpack.loads(zlib.decompress(data)) - except zlib.error: - logger.error("Error decompressing message") - raise + tmp = msgpack.loads(tmp) except (msgpack.exceptions.UnpackException, msgpack.exceptions.ExtraData): logger.error("Error msgunpacking message")