summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Sustrik <sustrik@250bpm.com>2011-04-19 08:08:15 +0200
committerMartin Sustrik <sustrik@250bpm.com>2011-04-19 08:08:15 +0200
commit581697695aac72894f2d3fefac904b9d50b3ba67 (patch)
tree1cb79d95271bb924f039ad915347020ff94269dc
parent20e0b7cdcb6e8095fbadb80765e9371803184060 (diff)
Message validity is checked in the runtime
Signed-off-by: Martin Sustrik <sustrik@250bpm.com>
-rw-r--r--doc/zmq_msg_close.txt3
-rw-r--r--doc/zmq_msg_copy.txt3
-rw-r--r--doc/zmq_msg_move.txt3
-rw-r--r--doc/zmq_recv.txt2
-rw-r--r--doc/zmq_send.txt2
-rw-r--r--include/zmq.h1
-rw-r--r--src/msg.cpp40
-rw-r--r--src/req.cpp2
-rw-r--r--src/socket_base.cpp14
-rw-r--r--src/xrep.cpp2
10 files changed, 59 insertions, 13 deletions
diff --git a/doc/zmq_msg_close.txt b/doc/zmq_msg_close.txt
index 1da353b..e530e33 100644
--- a/doc/zmq_msg_close.txt
+++ b/doc/zmq_msg_close.txt
@@ -35,7 +35,8 @@ it shall return `-1` and set 'errno' to one of the values defined below.
ERRORS
------
-No errors are defined.
+*EFAULT*::
+Invalid message.
SEE ALSO
diff --git a/doc/zmq_msg_copy.txt b/doc/zmq_msg_copy.txt
index f41a42e..e393f03 100644
--- a/doc/zmq_msg_copy.txt
+++ b/doc/zmq_msg_copy.txt
@@ -37,7 +37,8 @@ shall return `-1` and set 'errno' to one of the values defined below.
ERRORS
------
-No errors are defined.
+*EFAULT*::
+Invalid message.
SEE ALSO
diff --git a/doc/zmq_msg_move.txt b/doc/zmq_msg_move.txt
index 75c8e74..f14a28f 100644
--- a/doc/zmq_msg_move.txt
+++ b/doc/zmq_msg_move.txt
@@ -32,7 +32,8 @@ shall return `-1` and set 'errno' to one of the values defined below.
ERRORS
------
-No errors are defined.
+*EFAULT*::
+Invalid message.
SEE ALSO
diff --git a/doc/zmq_recv.txt b/doc/zmq_recv.txt
index fe601ba..0b6e0e4 100644
--- a/doc/zmq_recv.txt
+++ b/doc/zmq_recv.txt
@@ -68,6 +68,8 @@ The provided 'socket' was invalid.
*EINTR*::
The operation was interrupted by delivery of a signal before a message was
available.
+*EFAULT*::
+The message passed to the function was invalid.
EXAMPLE
diff --git a/doc/zmq_send.txt b/doc/zmq_send.txt
index 2a63cc6..85ac3b7 100644
--- a/doc/zmq_send.txt
+++ b/doc/zmq_send.txt
@@ -78,6 +78,8 @@ The provided 'socket' was invalid.
*EINTR*::
The operation was interrupted by delivery of a signal before the message was
sent.
+*EFAULT*::
+Invalid message.
EXAMPLE
diff --git a/include/zmq.h b/include/zmq.h
index e6fb60d..70197c9 100644
--- a/include/zmq.h
+++ b/include/zmq.h
@@ -137,6 +137,7 @@ ZMQ_EXPORT const char *zmq_strerror (int errnum);
/* allows us to pack the stucture tigher and thus improve performance. */
#define ZMQ_MSG_MORE 1
#define ZMQ_MSG_SHARED 128
+#define ZMQ_MSG_MASK 129 /* Merges all the flags */
/* A message. Note that 'content' is not a pointer to the raw data. */
/* Rather it is pointer to zmq::msg_content_t structure */
diff --git a/src/msg.cpp b/src/msg.cpp
index e9d1da7..e800bd6 100644
--- a/src/msg.cpp
+++ b/src/msg.cpp
@@ -26,12 +26,13 @@
#include <new>
#include "stdint.hpp"
+#include "likely.hpp"
#include "err.hpp"
int zmq_msg_init (zmq_msg_t *msg_)
{
msg_->content = (zmq::msg_content_t*) ZMQ_VSM;
- msg_->flags = 0;
+ msg_->flags = (unsigned char) ~ZMQ_MSG_MASK;
msg_->vsm_size = 0;
return 0;
}
@@ -40,7 +41,7 @@ int zmq_msg_init_size (zmq_msg_t *msg_, size_t size_)
{
if (size_ <= ZMQ_MAX_VSM_SIZE) {
msg_->content = (zmq::msg_content_t*) ZMQ_VSM;
- msg_->flags = 0;
+ msg_->flags = (unsigned char) ~ZMQ_MSG_MASK;
msg_->vsm_size = (uint8_t) size_;
}
else {
@@ -50,7 +51,7 @@ int zmq_msg_init_size (zmq_msg_t *msg_, size_t size_)
errno = ENOMEM;
return -1;
}
- msg_->flags = 0;
+ msg_->flags = (unsigned char) ~ZMQ_MSG_MASK;
zmq::msg_content_t *content = (zmq::msg_content_t*) msg_->content;
content->data = (void*) (content + 1);
@@ -67,7 +68,7 @@ int zmq_msg_init_data (zmq_msg_t *msg_, void *data_, size_t size_,
{
msg_->content = (zmq::msg_content_t*) malloc (sizeof (zmq::msg_content_t));
alloc_assert (msg_->content);
- msg_->flags = 0;
+ msg_->flags = (unsigned char) ~ZMQ_MSG_MASK;
zmq::msg_content_t *content = (zmq::msg_content_t*) msg_->content;
content->data = data_;
content->size = size_;
@@ -79,6 +80,12 @@ int zmq_msg_init_data (zmq_msg_t *msg_, void *data_, size_t size_,
int zmq_msg_close (zmq_msg_t *msg_)
{
+ // Check the validity tag.
+ if (unlikely (msg_->flags | ZMQ_MSG_MASK) != 0xff) {
+ errno = EFAULT;
+ return -1;
+ }
+
// For VSMs and delimiters there are no resources to free.
if (msg_->content != (zmq::msg_content_t*) ZMQ_DELIMITER &&
msg_->content != (zmq::msg_content_t*) ZMQ_VSM) {
@@ -98,17 +105,21 @@ int zmq_msg_close (zmq_msg_t *msg_)
}
}
- // As a safety measure, let's make the deallocated message look like
- // an empty message.
- msg_->content = (zmq::msg_content_t*) ZMQ_VSM;
+ // Remove the validity tag from the message.
msg_->flags = 0;
- msg_->vsm_size = 0;
return 0;
}
int zmq_msg_move (zmq_msg_t *dest_, zmq_msg_t *src_)
{
+ // Check the validity tags.
+ if (unlikely ((dest_->flags | ZMQ_MSG_MASK) != 0xff ||
+ (src_->flags | ZMQ_MSG_MASK) != 0xff)) {
+ errno = EFAULT;
+ return -1;
+ }
+
zmq_msg_close (dest_);
*dest_ = *src_;
zmq_msg_init (src_);
@@ -117,6 +128,13 @@ int zmq_msg_move (zmq_msg_t *dest_, zmq_msg_t *src_)
int zmq_msg_copy (zmq_msg_t *dest_, zmq_msg_t *src_)
{
+ // Check the validity tags.
+ if (unlikely ((dest_->flags | ZMQ_MSG_MASK) != 0xff ||
+ (src_->flags | ZMQ_MSG_MASK) != 0xff)) {
+ errno = EFAULT;
+ return -1;
+ }
+
zmq_msg_close (dest_);
// VSMs and delimiters require no special handling.
@@ -140,6 +158,9 @@ int zmq_msg_copy (zmq_msg_t *dest_, zmq_msg_t *src_)
void *zmq_msg_data (zmq_msg_t *msg_)
{
+ // Check the validity tag.
+ zmq_assert ((msg_->flags | ZMQ_MSG_MASK) == 0xff);
+
if (msg_->content == (zmq::msg_content_t*) ZMQ_VSM)
return msg_->vsm_data;
if (msg_->content == (zmq::msg_content_t*) ZMQ_DELIMITER)
@@ -150,6 +171,9 @@ void *zmq_msg_data (zmq_msg_t *msg_)
size_t zmq_msg_size (zmq_msg_t *msg_)
{
+ // Check the validity tag.
+ zmq_assert ((msg_->flags | ZMQ_MSG_MASK) == 0xff);
+
if (msg_->content == (zmq::msg_content_t*) ZMQ_VSM)
return msg_->vsm_size;
if (msg_->content == (zmq::msg_content_t*) ZMQ_DELIMITER)
diff --git a/src/req.cpp b/src/req.cpp
index f495492..503f221 100644
--- a/src/req.cpp
+++ b/src/req.cpp
@@ -49,7 +49,7 @@ int zmq::req_t::xsend (zmq_msg_t *msg_, int flags_)
zmq_msg_t prefix;
int rc = zmq_msg_init (&prefix);
zmq_assert (rc == 0);
- prefix.flags = ZMQ_MSG_MORE;
+ prefix.flags |= ZMQ_MSG_MORE;
rc = xreq_t::xsend (&prefix, flags_);
if (rc != 0)
return rc;
diff --git a/src/socket_base.cpp b/src/socket_base.cpp
index c9b5c31..9f3b1f6 100644
--- a/src/socket_base.cpp
+++ b/src/socket_base.cpp
@@ -466,11 +466,18 @@ int zmq::socket_base_t::connect (const char *addr_)
int zmq::socket_base_t::send (::zmq_msg_t *msg_, int flags_)
{
+ // Check whether the library haven't been shut down yet.
if (unlikely (ctx_terminated)) {
errno = ETERM;
return -1;
}
+ // Check whether message passed to the function is valid.
+ if (unlikely ((msg_->flags | ZMQ_MSG_MASK) != 0xff)) {
+ errno = EFAULT;
+ return -1;
+ }
+
// Process pending commands, if any.
int rc = process_commands (false, true);
if (unlikely (rc != 0))
@@ -504,11 +511,18 @@ int zmq::socket_base_t::send (::zmq_msg_t *msg_, int flags_)
int zmq::socket_base_t::recv (::zmq_msg_t *msg_, int flags_)
{
+ // Check whether the library haven't been shut down yet.
if (unlikely (ctx_terminated)) {
errno = ETERM;
return -1;
}
+ // Check whether message passed to the function is valid.
+ if (unlikely ((msg_->flags | ZMQ_MSG_MASK) != 0xff)) {
+ errno = EFAULT;
+ return -1;
+ }
+
// Get the message.
int rc = xrecv (msg_, flags_);
int err = errno;
diff --git a/src/xrep.cpp b/src/xrep.cpp
index 7f0da4d..75dc30e 100644
--- a/src/xrep.cpp
+++ b/src/xrep.cpp
@@ -269,7 +269,7 @@ int zmq::xrep_t::xrecv (zmq_msg_t *msg_, int flags_)
zmq_assert (rc == 0);
memcpy (zmq_msg_data (msg_), inpipes [current_in].identity.data (),
zmq_msg_size (msg_));
- msg_->flags = ZMQ_MSG_MORE;
+ msg_->flags |= ZMQ_MSG_MORE;
return 0;
}