summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Windisch <eric@cloudscaling.com>2013-02-12 01:13:17 -0500
committerEric Windisch <eric@cloudscaling.com>2013-03-12 15:28:14 -0400
commit40640215468b1fe7f7b17c299c658e94f82e7d70 (patch)
treee9d914b6c2400ec065b58ef42b451a752854b268
parent21925b63af87c36be97eec5b212e06477471bb1e (diff)
Sanitize input before creating IPC socket.
Sockets are created by the zeromq driver for the topic specified by each incoming message. Because the topic is arbitrarily supplied by the sender, path separators in the topic must be illegal. Fixes bug 1122763 Change-Id: Iccdb9b69e646bfe7665ee34c367fd4019db25f17
-rw-r--r--openstack/common/rpc/impl_zmq.py10
-rw-r--r--tests/unit/rpc/test_zmq.py19
2 files changed, 29 insertions, 0 deletions
diff --git a/openstack/common/rpc/impl_zmq.py b/openstack/common/rpc/impl_zmq.py
index 7af9cd0..87f8d21 100644
--- a/openstack/common/rpc/impl_zmq.py
+++ b/openstack/common/rpc/impl_zmq.py
@@ -16,6 +16,7 @@
import os
import pprint
+import re
import socket
import sys
import types
@@ -431,6 +432,8 @@ class ZmqProxy(ZmqBaseReactor):
def __init__(self, conf):
super(ZmqProxy, self).__init__(conf)
+ pathsep = set((os.path.sep or '', os.path.altsep or '', '/', '\\'))
+ self.badchars = re.compile(r'[%s]' % re.escape(''.join(pathsep)))
self.topic_proxy = {}
@@ -456,6 +459,13 @@ class ZmqProxy(ZmqBaseReactor):
LOG.info(_("Creating proxy for topic: %s"), topic)
try:
+ # The topic is received over the network,
+ # don't trust this input.
+ if self.badchars.search(topic) is not None:
+ emsg = _("Topic contained dangerous characters.")
+ LOG.warn(emsg)
+ raise RPCException(emsg)
+
out_sock = ZmqSocket("ipc://%s/zmq_topic_%s" %
(ipc_dir, topic),
sock_type, bind=True)
diff --git a/tests/unit/rpc/test_zmq.py b/tests/unit/rpc/test_zmq.py
index c197c35..d42a07d 100644
--- a/tests/unit/rpc/test_zmq.py
+++ b/tests/unit/rpc/test_zmq.py
@@ -21,6 +21,7 @@ Unit Tests for remote procedure calls using zeromq
import eventlet
eventlet.monkey_patch()
+import itertools
import logging
import os
import socket
@@ -100,6 +101,24 @@ class _RpcZmqBaseTestCase(common.BaseRpcTestCase):
if self.reactor:
self.reactor.close()
+ def test_cast_pathsep_topic(self):
+ """Ensure topics with a contain a path separator result in error."""
+ tmp_topic = self.topic_nested
+
+ # All OS path separators
+ badchars = itertools.ifilter(None,
+ set((os.sep, os.altsep, '/', '\\')))
+ for char in badchars:
+ self.topic_nested = char.join(('hello', 'world'))
+ try:
+ # TODO(ewindisch): Determine which exception is raised.
+ # pending bug #1121348
+ self.assertRaises(Exception, self._test_cast,
+ common.TestReceiver.echo, 42, {"value": 42},
+ fanout=False)
+ finally:
+ self.topic_nested = tmp_topic
+
class RpcZmqBaseTopicTestCase(_RpcZmqBaseTestCase):
"""