Skip to content

Commit

Permalink
added AMQP malloc checks (#453)
Browse files Browse the repository at this point in the history
* mollc size checks

* merge with main

* Update src/amqpvalue.c

Co-authored-by: Ewerton Scaboro da Silva <[email protected]>

* Update src/header_detect_io.c

Co-authored-by: Ewerton Scaboro da Silva <[email protected]>

* Update src/session.c

Co-authored-by: Ewerton Scaboro da Silva <[email protected]>

* PR update

* update cutil

---------

Co-authored-by: Ewerton Scaboro da Silva <[email protected]>
  • Loading branch information
ericwolz and ewertons authored Feb 9, 2024
1 parent 35b5780 commit e02272b
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 53 deletions.
10 changes: 7 additions & 3 deletions src/amqp_frame_codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "azure_macro_utils/macro_utils.h"
#include "azure_c_shared_utility/gballoc.h"
#include "azure_c_shared_utility/xlogging.h"
#include "azure_c_shared_utility/safe_math.h"
#include "azure_uamqp_c/amqp_frame_codec.h"
#include "azure_uamqp_c/frame_codec.h"
#include "azure_uamqp_c/amqpvalue.h"
Expand Down Expand Up @@ -274,10 +275,13 @@ int amqp_frame_codec_encode_frame(AMQP_FRAME_CODEC_HANDLE amqp_frame_codec, uint
}
else
{
PAYLOAD* new_payloads = (PAYLOAD*)calloc(1, (sizeof(PAYLOAD) * (payload_count + 1)));
if (new_payloads == NULL)
PAYLOAD* new_payloads;
size_t calloc_size = safe_add_size_t(payload_count, 1);
calloc_size = safe_multiply_size_t(calloc_size, sizeof(PAYLOAD));
if (calloc_size == SIZE_MAX ||
(new_payloads = (PAYLOAD*)calloc(1, calloc_size)) == NULL)
{
LogError("Could not allocate frame payloads");
LogError("Could not allocate frame payloads, size:%zu", calloc_size);
result = MU_FAILURE;
}
else
Expand Down
55 changes: 34 additions & 21 deletions src/amqpvalue.c
Original file line number Diff line number Diff line change
Expand Up @@ -1278,11 +1278,12 @@ int amqpvalue_set_list_item_count(AMQP_VALUE value, uint32_t list_size)
AMQP_VALUE* new_list;

/* Codes_SRS_AMQPVALUE_01_152: [amqpvalue_set_list_item_count shall resize an AMQP list.] */
new_list = (AMQP_VALUE*)realloc(value_data->value.list_value.items, list_size * sizeof(AMQP_VALUE));
if (new_list == NULL)
size_t realloc_size = safe_multiply_size_t(list_size, sizeof(AMQP_VALUE));
if (realloc_size == SIZE_MAX ||
(new_list = (AMQP_VALUE*)realloc(value_data->value.list_value.items, realloc_size)) == NULL)
{
/* Codes_SRS_AMQPVALUE_01_154: [If allocating memory for the list according to the new size fails, then amqpvalue_set_list_item_count shall return a non-zero value, while preserving the existing list contents.] */
LogError("Could not reallocate list memory");
LogError("Could not reallocate list memory, size:%zu", realloc_size);
result = MU_FAILURE;
}
else
Expand Down Expand Up @@ -1415,11 +1416,14 @@ int amqpvalue_set_list_item(AMQP_VALUE value, uint32_t index, AMQP_VALUE list_it
{
if (index >= value_data->value.list_value.count)
{
AMQP_VALUE* new_list = (AMQP_VALUE*)realloc(value_data->value.list_value.items, ((size_t)index + 1) * sizeof(AMQP_VALUE));
if (new_list == NULL)
AMQP_VALUE* new_list;
size_t realloc_size = safe_add_size_t((size_t)index, 1);
realloc_size = safe_multiply_size_t(realloc_size, sizeof(AMQP_VALUE));
if (realloc_size == SIZE_MAX ||
(new_list = (AMQP_VALUE*)realloc(value_data->value.list_value.items, realloc_size)) == NULL)
{
/* Codes_SRS_AMQPVALUE_01_170: [When amqpvalue_set_list_item fails due to not being able to clone the item or grow the list, the list shall not be altered.] */
LogError("Could not reallocate list storage");
LogError("Could not reallocate list storage, size:%zu", realloc_size);
amqpvalue_destroy(cloned_item);
result = MU_FAILURE;
}
Expand Down Expand Up @@ -1613,13 +1617,16 @@ int amqpvalue_set_map_value(AMQP_VALUE map, AMQP_VALUE key, AMQP_VALUE value)
}
else
{
AMQP_MAP_KEY_VALUE_PAIR* new_pairs = (AMQP_MAP_KEY_VALUE_PAIR*)realloc(value_data->value.map_value.pairs, ((size_t)value_data->value.map_value.pair_count + 1) * sizeof(AMQP_MAP_KEY_VALUE_PAIR));
if (new_pairs == NULL)
AMQP_MAP_KEY_VALUE_PAIR* new_pairs;
size_t realloc_size = safe_add_size_t((size_t)value_data->value.map_value.pair_count, 1);
realloc_size = safe_multiply_size_t(realloc_size, sizeof(AMQP_MAP_KEY_VALUE_PAIR));
if (realloc_size == SIZE_MAX ||
(new_pairs = (AMQP_MAP_KEY_VALUE_PAIR*)realloc(value_data->value.map_value.pairs, realloc_size)) == NULL)
{
/* Codes_SRS_AMQPVALUE_01_186: [If allocating memory to hold a new key/value pair fails, amqpvalue_set_map_value shall fail and return a non-zero value.] */
amqpvalue_destroy(cloned_key);
amqpvalue_destroy(cloned_value);
LogError("Could not reallocate memory for map");
LogError("Could not reallocate memory for new_pairs map, size:%zu", realloc_size);
result = MU_FAILURE;
}
else
Expand Down Expand Up @@ -1918,13 +1925,16 @@ int amqpvalue_add_array_item(AMQP_VALUE value, AMQP_VALUE array_item_value)
}
else
{
AMQP_VALUE* new_array = (AMQP_VALUE*)realloc(value_data->value.array_value.items, ((size_t)value_data->value.array_value.count + 1) * sizeof(AMQP_VALUE));
if (new_array == NULL)
AMQP_VALUE* new_array;
size_t realloc_size = safe_add_size_t((size_t)value_data->value.array_value.count, 1);
realloc_size = safe_multiply_size_t(realloc_size, sizeof(AMQP_VALUE));
if (realloc_size == SIZE_MAX ||
(new_array = (AMQP_VALUE*)realloc(value_data->value.array_value.items, realloc_size)) == NULL)
{
/* Codes_SRS_AMQPVALUE_01_423: [ When `amqpvalue_add_array_item` fails due to not being able to clone the item or grow the array, the array shall not be altered. ] */
/* Codes_SRS_AMQPVALUE_01_424: [ If growing the array fails, then `amqpvalue_add_array_item` shall fail and return a non-zero value. ] */
amqpvalue_destroy(cloned_item);
LogError("Cannot resize array");
LogError("Cannot resize array, size:%zu", realloc_size);
result = MU_FAILURE;
}
else
Expand Down Expand Up @@ -6360,10 +6370,11 @@ static int internal_decoder_decode_bytes(INTERNAL_DECODER_DATA* internal_decoder
else
{
uint32_t i;
internal_decoder_data->decode_to_value->value.list_value.items = (AMQP_VALUE*)calloc(1, (sizeof(AMQP_VALUE) * internal_decoder_data->decode_to_value->value.list_value.count));
if (internal_decoder_data->decode_to_value->value.list_value.items == NULL)
size_t calloc_size = safe_multiply_size_t(sizeof(AMQP_VALUE), internal_decoder_data->decode_to_value->value.list_value.count);
if (calloc_size == SIZE_MAX ||
(internal_decoder_data->decode_to_value->value.list_value.items = (AMQP_VALUE*)calloc(1, calloc_size)) == NULL)
{
LogError("Could not allocate memory for decoded list value");
LogError("Could not allocate memory for decoded list value, size:%zu", calloc_size);
result = MU_FAILURE;
}
else
Expand Down Expand Up @@ -6826,10 +6837,11 @@ static int internal_decoder_decode_bytes(INTERNAL_DECODER_DATA* internal_decoder
else
{
uint32_t i;
internal_decoder_data->decode_to_value->value.array_value.items = (AMQP_VALUE*)calloc(1, (sizeof(AMQP_VALUE) * internal_decoder_data->decode_to_value->value.array_value.count));
if (internal_decoder_data->decode_to_value->value.array_value.items == NULL)
size_t calloc_size = safe_multiply_size_t(sizeof(AMQP_VALUE), internal_decoder_data->decode_to_value->value.array_value.count);
if (calloc_size == SIZE_MAX ||
(internal_decoder_data->decode_to_value->value.array_value.items = (AMQP_VALUE*)calloc(1, calloc_size)) == NULL)
{
LogError("Could not allocate memory for array items");
LogError("Could not allocate memory for array items, size:%zu", calloc_size);
result = MU_FAILURE;
}
else
Expand Down Expand Up @@ -6860,10 +6872,11 @@ static int internal_decoder_decode_bytes(INTERNAL_DECODER_DATA* internal_decoder
else
{
uint32_t i;
internal_decoder_data->decode_to_value->value.array_value.items = (AMQP_VALUE*)calloc(1, (sizeof(AMQP_VALUE) * internal_decoder_data->decode_to_value->value.array_value.count));
if (internal_decoder_data->decode_to_value->value.array_value.items == NULL)
size_t calloc_size = safe_multiply_size_t(sizeof(AMQP_VALUE), internal_decoder_data->decode_to_value->value.array_value.count);
if (calloc_size == SIZE_MAX ||
(internal_decoder_data->decode_to_value->value.array_value.items = (AMQP_VALUE*)calloc(1, calloc_size)) == NULL)
{
LogError("Could not allocate memory for array items");
LogError("Could not allocate memory for array items, size:%zu", calloc_size);
result = MU_FAILURE;
}
else
Expand Down
8 changes: 5 additions & 3 deletions src/amqpvalue_to_string.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "azure_c_shared_utility/gballoc.h"
#include "azure_c_shared_utility/xlogging.h"
#include "azure_c_shared_utility/uuid.h"
#include "azure_c_shared_utility/safe_math.h"
#include "azure_uamqp_c/amqpvalue_to_string.h"
#include "azure_uamqp_c/amqpvalue.h"

Expand All @@ -35,10 +36,11 @@ static int string_concat(char** string, const char* to_concat)
src_length = 0;
}

new_string = (char*)realloc(*string, src_length + length);
if (new_string == NULL)
size_t realloc_size = safe_add_size_t(src_length, length);
if (realloc_size == SIZE_MAX ||
(new_string = (char*)realloc(*string, realloc_size)) == NULL)
{
LogError("Cannot allocate memory for the new string");
LogError("Cannot allocate memory for the new string, size:%zu", realloc_size);
result = MU_FAILURE;
}
else
Expand Down
43 changes: 34 additions & 9 deletions src/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "azure_c_shared_utility/xio.h"
#include "azure_c_shared_utility/xlogging.h"
#include "azure_c_shared_utility/tickcounter.h"
#include "azure_c_shared_utility/safe_math.h"

#include "azure_uamqp_c/connection.h"
#include "azure_uamqp_c/frame_codec.h"
Expand Down Expand Up @@ -1897,11 +1898,13 @@ ENDPOINT_HANDLE connection_create_endpoint(CONNECTION_HANDLE connection)
result->connection = connection;

/* Codes_S_R_S_CONNECTION_01_197: [The newly created endpoint shall be added to the endpoints list, so that it can be tracked.] */
new_endpoints = (ENDPOINT_HANDLE*)realloc(connection->endpoints, sizeof(ENDPOINT_HANDLE) * ((size_t)connection->endpoint_count + 1));
if (new_endpoints == NULL)
size_t realloc_size = safe_add_size_t((size_t)connection->endpoint_count, 1);
realloc_size = safe_multiply_size_t(realloc_size, sizeof(ENDPOINT_HANDLE));
if (realloc_size == SIZE_MAX ||
(new_endpoints = (ENDPOINT_HANDLE*)realloc(connection->endpoints, realloc_size)) == NULL)
{
/* Tests_S_R_S_CONNECTION_01_198: [If adding the endpoint to the endpoints list tracked by the connection fails, connection_create_endpoint shall fail and return NULL.] */
LogError("Cannot reallocate memory for connection endpoints");
LogError("Cannot reallocate memory for connection endpoints, size:%zu", realloc_size);
free(result);
result = NULL;
}
Expand All @@ -1911,7 +1914,15 @@ ENDPOINT_HANDLE connection_create_endpoint(CONNECTION_HANDLE connection)

if (i < connection->endpoint_count)
{
(void)memmove(&connection->endpoints[i + 1], &connection->endpoints[i], sizeof(ENDPOINT_INSTANCE*) * (connection->endpoint_count - i));
size_t memmove_size = safe_multiply_size_t(safe_subtract_size_t(connection->endpoint_count, i), sizeof(ENDPOINT_INSTANCE*));
if (memmove_size != SIZE_MAX)
{
(void)memmove(&connection->endpoints[i + 1], &connection->endpoints[i], memmove_size);
}
else
{
LogError("Cannot memmove endpoints, size:%zu", memmove_size);
}
}

connection->endpoints[i] = result;
Expand Down Expand Up @@ -2004,14 +2015,28 @@ void connection_destroy_endpoint(ENDPOINT_HANDLE endpoint)
else
{
ENDPOINT_HANDLE* new_endpoints;

if ((connection->endpoint_count - i - 1) > 0)
size_t new_count = safe_subtract_size_t(safe_subtract_size_t(connection->endpoint_count, i), 1);
if (new_count > 0)
{
(void)memmove(connection->endpoints + i, connection->endpoints + i + 1, sizeof(ENDPOINT_HANDLE) * (connection->endpoint_count - i - 1));
size_t memmove_size = safe_multiply_size_t(safe_subtract_size_t(safe_subtract_size_t(connection->endpoint_count, i), 1), sizeof(ENDPOINT_HANDLE));
if (memmove_size != SIZE_MAX)
{
(void)memmove(connection->endpoints + i, connection->endpoints + i + 1, memmove_size);
}
else
{
LogError("Cannot memmove endpoints, size:%zu", memmove_size);
}
}

new_endpoints = (ENDPOINT_HANDLE*)realloc(connection->endpoints, (connection->endpoint_count - 1) * sizeof(ENDPOINT_HANDLE));
if (new_endpoints != NULL)
size_t realloc_size = safe_subtract_size_t(connection->endpoint_count, 1);
realloc_size = safe_multiply_size_t(realloc_size, sizeof(ENDPOINT_HANDLE));
if (realloc_size == SIZE_MAX ||
(new_endpoints = (ENDPOINT_HANDLE*)realloc(connection->endpoints, realloc_size)) == NULL)
{
LogError("Memory realloc failed, size:%zu", realloc_size);
}
else
{
connection->endpoints = new_endpoints;
}
Expand Down
7 changes: 5 additions & 2 deletions src/header_detect_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "azure_c_shared_utility/gballoc.h"
#include "azure_c_shared_utility/xlogging.h"
#include "azure_c_shared_utility/singlylinkedlist.h"
#include "azure_c_shared_utility/safe_math.h"
#include "azure_uamqp_c/header_detect_io.h"
#include "azure_uamqp_c/server_protocol_io.h"

Expand Down Expand Up @@ -529,9 +530,11 @@ static CONCRETE_IO_HANDLE header_detect_io_create(void* io_create_parameters)
else
{
/* Codes_SRS_HEADER_DETECT_IO_01_009: [ The `header_detect_entries` array shall be copied so that it can be later used when detecting which header was received. ]*/
result->header_detect_entries = (INTERNAL_HEADER_DETECT_ENTRY*)calloc(1, (header_detect_io_config->header_detect_entry_count * sizeof(INTERNAL_HEADER_DETECT_ENTRY)));
if (result->header_detect_entries == NULL)
size_t calloc_size = safe_multiply_size_t(header_detect_io_config->header_detect_entry_count, sizeof(INTERNAL_HEADER_DETECT_ENTRY));
if (calloc_size == SIZE_MAX ||
(result->header_detect_entries = (INTERNAL_HEADER_DETECT_ENTRY*)calloc(1, calloc_size)) == NULL)
{
LogError("Could not allocate header_detect_entries, size:%zu", calloc_size);
free(result);
result = NULL;
}
Expand Down
9 changes: 6 additions & 3 deletions src/link.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "azure_c_shared_utility/xlogging.h"
#include "azure_c_shared_utility/singlylinkedlist.h"
#include "azure_c_shared_utility/tickcounter.h"
#include "azure_c_shared_utility/safe_math.h"
#include "azure_uamqp_c/link.h"
#include "azure_uamqp_c/session.h"
#include "azure_uamqp_c/amqpvalue.h"
Expand Down Expand Up @@ -448,10 +449,12 @@ static void link_frame_received(void* context, AMQP_VALUE performative, uint32_t
/* If this is a continuation transfer or if this is the first chunk of a multi frame transfer */
if ((link_instance->received_payload_size > 0) || more)
{
unsigned char* new_received_payload = (unsigned char*)realloc(link_instance->received_payload, (size_t)link_instance->received_payload_size + payload_size);
if (new_received_payload == NULL)
unsigned char* new_received_payload;;
size_t realloc_size = safe_add_size_t((size_t)link_instance->received_payload_size, payload_size);
if (realloc_size == SIZE_MAX ||
(new_received_payload = (unsigned char*)realloc(link_instance->received_payload, realloc_size)) == NULL)
{
LogError("Could not allocate memory for the received payload");
LogError("Could not allocate memory for the received payload, size:%zu", realloc_size);
}
else
{
Expand Down
5 changes: 3 additions & 2 deletions src/message.c
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ MESSAGE_HANDLE message_clone(MESSAGE_HANDLE source_message)
if (calloc_size == SIZE_MAX)
{
LogError("Invalid size for body_amqp_data_items");
message_destroy(result);
result = NULL;
}
else
Expand Down Expand Up @@ -1022,7 +1023,7 @@ int message_add_body_amqp_data(MESSAGE_HANDLE message, BINARY_DATA amqp_data)
if ((message == NULL) ||
/* Tests_SRS_MESSAGE_01_089: [ If the `bytes` member of `amqp_data` is NULL and the `size` member is non-zero, `message_add_body_amqp_data` shall fail and return a non-zero value. ]*/
((amqp_data.bytes == NULL) &&
(amqp_data.length != 0)))
(amqp_data.length != 0)))
{
LogError("Bad arguments: message = %p, bytes = %p, length = %u",
message, amqp_data.bytes, (unsigned int)amqp_data.length);
Expand Down Expand Up @@ -1471,7 +1472,7 @@ int message_set_message_format(MESSAGE_HANDLE message, uint32_t message_format)
return result;
}

int message_get_message_format(MESSAGE_HANDLE message, uint32_t *message_format)
int message_get_message_format(MESSAGE_HANDLE message, uint32_t* message_format)
{
int result;

Expand Down
Loading

0 comments on commit e02272b

Please sign in to comment.