File CVE-2024-21646.patch of Package python-uamqp.32584

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

openSUSE Build Service is sponsored by