Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP2:GA
python-uamqp
CVE-2024-21646.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File CVE-2024-21646.patch of Package python-uamqp
From 74c02ad54ae987ccd7a51c676581c7d4a40127ba Mon Sep 17 00:00:00 2001 From: Kashif Khan <361477+kashifkhan@users.noreply.github.com> Date: Mon, 22 Jan 2024 09:11:42 -0600 Subject: [PATCH] CVE fix (#373) * Fixes for CVE-2024-21646 * changelog update * add back function * fix windows build * move install for windows compiler --- .../azure-c-shared-utility/CMakeLists.txt | 1 + .../inc/azure_c_shared_utility/safe_math.h | 17 +++ src/vendor/azure-uamqp-c/src/amqpvalue.c | 136 ++++++++++++++---- 3 files changed, 130 insertions(+), 24 deletions(-) create mode 100644 src/vendor/azure-uamqp-c/deps/azure-c-shared-utility/inc/azure_c_shared_utility/safe_math.h diff --git a/src/vendor/azure-uamqp-c/deps/azure-c-shared-utility/CMakeLists.txt b/src/vendor/azure-uamqp-c/deps/azure-c-shared-utility/CMakeLists.txt index 5101951..c2f9b2f 100644 --- a/src/vendor/azure-uamqp-c/deps/azure-c-shared-utility/CMakeLists.txt +++ b/src/vendor/azure-uamqp-c/deps/azure-c-shared-utility/CMakeLists.txt @@ -373,6 +373,7 @@ set(source_h_files ./inc/azure_c_shared_utility/tlsio.h ./inc/azure_c_shared_utility/optionhandler.h ./inc/azure_c_shared_utility/memory_data.h + ./inc/azure_c_shared_utility/safe_math.h ${LOGGING_STACKTRACE_H_FILE} ) diff --git a/src/vendor/azure-uamqp-c/deps/azure-c-shared-utility/inc/azure_c_shared_utility/safe_math.h b/src/vendor/azure-uamqp-c/deps/azure-c-shared-utility/inc/azure_c_shared_utility/safe_math.h new file mode 100644 index 0000000..cf8198d --- /dev/null +++ b/src/vendor/azure-uamqp-c/deps/azure-c-shared-utility/inc/azure_c_shared_utility/safe_math.h @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +#ifndef SAFE_MATH_H +#define SAFE_MATH_H + +#ifndef SIZE_MAX +#define SIZE_MAX ((size_t)((size_t)~(size_t)0)) +#endif + +#define safe_add_size_t(a, b) ((((size_t)(a)) < ((size_t)(SIZE_MAX - ((size_t)(b))))) ? ((size_t)(a) + (size_t)(b)) : SIZE_MAX) + +#define safe_subtract_size_t(a, b) (((a) >= (b)) ? ((size_t)(a) - (size_t)(b)) : SIZE_MAX) + +#define safe_multiply_size_t(a, b) (((a) == 0 || (b) == 0) ? 0 : (((SIZE_MAX / (size_t)(a)) >= (size_t)(b)) ? (size_t)(a) * (size_t)(b) : SIZE_MAX)) + +#endif // SAFE_MATH_H \ No newline at end of file diff --git a/src/vendor/azure-uamqp-c/src/amqpvalue.c b/src/vendor/azure-uamqp-c/src/amqpvalue.c index e1445e7..43245cf 100644 --- a/src/vendor/azure-uamqp-c/src/amqpvalue.c +++ b/src/vendor/azure-uamqp-c/src/amqpvalue.c @@ -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) @@ -1069,8 +1070,20 @@ AMQP_VALUE amqpvalue_create_string(const char* value) else { size_t length = strlen(value); + size_t malloc_size = 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) + { + LogError("Invalid string size exceeded max allocation"); + result = NULL; + } + else + { + result = REFCOUNT_TYPE_CREATE(AMQP_VALUE_DATA); + } - 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.] */ @@ -1079,7 +1092,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.] */ @@ -1089,7 +1102,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); } } } @@ -1145,7 +1158,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"); @@ -1402,7 +1415,7 @@ 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, (index + 1) * sizeof(AMQP_VALUE)); + AMQP_VALUE* new_list = (AMQP_VALUE*)realloc(value_data->value.list_value.items, ((size_t)index + 1) * sizeof(AMQP_VALUE)); if (new_list == 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.] */ @@ -1629,7 +1642,7 @@ 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, (value_data->value.map_value.pair_count + 1) * sizeof(AMQP_MAP_KEY_VALUE_PAIR)); + 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) { /* 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.] */ @@ -1934,7 +1947,7 @@ 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, (value_data->value.array_value.count + 1) * sizeof(AMQP_VALUE)); + 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) { /* 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. ] */ @@ -5902,7 +5915,7 @@ static int internal_decoder_decode_bytes(INTERNAL_DECODER_DATA* internal_decoder size -= to_copy; internal_decoder_data->bytes_decoded += to_copy; - if (internal_decoder_data->bytes_decoded == internal_decoder_data->decode_to_value->value.binary_value.length + 1) + if (internal_decoder_data->bytes_decoded == (size_t)internal_decoder_data->decode_to_value->value.binary_value.length + 1) { internal_decoder_data->decoder_state = DECODER_STATE_CONSTRUCTOR; @@ -5941,7 +5954,17 @@ 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.] */ @@ -5973,7 +5996,7 @@ static int internal_decoder_decode_bytes(INTERNAL_DECODER_DATA* internal_decoder size -= to_copy; internal_decoder_data->bytes_decoded += to_copy; - if (internal_decoder_data->bytes_decoded == internal_decoder_data->decode_to_value->value.binary_value.length + 4) + if (internal_decoder_data->bytes_decoded == (size_t)internal_decoder_data->decode_to_value->value.binary_value.length + 4) { internal_decoder_data->decoder_state = DECODER_STATE_CONSTRUCTOR; internal_decoder_data->on_value_decoded(internal_decoder_data->on_value_decoded_context, internal_decoder_data->decode_to_value); @@ -5994,7 +6017,19 @@ 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(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.] */ @@ -6030,7 +6065,7 @@ static int internal_decoder_decode_bytes(INTERNAL_DECODER_DATA* internal_decoder size -= to_copy; internal_decoder_data->bytes_decoded += to_copy; - if (internal_decoder_data->bytes_decoded == internal_decoder_data->decode_value_state.string_value_state.length + 1) + if (internal_decoder_data->bytes_decoded == (size_t)internal_decoder_data->decode_value_state.string_value_state.length + 1) { internal_decoder_data->decode_to_value->value.string_value.chars[internal_decoder_data->decode_value_state.string_value_state.length] = 0; internal_decoder_data->decoder_state = DECODER_STATE_CONSTRUCTOR; @@ -6057,7 +6092,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.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 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.] */ @@ -6098,7 +6145,7 @@ static int internal_decoder_decode_bytes(INTERNAL_DECODER_DATA* internal_decoder size -= to_copy; internal_decoder_data->bytes_decoded += to_copy; - if (internal_decoder_data->bytes_decoded == internal_decoder_data->decode_value_state.string_value_state.length + 4) + if (internal_decoder_data->bytes_decoded == (size_t)internal_decoder_data->decode_value_state.string_value_state.length + 4) { internal_decoder_data->decode_to_value->value.string_value.chars[internal_decoder_data->decode_value_state.string_value_state.length] = '\0'; internal_decoder_data->decoder_state = DECODER_STATE_CONSTRUCTOR; @@ -6123,7 +6170,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(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.] */ @@ -6159,7 +6218,7 @@ static int internal_decoder_decode_bytes(INTERNAL_DECODER_DATA* internal_decoder size -= to_copy; internal_decoder_data->bytes_decoded += to_copy; - if (internal_decoder_data->bytes_decoded == internal_decoder_data->decode_value_state.symbol_value_state.length + 1) + if (internal_decoder_data->bytes_decoded == (size_t)internal_decoder_data->decode_value_state.symbol_value_state.length + 1) { internal_decoder_data->decode_to_value->value.symbol_value.chars[internal_decoder_data->decode_value_state.symbol_value_state.length] = 0; internal_decoder_data->decoder_state = DECODER_STATE_CONSTRUCTOR; @@ -6186,7 +6245,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); + 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.] */ @@ -6227,7 +6298,7 @@ static int internal_decoder_decode_bytes(INTERNAL_DECODER_DATA* internal_decoder size -= to_copy; internal_decoder_data->bytes_decoded += to_copy; - if (internal_decoder_data->bytes_decoded == internal_decoder_data->decode_value_state.symbol_value_state.length + 4) + if (internal_decoder_data->bytes_decoded == (size_t)internal_decoder_data->decode_value_state.symbol_value_state.length + 4) { internal_decoder_data->decode_to_value->value.symbol_value.chars[internal_decoder_data->decode_value_state.symbol_value_state.length] = '\0'; internal_decoder_data->decoder_state = DECODER_STATE_CONSTRUCTOR; @@ -6530,8 +6601,19 @@ 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(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); + } - internal_decoder_data->decode_to_value->value.map_value.pairs = (AMQP_MAP_KEY_VALUE_PAIR*)malloc(sizeof(AMQP_MAP_KEY_VALUE_PAIR) * (internal_decoder_data->decode_to_value->value.map_value.pair_count * 2)); if (internal_decoder_data->decode_to_value->value.map_value.pairs == NULL) { LogError("Could not allocate memory for map value items"); @@ -6569,13 +6651,21 @@ 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) * (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"); @@ -6610,8 +6700,6 @@ static int internal_decoder_decode_bytes(INTERNAL_DECODER_DATA* internal_decoder if (internal_decoder_data->bytes_decoded == 0) { - AMQP_VALUE_DATA* map_item; - if (internal_decoder_data->decode_value_state.map_value_state.item >= internal_decoder_data->decode_to_value->value.map_value.pair_count) { LogError("Map item index is out of range"); @@ -6620,7 +6708,7 @@ static int internal_decoder_decode_bytes(INTERNAL_DECODER_DATA* internal_decoder break; } - map_item = (AMQP_VALUE_DATA*)REFCOUNT_TYPE_CREATE(AMQP_VALUE_DATA); + AMQP_VALUE_DATA* map_item = (AMQP_VALUE_DATA*)REFCOUNT_TYPE_CREATE(AMQP_VALUE_DATA); if (map_item == NULL) { LogError("Could not allocate memory for map item"); @@ -7382,4 +7470,4 @@ AMQP_VALUE amqpvalue_get_list_item_in_place(AMQP_VALUE value, size_t index) } return result; -} +} \ No newline at end of file -- 2.43.0
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor