Properly deserializes built-in exceptions
If the remote target and the caller have different python versions, then built-in exceptions raised by the remote target will not be properly deserialized on the caller. Because of this, oslo.messaging will simply raise a RemoteError, instead of any expected exceptions the caller might expect. This patch addresses this issue. Closes-Bug: #1630795 Change-Id: I6d9eaf5497e746be9766731172406ec624ef9ba7
This commit is contained in:
parent
f52e5cfbca
commit
da830016d5
@ -33,6 +33,7 @@ from oslo_messaging import _utils as utils
|
|||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
_EXCEPTIONS_MODULE = 'exceptions' if six.PY2 else 'builtins'
|
_EXCEPTIONS_MODULE = 'exceptions' if six.PY2 else 'builtins'
|
||||||
|
_EXCEPTIONS_MODULES = ['exceptions', 'builtins']
|
||||||
|
|
||||||
|
|
||||||
'''RPC Envelope Version.
|
'''RPC Envelope Version.
|
||||||
@ -208,6 +209,13 @@ def deserialize_remote_exception(data, allowed_remote_exmods):
|
|||||||
name = failure.get('class')
|
name = failure.get('class')
|
||||||
module = failure.get('module')
|
module = failure.get('module')
|
||||||
|
|
||||||
|
# the remote service which raised the given exception might have a
|
||||||
|
# different python version than the caller. For example, the caller might
|
||||||
|
# run python 2.7, while the remote service might run python 3.4. Thus,
|
||||||
|
# the exception module will be "builtins" instead of "exceptions".
|
||||||
|
if module in _EXCEPTIONS_MODULES:
|
||||||
|
module = _EXCEPTIONS_MODULE
|
||||||
|
|
||||||
# NOTE(ameade): We DO NOT want to allow just any module to be imported, in
|
# NOTE(ameade): We DO NOT want to allow just any module to be imported, in
|
||||||
# order to prevent arbitrary code execution.
|
# order to prevent arbitrary code execution.
|
||||||
if module != _EXCEPTIONS_MODULE and module not in allowed_remote_exmods:
|
if module != _EXCEPTIONS_MODULE and module not in allowed_remote_exmods:
|
||||||
|
@ -26,6 +26,7 @@ from oslo_messaging.tests import utils as test_utils
|
|||||||
load_tests = testscenarios.load_tests_apply_scenarios
|
load_tests = testscenarios.load_tests_apply_scenarios
|
||||||
|
|
||||||
EXCEPTIONS_MODULE = 'exceptions' if six.PY2 else 'builtins'
|
EXCEPTIONS_MODULE = 'exceptions' if six.PY2 else 'builtins'
|
||||||
|
OTHER_EXCEPTIONS_MODULE = 'builtins' if six.PY2 else 'exceptions'
|
||||||
|
|
||||||
|
|
||||||
class NovaStyleException(Exception):
|
class NovaStyleException(Exception):
|
||||||
@ -149,6 +150,17 @@ class DeserializeRemoteExceptionTestCase(test_utils.BaseTestCase):
|
|||||||
remote_name='Exception',
|
remote_name='Exception',
|
||||||
remote_args=('test\ntraceback\ntraceback\n', ),
|
remote_args=('test\ntraceback\ntraceback\n', ),
|
||||||
remote_kwargs={})),
|
remote_kwargs={})),
|
||||||
|
('different_python_versions',
|
||||||
|
dict(allowed=_standard_allowed,
|
||||||
|
clsname='Exception',
|
||||||
|
modname=OTHER_EXCEPTIONS_MODULE,
|
||||||
|
cls=Exception,
|
||||||
|
args=['test'],
|
||||||
|
kwargs={},
|
||||||
|
str='test\ntraceback\ntraceback\n',
|
||||||
|
remote_name='Exception',
|
||||||
|
remote_args=('test\ntraceback\ntraceback\n', ),
|
||||||
|
remote_kwargs={})),
|
||||||
('nova_style',
|
('nova_style',
|
||||||
dict(allowed=_standard_allowed,
|
dict(allowed=_standard_allowed,
|
||||||
clsname='NovaStyleException',
|
clsname='NovaStyleException',
|
||||||
|
Loading…
Reference in New Issue
Block a user