mitogen/core: Unpickle user defined classes from the (trusted) parent

The parent has other possibilities than doing attacks via malicious messages.
Therefore it's okay to trust the messages from the parents and use unsecure
unpickling methods.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
pull/1342/head
Marc Hartmayer 3 months ago
parent 5490cd74b4
commit 5b04049ce2

@ -792,8 +792,19 @@ if PY3:
# In 3.x Unpickler is a class exposing find_class as an overridable, but it
# cannot be overridden without subclassing.
class _Unpickler(pickle.Unpickler):
def __init__(self, *args, insecure=False, **kwargs):
super().__init__(*args, **kwargs)
self.__insecure = insecure
def find_class(self, module, func):
return self.find_global(module, func)
try:
return self.find_global(module, func)
except Exception as error:
if not self.__insecure:
raise error
return super().find_class(module, func)
pickle__dumps = pickle.dumps
elif PY24:
# On Python 2.4, we must use a pure-Python pickler.
@ -977,7 +988,7 @@ class Message(object):
else:
raise ChannelError(ChannelError.remote_msg)
def unpickle(self, throw=True, throw_dead=True):
def unpickle(self, throw=True, throw_dead=True, *, insecure=False):
"""
Unpickle :attr:`data`, optionally raising any exceptions present.
@ -985,6 +996,9 @@ class Message(object):
If :data:`True`, raise exceptions, otherwise it is the caller's
responsibility.
:param bool insecure:
If :data:`True`, also use possibly unsecure unpickling methods.
:raises CallError:
The serialized data contained CallError exception.
:raises ChannelError:
@ -997,7 +1011,7 @@ class Message(object):
obj = self._unpickled
if obj is Message._unpickled:
fp = BytesIO(self.data)
unpickler = _Unpickler(fp, **self.UNPICKLER_KWARGS)
unpickler = _Unpickler(fp, insecure=insecure, **self.UNPICKLER_KWARGS)
unpickler.find_global = self._find_global
try:
# Must occur off the broker thread.
@ -3844,7 +3858,7 @@ class Dispatcher(object):
econtext.dispatcher._error_by_chain_id.pop(chain_id, None)
def _parse_request(self, msg):
data = msg.unpickle(throw=False)
data = msg.unpickle(throw=False, insecure=True)
_v and LOG.debug('%r: dispatching %r', self, data)
chain_id, modname, klass, func, args, kwargs = data

Loading…
Cancel
Save