mirror of
https://github.com/zeromq/libzmq.git
synced 2025-11-07 05:58:45 +01:00
Problem: Possible buffer overruns related to metadata in various mechanisms (#2683)
* Problem: no test case with CURVE encryption and large identity Solution: added test case (currently crashing) * Problem: possible buffer overflow in mechanism_t::add_property Solution: add target buffer length parameter and check the buffer is sufficiently large * Problem: test cases accidentally excluded from build Solution: remove #if/#endif * Problem: possible buffer overruns related to metadata at various locations Solution: allocate buffer large enough for actual metadata, reduce code duplication * Problem: syntax error related to pointer type conversion Solution: change argument type of make_command_with_basic_properties to const char * * Problem: large metadata may cause an assertion in produce_initiate Solution: Allow metadata of arbitrary size in produce_initiate
This commit is contained in:
committed by
Luca Boccassi
parent
d5e4319edc
commit
4a18f6204c
@@ -82,11 +82,28 @@ const char *zmq::mechanism_t::socket_type_string (int socket_type) const
|
||||
return names [socket_type];
|
||||
}
|
||||
|
||||
size_t zmq::mechanism_t::add_property (unsigned char *ptr, const char *name,
|
||||
const void *value, size_t value_len)
|
||||
static size_t property_len (size_t name_len, size_t value_len)
|
||||
{
|
||||
return 1 + name_len + 4 + value_len;
|
||||
}
|
||||
|
||||
static size_t name_len (const char *name)
|
||||
{
|
||||
const size_t name_len = strlen (name);
|
||||
zmq_assert (name_len <= 255);
|
||||
return name_len;
|
||||
}
|
||||
|
||||
size_t zmq::mechanism_t::add_property (unsigned char *ptr,
|
||||
size_t ptr_capacity,
|
||||
const char *name,
|
||||
const void *value,
|
||||
size_t value_len)
|
||||
{
|
||||
const size_t name_len = ::name_len (name);
|
||||
const size_t total_len = ::property_len (name_len, value_len);
|
||||
zmq_assert (total_len <= ptr_capacity);
|
||||
|
||||
*ptr++ = static_cast <unsigned char> (name_len);
|
||||
memcpy (ptr, name, name_len);
|
||||
ptr += name_len;
|
||||
@@ -95,11 +112,66 @@ size_t zmq::mechanism_t::add_property (unsigned char *ptr, const char *name,
|
||||
ptr += 4;
|
||||
memcpy (ptr, value, value_len);
|
||||
|
||||
return 1 + name_len + 4 + value_len;
|
||||
return total_len;
|
||||
}
|
||||
|
||||
size_t zmq::mechanism_t::property_len (const char *name, size_t value_len)
|
||||
{
|
||||
return ::property_len (name_len (name), value_len);
|
||||
}
|
||||
|
||||
size_t zmq::mechanism_t::add_basic_properties (unsigned char *buf,
|
||||
size_t buf_capacity) const
|
||||
{
|
||||
unsigned char *ptr = buf;
|
||||
|
||||
// Add socket type property
|
||||
const char *socket_type = socket_type_string (options.type);
|
||||
ptr += add_property (ptr, buf_capacity,
|
||||
ZMQ_MSG_PROPERTY_SOCKET_TYPE, socket_type,
|
||||
strlen (socket_type));
|
||||
|
||||
// Add identity property
|
||||
if (options.type == ZMQ_REQ || options.type == ZMQ_DEALER
|
||||
|| options.type == ZMQ_ROUTER)
|
||||
ptr += add_property (ptr, buf_capacity - (ptr - buf),
|
||||
ZMQ_MSG_PROPERTY_IDENTITY, options.identity,
|
||||
options.identity_size);
|
||||
|
||||
return ptr - buf;
|
||||
}
|
||||
|
||||
size_t zmq::mechanism_t::basic_properties_len() const
|
||||
{
|
||||
const char *socket_type = socket_type_string (options.type);
|
||||
return property_len (ZMQ_MSG_PROPERTY_SOCKET_TYPE, strlen (socket_type))
|
||||
+ ((options.type == ZMQ_REQ || options.type == ZMQ_DEALER
|
||||
|| options.type == ZMQ_ROUTER)
|
||||
? property_len (ZMQ_MSG_PROPERTY_IDENTITY,
|
||||
options.identity_size)
|
||||
: 0);
|
||||
}
|
||||
|
||||
void zmq::mechanism_t::make_command_with_basic_properties (
|
||||
msg_t *msg_, const char *prefix, size_t prefix_len) const
|
||||
{
|
||||
const size_t command_size = prefix_len + basic_properties_len ();
|
||||
const int rc = msg_->init_size (command_size);
|
||||
errno_assert (rc == 0);
|
||||
|
||||
unsigned char *ptr = (unsigned char *) msg_->data ();
|
||||
|
||||
// Add prefix
|
||||
memcpy (ptr, prefix, prefix_len);
|
||||
ptr += prefix_len;
|
||||
|
||||
ptr += add_basic_properties (
|
||||
ptr, command_size - (ptr - (unsigned char *) msg_->data ()));
|
||||
}
|
||||
|
||||
int zmq::mechanism_t::parse_metadata (const unsigned char *ptr_,
|
||||
size_t length_, bool zap_flag)
|
||||
size_t length_,
|
||||
bool zap_flag)
|
||||
{
|
||||
size_t bytes_left = length_;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user