From f4fe375bd1a650209c37ab3c4de09830dbe6d3f7 Mon Sep 17 00:00:00 2001 From: Brian Silverman Date: Fri, 5 Feb 2016 14:04:22 -0500 Subject: [PATCH] Don't call memcpy with 0 size and NULL pointer(s) It's undefined behavior, and ubsan flags it. --- src/dealer.cpp | 3 ++- src/options.cpp | 3 ++- src/req.cpp | 3 ++- src/router.cpp | 3 ++- src/stream.cpp | 3 ++- src/sub.cpp | 3 ++- src/xsub.cpp | 3 ++- src/zmq.cpp | 6 ++++-- 8 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/dealer.cpp b/src/dealer.cpp index 3d7b62b8..ce182224 100644 --- a/src/dealer.cpp +++ b/src/dealer.cpp @@ -70,7 +70,8 @@ int zmq::dealer_t::xsetsockopt (int option_, const void *optval_, size_t optvallen_) { bool is_int = (optvallen_ == sizeof (int)); - int value = is_int? *((int *) optval_): 0; + int value = 0; + if (is_int) memcpy(&value, optval_, sizeof (int)); switch (option_) { case ZMQ_PROBE_ROUTER: diff --git a/src/options.cpp b/src/options.cpp index 1acabae1..3f8fa639 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -92,7 +92,8 @@ int zmq::options_t::setsockopt (int option_, const void *optval_, size_t optvallen_) { bool is_int = (optvallen_ == sizeof (int)); - int value = is_int? *((int *) optval_): 0; + int value = 0; + if (is_int) memcpy(&value, optval_, sizeof (int)); #if defined (ZMQ_ACT_MILITANT) bool malformed = true; // Did caller pass a bad option value? #endif diff --git a/src/req.cpp b/src/req.cpp index 1f7fad60..3aec0751 100644 --- a/src/req.cpp +++ b/src/req.cpp @@ -204,7 +204,8 @@ bool zmq::req_t::xhas_out () int zmq::req_t::xsetsockopt (int option_, const void *optval_, size_t optvallen_) { bool is_int = (optvallen_ == sizeof (int)); - int value = is_int? *((int *) optval_): 0; + int value = 0; + if (is_int) memcpy(&value, optval_, sizeof (int)); switch (option_) { case ZMQ_REQ_CORRELATE: if (is_int && value >= 0) { diff --git a/src/router.cpp b/src/router.cpp index 64a16628..1beba58d 100644 --- a/src/router.cpp +++ b/src/router.cpp @@ -97,7 +97,8 @@ int zmq::router_t::xsetsockopt (int option_, const void *optval_, size_t optvallen_) { bool is_int = (optvallen_ == sizeof (int)); - int value = is_int? *((int *) optval_): 0; + int value = 0; + if (is_int) memcpy(&value, optval_, sizeof (int)); switch (option_) { case ZMQ_CONNECT_RID: diff --git a/src/stream.cpp b/src/stream.cpp index 1cffcc93..af8c730a 100644 --- a/src/stream.cpp +++ b/src/stream.cpp @@ -178,7 +178,8 @@ int zmq::stream_t::xsetsockopt (int option_, const void *optval_, size_t optvallen_) { bool is_int = (optvallen_ == sizeof (int)); - int value = is_int? *((int *) optval_): 0; + int value = 0; + if (is_int) memcpy(&value, optval_, sizeof (int)); switch (option_) { case ZMQ_CONNECT_RID: if (optval_ && optvallen_) { diff --git a/src/sub.cpp b/src/sub.cpp index f8eaf858..90ef672d 100644 --- a/src/sub.cpp +++ b/src/sub.cpp @@ -62,7 +62,8 @@ int zmq::sub_t::xsetsockopt (int option_, const void *optval_, else if (option_ == ZMQ_UNSUBSCRIBE) *data = 0; - memcpy (data + 1, optval_, optvallen_); + if (optvallen_ > 0) + memcpy (data + 1, optval_, optvallen_); // Pass it further on in the stack. int err = 0; diff --git a/src/xsub.cpp b/src/xsub.cpp index d8093e06..616e93bd 100644 --- a/src/xsub.cpp +++ b/src/xsub.cpp @@ -232,7 +232,8 @@ void zmq::xsub_t::send_subscription (unsigned char *data_, size_t size_, errno_assert (rc == 0); unsigned char *data = (unsigned char*) msg.data (); data [0] = 1; - memcpy (data + 1, data_, size_); + if (size_ > 0) + memcpy (data + 1, data_, size_); // Send it to the pipe. bool sent = pipe->write (&msg); diff --git a/src/zmq.cpp b/src/zmq.cpp index a041538d..60bb0fca 100644 --- a/src/zmq.cpp +++ b/src/zmq.cpp @@ -393,7 +393,8 @@ int zmq_send (void *s_, const void *buf_, size_t len_, int flags_) int rc = zmq_msg_init_size (&msg, len_); if (rc != 0) return -1; - memcpy (zmq_msg_data (&msg), buf_, len_); + if (len_ > 0) + memcpy (zmq_msg_data (&msg), buf_, len_); zmq::socket_base_t *s = (zmq::socket_base_t *) s_; rc = s_sendmsg (s, &msg, flags_); @@ -519,7 +520,8 @@ int zmq_recv (void *s_, void *buf_, size_t len_, int flags_) // At the moment an oversized message is silently truncated. // TODO: Build in a notification mechanism to report the overflows. size_t to_copy = size_t (nbytes) < len_ ? size_t (nbytes) : len_; - memcpy (buf_, zmq_msg_data (&msg), to_copy); + if (to_copy > 0) + memcpy (buf_, zmq_msg_data (&msg), to_copy); rc = zmq_msg_close (&msg); errno_assert (rc == 0);