Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions sdk/core/azure-core-amqp/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

- Fixed several memory leaks.
- AMQP Link Credits now work as expected.
- Integrated the fix for NVD - CVE-2024-21646.

### Other Changes

Expand Down
112 changes: 99 additions & 13 deletions sdk/core/azure-core-amqp/vendor/azure-uamqp-c/src/amqpvalue.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "azure_uamqp_c/amqp_types.h"
#include "azure_uamqp_c/amqpvalue.h"
#include "azure_c_shared_utility/refcount.h"
#include "azure_c_shared_utility/safe_math.h"

// max alloc size 100MB
#define MAX_AMQPVALUE_MALLOC_SIZE_BYTES (100 * 1024 * 1024)
Expand Down Expand Up @@ -1069,8 +1070,19 @@ AMQP_VALUE amqpvalue_create_string(const char* value)
else
{
size_t length = strlen(value);
size_t malloc_size = length + 1;

result = REFCOUNT_TYPE_CREATE(AMQP_VALUE_DATA);
// If the result of malloc_size is zero it means it had a type overflow (size_t is an unsigned
// type). It is very unlikely but could happen.
if (malloc_size == 0)
{
LogError("Invalid string size exceeded max allocation");
result = NULL;
}
else
{
result = REFCOUNT_TYPE_CREATE(AMQP_VALUE_DATA);
}
if (result == NULL)
{
/* Codes_SRS_AMQPVALUE_01_136: [If allocating the AMQP_VALUE fails then amqpvalue_create_string shall return NULL.] */
Expand All @@ -1079,7 +1091,7 @@ AMQP_VALUE amqpvalue_create_string(const char* value)
else
{
result->type = AMQP_TYPE_STRING;
result->value.string_value.chars = (char*)malloc(length + 1);
result->value.string_value.chars = (char*)malloc(malloc_size);
if (result->value.string_value.chars == NULL)
{
/* Codes_SRS_AMQPVALUE_01_136: [If allocating the AMQP_VALUE fails then amqpvalue_create_string shall return NULL.] */
Expand All @@ -1089,7 +1101,7 @@ AMQP_VALUE amqpvalue_create_string(const char* value)
}
else
{
(void)memcpy(result->value.string_value.chars, value, length + 1);
(void)memcpy(result->value.string_value.chars, value, malloc_size);
}
}
}
Expand Down Expand Up @@ -1145,7 +1157,7 @@ AMQP_VALUE amqpvalue_create_symbol(const char* value)
else
{
size_t length = strlen(value);
if (length > UINT32_MAX)
if (length >= UINT32_MAX)
{
/* Codes_SRS_AMQPVALUE_01_401: [ If the string pointed to by value is longer than 2^32-1 then amqpvalue_create_symbol shall return NULL. ]*/
LogError("string too long to be represented as a symbol");
Expand Down Expand Up @@ -5941,7 +5953,16 @@ static int internal_decoder_decode_bytes(INTERNAL_DECODER_DATA* internal_decoder
}
else
{
internal_decoder_data->decode_to_value->value.binary_value.bytes = (unsigned char*)malloc((size_t)internal_decoder_data->decode_to_value->value.binary_value.length + 1);
size_t malloc_size = (size_t)internal_decoder_data->decode_to_value->value.binary_value.length + 1;
if (malloc_size == 0)
{
internal_decoder_data->decode_to_value->value.binary_value.bytes = NULL;
LogError("Invalid binary_value size exceeded max allocation");
}
else
{
internal_decoder_data->decode_to_value->value.binary_value.bytes = (unsigned char*)malloc(malloc_size);
}
if (internal_decoder_data->decode_to_value->value.binary_value.bytes == NULL)
{
/* Codes_SRS_AMQPVALUE_01_326: [If any allocation failure occurs during decoding, amqpvalue_decode_bytes shall fail and return a non-zero value.] */
Expand Down Expand Up @@ -5994,7 +6015,18 @@ static int internal_decoder_decode_bytes(INTERNAL_DECODER_DATA* internal_decoder
buffer++;
size--;

internal_decoder_data->decode_to_value->value.string_value.chars = (char*)malloc((size_t)internal_decoder_data->decode_value_state.string_value_state.length + 1);
size_t malloc_size = (size_t)internal_decoder_data->decode_value_state.string_value_state.length + 1;
// If the result of malloc_size is zero it means it had a type overflow (size_t is an unsigned type).
// It is very unlikely but could happen.
if (malloc_size == 0)
{
internal_decoder_data->decode_to_value->value.string_value.chars = NULL;
LogError("Invalid string size exceeded max allocation");
}
else
{
internal_decoder_data->decode_to_value->value.string_value.chars = (char*)malloc(malloc_size);
}
if (internal_decoder_data->decode_to_value->value.string_value.chars == NULL)
{
/* Codes_SRS_AMQPVALUE_01_326: [If any allocation failure occurs during decoding, amqpvalue_decode_bytes shall fail and return a non-zero value.] */
Expand Down Expand Up @@ -6057,8 +6089,21 @@ static int internal_decoder_decode_bytes(INTERNAL_DECODER_DATA* internal_decoder

if (internal_decoder_data->bytes_decoded == 4)
{
internal_decoder_data->decode_to_value->value.string_value.chars = (char*)malloc((size_t)internal_decoder_data->decode_value_state.string_value_state.length + 1);
if (internal_decoder_data->decode_to_value->value.string_value.chars == NULL)
size_t malloc_size = (size_t)internal_decoder_data->decode_value_state.string_value_state.length + 1;

// If the result of malloc_size is zero it means it had a type overflow
// (size_t is an unsigned type). It is very unlikely but could happen.
if (malloc_size == 0)
{
internal_decoder_data->decode_to_value->value.string_value.chars = NULL;
LogError("Invalid string value size exceeded max allocation");
}
else
{
internal_decoder_data->decode_to_value->value.string_value.chars = (char*)malloc(malloc_size);
}
if (internal_decoder_data->decode_to_value->value.string_value.chars
== NULL)
{
/* Codes_SRS_AMQPVALUE_01_326: [If any allocation failure occurs during decoding, amqpvalue_decode_bytes shall fail and return a non-zero value.] */
internal_decoder_data->decoder_state = DECODER_STATE_ERROR;
Expand Down Expand Up @@ -6123,7 +6168,19 @@ static int internal_decoder_decode_bytes(INTERNAL_DECODER_DATA* internal_decoder
buffer++;
size--;

internal_decoder_data->decode_to_value->value.symbol_value.chars = (char*)malloc((size_t)internal_decoder_data->decode_value_state.symbol_value_state.length + 1);
size_t malloc_size = (size_t)internal_decoder_data->decode_value_state.symbol_value_state.length + 1;
// If the result of malloc_size is zero it means it had a type overflow
// (size_t is an unsigned type). It is very unlikely but could happen.
if (malloc_size == 0)
{
internal_decoder_data->decode_to_value->value.symbol_value.chars = NULL;
LogError("Invalid symbol_value size exceeded max allocation");
}
else
{
internal_decoder_data->decode_to_value->value.symbol_value.chars = (char*)malloc(malloc_size);
}

if (internal_decoder_data->decode_to_value->value.symbol_value.chars == NULL)
{
/* Codes_SRS_AMQPVALUE_01_326: [If any allocation failure occurs during decoding, amqpvalue_decode_bytes shall fail and return a non-zero value.] */
Expand Down Expand Up @@ -6186,8 +6243,19 @@ static int internal_decoder_decode_bytes(INTERNAL_DECODER_DATA* internal_decoder

if (internal_decoder_data->bytes_decoded == 4)
{
internal_decoder_data->decode_to_value->value.symbol_value.chars = (char*)malloc((size_t)internal_decoder_data->decode_value_state.symbol_value_state.length + 1);
if (internal_decoder_data->decode_to_value->value.symbol_value.chars == NULL)
size_t malloc_size = (size_t)internal_decoder_data->decode_value_state.symbol_value_state.length + 1;
// If the result of malloc_size is zero it means it had a type overflow
// (size_t is an unsigned type). It is very unlikely but could happen.
if (malloc_size == 0)
{
internal_decoder_data->decode_to_value->value.symbol_value.chars = NULL;
LogError("Invalid symbol value size exceeded max allocation");
}
else
{
internal_decoder_data->decode_to_value->value.symbol_value.chars = (char*)malloc(malloc_size);
}
if (internal_decoder_data->decode_to_value->value.symbol_value.chars == NULL)
{
/* Codes_SRS_AMQPVALUE_01_326: [If any allocation failure occurs during decoding, amqpvalue_decode_bytes shall fail and return a non-zero value.] */
internal_decoder_data->decoder_state = DECODER_STATE_ERROR;
Expand Down Expand Up @@ -6531,7 +6599,18 @@ static int internal_decoder_decode_bytes(INTERNAL_DECODER_DATA* internal_decoder

internal_decoder_data->decode_to_value->value.map_value.pair_count /= 2;

internal_decoder_data->decode_to_value->value.map_value.pairs = (AMQP_MAP_KEY_VALUE_PAIR*)malloc(sizeof(AMQP_MAP_KEY_VALUE_PAIR) * ((size_t)internal_decoder_data->decode_to_value->value.map_value.pair_count * 2));
size_t malloc_size = safe_multiply_size_t(sizeof(AMQP_MAP_KEY_VALUE_PAIR), (size_t)internal_decoder_data->decode_to_value->value.map_value.pair_count);
malloc_size = safe_multiply_size_t(malloc_size, 2);

if (malloc_size == SIZE_MAX)
{
LogError("Invalid map_value size exceeded max allocation");
internal_decoder_data->decode_to_value->value.map_value.pairs = NULL;
}
else
{
internal_decoder_data->decode_to_value->value.map_value.pairs = (AMQP_MAP_KEY_VALUE_PAIR*)malloc(malloc_size);
}
if (internal_decoder_data->decode_to_value->value.map_value.pairs == NULL)
{
LogError("Could not allocate memory for map value items");
Expand Down Expand Up @@ -6569,13 +6648,20 @@ static int internal_decoder_decode_bytes(INTERNAL_DECODER_DATA* internal_decoder
uint32_t i;

internal_decoder_data->decode_to_value->value.map_value.pair_count /= 2;
size_t malloc_size = safe_multiply_size_t((size_t)internal_decoder_data->decode_to_value->value.map_value.pair_count, 2);
malloc_size = safe_multiply_size_t(sizeof(AMQP_MAP_KEY_VALUE_PAIR), malloc_size);
if (internal_decoder_data->decode_to_value->value.map_value.pair_count > MAX_AMQPVALUE_ITEM_COUNT)
{
LogError("AMQP list map count exceeded MAX_AMQPVALUE_ITEM_COUNT");
result = MU_FAILURE;
}
else if (malloc_size == SIZE_MAX)
{
LogError("Invalid map_value size exceeded max allocation");
result = MU_FAILURE;
}
else if ((internal_decoder_data->decode_to_value->value.map_value.pairs =
(AMQP_MAP_KEY_VALUE_PAIR*)malloc(sizeof(AMQP_MAP_KEY_VALUE_PAIR) * ((size_t)internal_decoder_data->decode_to_value->value.map_value.pair_count * 2)))
(AMQP_MAP_KEY_VALUE_PAIR*)malloc(malloc_size))
== NULL)
{
LogError("Could not allocate memory for map value items");
Expand Down