Commit f4fe375b authored by Brian Silverman's avatar Brian Silverman

Don't call memcpy with 0 size and NULL pointer(s)

It's undefined behavior, and ubsan flags it.
parent c9c9a777
...@@ -70,7 +70,8 @@ int zmq::dealer_t::xsetsockopt (int option_, const void *optval_, ...@@ -70,7 +70,8 @@ int zmq::dealer_t::xsetsockopt (int option_, const void *optval_,
size_t optvallen_) size_t optvallen_)
{ {
bool is_int = (optvallen_ == sizeof (int)); 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_) { switch (option_) {
case ZMQ_PROBE_ROUTER: case ZMQ_PROBE_ROUTER:
......
...@@ -92,7 +92,8 @@ int zmq::options_t::setsockopt (int option_, const void *optval_, ...@@ -92,7 +92,8 @@ int zmq::options_t::setsockopt (int option_, const void *optval_,
size_t optvallen_) size_t optvallen_)
{ {
bool is_int = (optvallen_ == sizeof (int)); 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) #if defined (ZMQ_ACT_MILITANT)
bool malformed = true; // Did caller pass a bad option value? bool malformed = true; // Did caller pass a bad option value?
#endif #endif
......
...@@ -204,7 +204,8 @@ bool zmq::req_t::xhas_out () ...@@ -204,7 +204,8 @@ bool zmq::req_t::xhas_out ()
int zmq::req_t::xsetsockopt (int option_, const void *optval_, size_t optvallen_) int zmq::req_t::xsetsockopt (int option_, const void *optval_, size_t optvallen_)
{ {
bool is_int = (optvallen_ == sizeof (int)); 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_) { switch (option_) {
case ZMQ_REQ_CORRELATE: case ZMQ_REQ_CORRELATE:
if (is_int && value >= 0) { if (is_int && value >= 0) {
......
...@@ -97,7 +97,8 @@ int zmq::router_t::xsetsockopt (int option_, const void *optval_, ...@@ -97,7 +97,8 @@ int zmq::router_t::xsetsockopt (int option_, const void *optval_,
size_t optvallen_) size_t optvallen_)
{ {
bool is_int = (optvallen_ == sizeof (int)); 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_) { switch (option_) {
case ZMQ_CONNECT_RID: case ZMQ_CONNECT_RID:
......
...@@ -178,7 +178,8 @@ int zmq::stream_t::xsetsockopt (int option_, const void *optval_, ...@@ -178,7 +178,8 @@ int zmq::stream_t::xsetsockopt (int option_, const void *optval_,
size_t optvallen_) size_t optvallen_)
{ {
bool is_int = (optvallen_ == sizeof (int)); 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_) { switch (option_) {
case ZMQ_CONNECT_RID: case ZMQ_CONNECT_RID:
if (optval_ && optvallen_) { if (optval_ && optvallen_) {
......
...@@ -62,7 +62,8 @@ int zmq::sub_t::xsetsockopt (int option_, const void *optval_, ...@@ -62,7 +62,8 @@ int zmq::sub_t::xsetsockopt (int option_, const void *optval_,
else else
if (option_ == ZMQ_UNSUBSCRIBE) if (option_ == ZMQ_UNSUBSCRIBE)
*data = 0; *data = 0;
memcpy (data + 1, optval_, optvallen_); if (optvallen_ > 0)
memcpy (data + 1, optval_, optvallen_);
// Pass it further on in the stack. // Pass it further on in the stack.
int err = 0; int err = 0;
......
...@@ -232,7 +232,8 @@ void zmq::xsub_t::send_subscription (unsigned char *data_, size_t size_, ...@@ -232,7 +232,8 @@ void zmq::xsub_t::send_subscription (unsigned char *data_, size_t size_,
errno_assert (rc == 0); errno_assert (rc == 0);
unsigned char *data = (unsigned char*) msg.data (); unsigned char *data = (unsigned char*) msg.data ();
data [0] = 1; data [0] = 1;
memcpy (data + 1, data_, size_); if (size_ > 0)
memcpy (data + 1, data_, size_);
// Send it to the pipe. // Send it to the pipe.
bool sent = pipe->write (&msg); bool sent = pipe->write (&msg);
......
...@@ -393,7 +393,8 @@ int zmq_send (void *s_, const void *buf_, size_t len_, int flags_) ...@@ -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_); int rc = zmq_msg_init_size (&msg, len_);
if (rc != 0) if (rc != 0)
return -1; 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_; zmq::socket_base_t *s = (zmq::socket_base_t *) s_;
rc = s_sendmsg (s, &msg, flags_); rc = s_sendmsg (s, &msg, flags_);
...@@ -519,7 +520,8 @@ int zmq_recv (void *s_, void *buf_, size_t len_, int 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. // At the moment an oversized message is silently truncated.
// TODO: Build in a notification mechanism to report the overflows. // TODO: Build in a notification mechanism to report the overflows.
size_t to_copy = size_t (nbytes) < len_ ? size_t (nbytes) : len_; 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); rc = zmq_msg_close (&msg);
errno_assert (rc == 0); errno_assert (rc == 0);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment