CVE-2024-29195 (published 2024-03-26T03:15Z)

The azure-c-shared-utility is a C library for AMQP/MQTT communication to Azure Cloud Services. This library may be used by the Azure IoT C SDK for communication between IoT Hub and IoT Hub devices. An attacker can cause an integer wraparound or under-allocation or heap buffer overflow due to vulnerabilities in parameter checking mechanism, by exploiting the buffer length parameter in Azure C SDK, which may lead to remote code execution. Requirements for RCE are 1. Compromised Azure account allowing malformed payloads to be sent to the device via IoT Hub service, 2. By passing IoT hub service max message payload limit of 128KB, and 3. Ability to overwrite code space with remote code. Fixed in commit https://github.com/Azure/azure-c-shared-utility/commit/1129147c38ac02ad974c4c701a1e01b2141b9fe2.


Weakness information:
cwe_id: NVD-CWE-noinfo
cwe_name: Insufficient Information
description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/Azure/azure-c-shared-utility
commit_details: repo_url: https://github.com/Azure/azure-c-shared-utility
author: Eric Wolz
author_date: 2024-01-26 14:37:39-08:00
msg: Add malloc size checks (#652)

* Add malloc size checks

* Update adapters/socketio_berkeley.c

Co-authored-by: Valerie Avva Lim <54871851+vaavva@users.noreply.github.com>

* Update adapters/string_utils.c

Co-authored-by: Valerie Avva Lim <54871851+vaavva@users.noreply.github.com>

* PR review

---------

Co-authored-by: Valerie Avva Lim <54871851+vaavva@users.noreply.github.com>
repository: repo_url: https://github.com/Azure/azure-c-shared-utility
repo_name: Azure/azure-c-shared-utility
description: Azure C SDKs common code
repo_language: C
owner: Azure
file_changes: filename: httpapi_compact.c
change_type: ModificationType.MODIFY
diff: @@ -18,6 +18,7 @@
 #include "azure_c_shared_utility/threadapi.h"
 #include "azure_c_shared_utility/shared_util_options.h"
 #include "azure_c_shared_utility/http_proxy_io.h"
+#include "azure_c_shared_utility/safe_math.h"
 
 #ifdef _MSC_VER
 #define snprintf _snprintf
@@ -431,7 +432,18 @@ static void on_bytes_received(void* context, const unsigned char* buffer, size_t
         else
         {
             /* Here we got some bytes so we'll buffer them so the receive functions can consumer it */
-            new_received_bytes = (unsigned char*)realloc(http_instance->received_bytes, http_instance->received_bytes_count + size);
+            size_t malloc_size = http_instance->received_bytes_count + size;
+            if (malloc_size < size)
+            {
+                // check for int overflow
+                new_received_bytes = NULL;
+                LogError("Invalid size parameter");
+            }
+            else
+            {
+                new_received_bytes = (unsigned char*)realloc(http_instance->received_bytes, malloc_size);
+            }
+
             if (new_received_bytes == NULL)
             {
                 http_instance->is_io_error = 1;
@@ -1301,15 +1313,25 @@ HTTPAPI_RESULT HTTPAPI_SetOption(HTTP_HANDLE handle, const char* optionName, con
         result = HTTPAPI_OK;
         http_instance->certificate = (char*)value;
 #else
-        int len;
 
         if (http_instance->certificate)
         {
             free(http_instance->certificate);
         }
 
-        len = (int)strlen((char*)value);
-        http_instance->certificate = (char*)malloc((len + 1) * sizeof(char));
+        size_t len = strlen((char*)value);
+        size_t malloc_size = safe_add_size_t(len, 1);
+        malloc_size = safe_multiply_size_t(malloc_size, sizeof(char));
+        if (malloc_size == SIZE_MAX)
+        {
+            LogError("Invalid malloc size");
+            http_instance->certificate = NULL;
+        }
+        else
+        {
+            http_instance->certificate = (char*)malloc(malloc_size);
+        }
+
         if (http_instance->certificate == NULL)
         {
             /*Codes_SRS_HTTPAPI_COMPACT_21_062: [ If any memory allocation get fail, the HTTPAPI_SetOption shall return HTTPAPI_ALLOC_FAILED. ]*/
@@ -1326,14 +1348,24 @@ HTTPAPI_RESULT HTTPAPI_SetOption(HTTP_HANDLE handle, const char* optionName, con
     }
     else if (strcmp(SU_OPTION_X509_CERT, optionName) == 0 || strcmp(OPTION_X509_ECC_CERT, optionName) == 0)
     {
-        int len;
         if (http_instance->x509ClientCertificate)
         {
             free(http_instance->x509ClientCertificate);
         }
 
-        len = (int)strlen((char*)value);
-        http_instance->x509ClientCertificate = (char*)malloc((len + 1) * sizeof(char));
+        size_t len = strlen((char*)value);
+        size_t malloc_size = safe_add_size_t(len, 1);
+        malloc_size = safe_multiply_size_t(malloc_size, sizeof(char));
+        if (malloc_size == SIZE_MAX)
+        {
+            LogError("Invalid malloc size");
+            http_instance->x509ClientCertificate = NULL;
+        }
+        else
+        {
+            http_instance->x509ClientCertificate = (char*)malloc(malloc_size);
+        }
+
         if (http_instance->x509ClientCertificate == NULL)
         {
             /*Codes_SRS_HTTPAPI_COMPACT_21_062: [ If any memory allocation get fail, the HTTPAPI_SetOption shall return HTTPAPI_ALLOC_FAILED. ]*/
@@ -1349,14 +1381,24 @@ HTTPAPI_RESULT HTTPAPI_SetOption(HTTP_HANDLE handle, const char* optionName, con
     }
     else if (strcmp(SU_OPTION_X509_PRIVATE_KEY, optionName) == 0 || strcmp(OPTION_X509_ECC_KEY, optionName) == 0)
     {
-        int len;
         if (http_instance->x509ClientPrivateKey)
         {
             free(http_instance->x509ClientPrivateKey);
         }
 
-        len = (int)strlen((char*)value);
-        http_instance->x509ClientPrivateKey = (char*)malloc((len + 1) * sizeof(char));
+        size_t len = strlen((char*)value);
+        size_t malloc_size = safe_add_size_t(len, 1);
+        malloc_size = safe_multiply_size_t(malloc_size, sizeof(char));
+        if (malloc_size == SIZE_MAX)
+        {
+            LogError("Invalid malloc size");
+            http_instance->x509ClientPrivateKey = NULL;
+        }
+        else
+        {
+            http_instance->x509ClientPrivateKey = (char*)malloc(malloc_size);
+        }
+
         if (http_instance->x509ClientPrivateKey == NULL)
         {
             /*Codes_SRS_HTTPAPI_COMPACT_21_062: [ If any memory allocation get fail, the HTTPAPI_SetOption shall return HTTPAPI_ALLOC_FAILED. ]*/
@@ -1482,7 +1524,17 @@ HTTPAPI_RESULT HTTPAPI_CloneOption(const char* optionName, const void* value, co
         result = HTTPAPI_OK;
 #else
         certLen = strlen((const char*)value);
-        tempCert = (char*)malloc((certLen + 1) * sizeof(char));
+        size_t malloc_size = safe_add_size_t(certLen, 1);
+        malloc_size = safe_multiply_size_t(malloc_size, sizeof(char));
+        if (malloc_size == SIZE_MAX)
+        {
+            tempCert = NULL;
+        }
+        else
+        {
+            tempCert = (char*)malloc(malloc_size);
+        }
+
         if (tempCert == NULL)
         {
             /*Codes_SRS_HTTPAPI_COMPACT_21_070: [ If any memory allocation get fail, the HTTPAPI_CloneOption shall return HTTPAPI_ALLOC_FAILED. ]*/
@@ -1500,7 +1552,18 @@ HTTPAPI_RESULT HTTPAPI_CloneOption(const char* optionName, const void* value, co
     else if (strcmp(SU_OPTION_X509_CERT, optionName) == 0 || strcmp(OPTION_X509_ECC_CERT, optionName) == 0)
     {
         certLen = strlen((const char*)value);
-        tempCert = (char*)malloc((certLen + 1) * sizeof(char));
+        size_t malloc_size = safe_add_size_t(certLen, 1);
+        malloc_size = safe_multiply_size_t(malloc_size, sizeof(char));
+        if (malloc_size == SIZE_MAX)
+        {
+            LogError("Invalid malloc size");
+            tempCert = NULL;
+        }
+        else
+        {
+            tempCert = (char*)malloc(malloc_size);
+        }
+
         if (tempCert == NULL)
         {
             /*Codes_SRS_HTTPAPI_COMPACT_21_070: [ If any memory allocation get fail, the HTTPAPI_CloneOption shall return HTTPAPI_ALLOC_FAILED. ]*/
@@ -1517,7 +1580,18 @@ HTTPAPI_RESULT HTTPAPI_CloneOption(const char* optionName, const void* value, co
     else if (strcmp(SU_OPTION_X509_PRIVATE_KEY, optionName) == 0 || strcmp(OPTION_X509_ECC_KEY, optionName) == 0)
     {
         certLen = strlen((const char*)value);
-        tempCert = (char*)malloc((certLen + 1) * sizeof(char));
+        size_t malloc_size = safe_add_size_t(certLen, 1);
+        malloc_size = safe_multiply_size_t(malloc_size, sizeof(char));
+        if (malloc_size == SIZE_MAX)
+        {
+            LogError("Invalid malloc size");
+            tempCert = NULL;
+        }
+        else
+        {
+            tempCert = (char*)malloc(malloc_size);
+        }
+
         if (tempCert == NULL)
         {
             /*Codes_SRS_HTTPAPI_COMPACT_21_070: [ If any memory allocation get fail, the HTTPAPI_CloneOption shall return HTTPAPI_ALLOC_FAILED. ]*/

programming_language: C
filename: httpapi_curl.c
change_type: ModificationType.MODIFY
diff: @@ -27,6 +27,7 @@
 #include "mbedtls/ssl.h"
 #endif
 #include "azure_c_shared_utility/shared_util_options.h"
+#include "azure_c_shared_utility/safe_math.h"
 
 #define TEMP_BUFFER_SIZE 1024
 
@@ -118,8 +119,18 @@ HTTP_HANDLE HTTPAPI_CreateConnection(const char* hostName)
         httpHandleData = (HTTP_HANDLE_DATA*)malloc(sizeof(HTTP_HANDLE_DATA));
         if (httpHandleData != NULL)
         {
-            size_t hostURL_size = strlen("https://") + strlen(hostName) + 1;
-            httpHandleData->hostURL = malloc(hostURL_size);
+            size_t hostURL_size = safe_add_size_t(strlen("https://"), strlen(hostName));
+            hostURL_size = safe_add_size_t(hostURL_size, 1);
+
+            if (hostURL_size == SIZE_MAX)
+            {
+                LogError("invalid malloc size");
+                httpHandleData->hostURL = NULL;
+            }
+            else
+            {
+                httpHandleData->hostURL = malloc(hostURL_size);
+            }
 
             if (httpHandleData->hostURL == NULL)
             {
@@ -282,7 +293,20 @@ static size_t ContentWriteFunction(void *ptr, size_t size, size_t nmemb, void *u
         (ptr != NULL) &&
         (size * nmemb > 0))
     {
-        void* newBuffer = realloc(responseContentBuffer->buffer, responseContentBuffer->bufferSize + (size * nmemb));
+        size_t malloc_size = safe_multiply_size_t(size, nmemb);
+        malloc_size = safe_add_size_t(malloc_size, responseContentBuffer->bufferSize);
+
+        void* newBuffer;
+        if (malloc_size == SIZE_MAX)
+        {
+            LogError("Invalid buffer size");
+            newBuffer = NULL;
+        }
+        else
+        {
+            newBuffer = realloc(responseContentBuffer->buffer, malloc_size);
+        }
+
         if (newBuffer != NULL)
         {
             responseContentBuffer->buffer = newBuffer;
@@ -291,7 +315,7 @@ static size_t ContentWriteFunction(void *ptr, size_t size, size_t nmemb, void *u
         }
         else
         {
-            LogError("Could not allocate buffer of size %lu", (unsigned long)(responseContentBuffer->bufferSize + (size * nmemb)));
+            LogError("Could not allocate buffer of size %lu", (unsigned long)(malloc_size));
             responseContentBuffer->error = 1;
             if (responseContentBuffer->buffer != NULL)
             {
@@ -452,8 +476,18 @@ HTTPAPI_RESULT HTTPAPI_ExecuteRequest(HTTP_HANDLE handle, HTTPAPI_REQUEST_TYPE r
     else
     {
         char* tempHostURL;
-        size_t tempHostURL_size = strlen(httpHandleData->hostURL) + strlen(relativePath) + 1;
-        tempHostURL = malloc(tempHostURL_size);
+        size_t tempHostURL_size = safe_add_size_t(strlen(httpHandleData->hostURL), strlen(relativePath));
+        tempHostURL_size = safe_add_size_t(tempHostURL_size, 1);
+        if (tempHostURL_size == SIZE_MAX)
+        {
+            LogError("Invalid malloc size");
+            tempHostURL = NULL;
+        }
+        else
+        {
+            tempHostURL = malloc(tempHostURL_size);
+        }
+
         if (tempHostURL == NULL)
         {
             result = HTTPAPI_ERROR;
@@ -963,8 +997,18 @@ HTTPAPI_RESULT HTTPAPI_SetOption(HTTP_HANDLE handle, const char* optionName, con
                 {
                     if (proxy_data->username != NULL && proxy_data->password != NULL)
                     {
-                        size_t authLen = strlen(proxy_data->username)+strlen(proxy_data->password)+1;
-                        proxy_auth = malloc(authLen+1);
+                        size_t authLen = safe_add_size_t(strlen(proxy_data->username), strlen(proxy_data->password));
+                        authLen = safe_add_size_t(authLen, 2);
+                        if (authLen == SIZE_MAX)
+                        {
+                            LogError("Invalid malloc size");
+                            proxy_auth = NULL;
+                        }
+                        else
+                        {
+                            proxy_auth = malloc(authLen);
+                        }
+
                         if (proxy_auth == NULL)
                         {
                             LogError("failure allocating proxy authentication");

programming_language: C
filename: httpapi_tirtos.c
change_type: ModificationType.MODIFY
diff: @@ -10,6 +10,7 @@
 #include "azure_c_shared_utility/httpapi.h"
 #include "azure_c_shared_utility/strings.h"
 #include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/safe_math.h"
 
 #define CONTENT_BUF_LEN     128
 
@@ -198,7 +199,17 @@ HTTPAPI_RESULT HTTPAPI_ExecuteRequest(HTTP_HANDLE handle,
         }
 
         if (cnt < offset + ret) {
-            hname = (char *)realloc(hname, offset + ret);
+            size_t malloc_size = safe_add_size_t(offset, ret);
+            if (malloc_size == SIZE_MAX)
+            {
+                LogError("invalid realloc size");
+                hname = NULL;
+            }
+            else
+            {
+                hname = (char*)realloc(hname, malloc_size);
+            }
+
             if (hname == NULL) {
                 LogError("Failed reallocating memory");
                 ret = HTTPAPI_ALLOC_FAILED;

programming_language: C
filename: httpapi_winhttp.c
change_type: ModificationType.MODIFY
diff: @@ -16,6 +16,7 @@
 #include "azure_c_shared_utility/strings.h"
 #include "azure_c_shared_utility/x509_schannel.h"
 #include "azure_c_shared_utility/shared_util_options.h"
+#include "azure_c_shared_utility/safe_math.h"
 
 MU_DEFINE_ENUM_STRINGS(HTTPAPI_RESULT, HTTPAPI_RESULT_VALUES)
 
@@ -51,8 +52,20 @@ static size_t nUsersOfHTTPAPI = 0; /*used for reference counting (a weak one)*/
 
 static char* ConcatHttpHeaders(HTTP_HEADERS_HANDLE httpHeadersHandle, size_t toAlloc, size_t headersCount)
 {
-    char *result = (char*)malloc(toAlloc * sizeof(char) + 1);
     size_t i;
+    char* result;
+
+    size_t malloc_size = safe_multiply_size_t(toAlloc, sizeof(char));
+    malloc_size = safe_add_size_t(malloc_size, 1);
+    if (malloc_size == SIZE_MAX)
+    {
+        LogError("Invalid malloc size");
+        result = NULL;
+    }
+    else
+    {
+        result = (char*)malloc(malloc_size);
+    }
     
     if (result == NULL)
     {
@@ -132,6 +145,7 @@ static HTTPAPI_RESULT ConstructHeadersString(HTTP_HEADERS_HANDLE httpHeadersHand
         {
             char *httpHeadersA;
             size_t requiredCharactersForHeaders;
+            size_t malloc_size;
 
             if ((httpHeadersA = ConcatHttpHeaders(httpHeadersHandle, toAlloc, headersCount)) == NULL)
             {
@@ -143,7 +157,8 @@ static HTTPAPI_RESULT ConstructHeadersString(HTTP_HEADERS_HANDLE httpHeadersHand
                 result = HTTPAPI_STRING_PROCESSING_ERROR;
                 LogError("MultiByteToWideChar failed, GetLastError=0x%08x (result = %" PRI_MU_ENUM ")", GetLastError(), MU_ENUM_VALUE(HTTPAPI_RESULT, result));
             }
-            else if ((*httpHeaders = (wchar_t*)malloc((requiredCharactersForHeaders + 1) * sizeof(wchar_t))) == NULL)
+            else if ((malloc_size = safe_multiply_size_t(safe_add_size_t(requiredCharactersForHeaders, 1), sizeof(wchar_t))) == SIZE_MAX ||
+                (*httpHeaders = (wchar_t*)malloc(malloc_size)) == NULL)
             {
                 result = HTTPAPI_ALLOC_FAILED;
                 LogError("Cannot allocate memory (result = %" PRI_MU_ENUM ")", MU_ENUM_VALUE(HTTPAPI_RESULT, result));
@@ -332,7 +347,17 @@ HTTP_HANDLE HTTPAPI_CreateConnection(const char* hostName)
             }
             else
             {
-                hostNameTemp = (wchar_t*)malloc(sizeof(wchar_t) * hostNameTemp_size);
+                size_t malloc_size = safe_multiply_size_t(sizeof(wchar_t), hostNameTemp_size);
+                if (malloc_size == SIZE_MAX)
+                {
+                    LogError("Invalid malloc size");
+                    hostNameTemp = NULL;
+                }
+                else
+                {
+                    hostNameTemp = (wchar_t*)malloc(malloc_size);
+                }
+
                 if (hostNameTemp == NULL)
                 {
                     LogError("malloc failed");
@@ -454,7 +479,8 @@ static HTTPAPI_RESULT InitiateWinhttpRequest(HTTP_HANDLE_DATA* handleData, HTTPA
     const wchar_t* requestTypeString;
     size_t requiredCharactersForRelativePath;
     wchar_t* relativePathTemp = NULL;
-    
+    size_t malloc_size;
+
     if ((requestTypeString = GetHttpRequestString(requestType)) == NULL)
     {
         result = HTTPAPI_INVALID_ARG;
@@ -465,7 +491,12 @@ static HTTPAPI_RESULT InitiateWinhttpRequest(HTTP_HANDLE_DATA* handleData, HTTPA
         result = HTTPAPI_STRING_PROCESSING_ERROR;
         LogError("MultiByteToWideChar failed, GetLastError=0x%08x", GetLastError());
     }
-    else if ((relativePathTemp = (wchar_t*)malloc((requiredCharactersForRelativePath + 1) * sizeof(wchar_t))) == NULL)
+    else if ((malloc_size = safe_multiply_size_t(safe_add_size_t(requiredCharactersForRelativePath, 1), sizeof(wchar_t))) == SIZE_MAX)
+    {
+        LogError("malloc invalid size");
+        result = HTTPAPI_ALLOC_FAILED;
+    }
+    else if ((relativePathTemp = (wchar_t*)malloc(malloc_size)) == NULL)
     {
         result = HTTPAPI_ALLOC_FAILED;
         LogError("malloc failed (result = %" PRI_MU_ENUM ")", MU_ENUM_VALUE(HTTPAPI_RESULT, result));
@@ -780,7 +811,18 @@ static HTTPAPI_RESULT ReceiveResponseHeaders(HINTERNET requestHandle, HTTP_HEADE
         &responseHeadersTempLength,
         WINHTTP_NO_HEADER_INDEX);
 
-    if ((responseHeadersTemp = (wchar_t*)malloc((size_t)responseHeadersTempLength + 2)) == NULL)
+    size_t malloc_size = safe_add_size_t((size_t)responseHeadersTempLength, 2);
+    if (malloc_size == SIZE_MAX)
+    {
+        LogError("Invalid malloc size");
+        responseHeadersTemp = NULL;
+    }
+    else
+    {
+        responseHeadersTemp = (wchar_t*)malloc(malloc_size);
+    }
+
+    if (responseHeadersTemp == NULL)
     {
         result = HTTPAPI_ALLOC_FAILED;
         LogError("malloc failed: (result = %" PRI_MU_ENUM ")", MU_ENUM_VALUE(HTTPAPI_RESULT, result));
@@ -816,7 +858,13 @@ static HTTPAPI_RESULT ReceiveResponseHeaders(HINTERNET requestHandle, HTTP_HEADE
                 LogError("WideCharToMultiByte failed");
                 break;
             }
-            else if ((tokenTemp = (char*)malloc(sizeof(char) * tokenTemp_size)) == NULL)
+            else if ((malloc_size = safe_multiply_size_t(sizeof(char), tokenTemp_size)) == SIZE_MAX)
+            {
+                result = HTTPAPI_ALLOC_FAILED;
+                LogError("invalid malloc size");
+                break;
+            }
+            else if ((tokenTemp = (char*)malloc(malloc_size)) == NULL)
             {
                 result = HTTPAPI_ALLOC_FAILED;
                 LogError("malloc failed");

programming_language: C
filename: socketio_berkeley.c
change_type: ModificationType.MODIFY
diff: @@ -47,6 +47,7 @@
 #include "azure_c_shared_utility/xlogging.h"
 #include "azure_c_shared_utility/const_defines.h"
 #include "azure_c_shared_utility/dns_resolver.h"
+#include "azure_c_shared_utility/safe_math.h"
 #include <sys/ioctl.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
@@ -126,7 +127,13 @@ static void* socketio_CloneOption(const char* name, const void* value)
             }
             else
             {
-                if ((result = malloc(sizeof(char) * (strlen((char*)value) + 1))) == NULL)
+                size_t malloc_size = safe_add_size_t(strlen((char*)value), 1);
+                malloc_size = safe_multiply_size_t(malloc_size, sizeof(char));
+                if (malloc_size == SIZE_MAX)
+                {
+                    LogError("Invalid malloc size");
+                }
+                else if ((result = malloc(malloc_size)) == NULL)
                 {
                     LogError("Failed cloning option %s (malloc failed)", name);
                 }
@@ -313,12 +320,19 @@ static void destroy_network_interface_descriptions(NETWORK_INTERFACE_DESCRIPTION
 static NETWORK_INTERFACE_DESCRIPTION* create_network_interface_description(struct ifreq *ifr, NETWORK_INTERFACE_DESCRIPTION* previous_nid)
 {
     NETWORK_INTERFACE_DESCRIPTION* result;
+    size_t malloc_size;
 
     if ((result = (NETWORK_INTERFACE_DESCRIPTION*)malloc(sizeof(NETWORK_INTERFACE_DESCRIPTION))) == NULL)
     {
         LogError("Failed allocating NETWORK_INTERFACE_DESCRIPTION");
     }
-    else if ((result->name = (char*)malloc(sizeof(char) * (strlen(ifr->ifr_name) + 1))) == NULL)
+    else if ((malloc_size = safe_multiply_size_t(safe_add_size_t(strlen(ifr->ifr_name), 1), sizeof(char))) == SIZE_MAX)
+    {
+        LogError("invalid malloc size");
+        destroy_network_interface_descriptions(result);
+        result = NULL;
+    }
+    else if ((result->name = (char*)malloc(malloc_size)) == NULL)
     {
         LogError("failed setting interface description name (malloc failed)");
         destroy_network_interface_descriptions(result);
@@ -330,10 +344,12 @@ static NETWORK_INTERFACE_DESCRIPTION* create_network_interface_description(struc
 
         char* ip_address;
         unsigned char* mac = (unsigned char*)ifr->ifr_hwaddr.sa_data;
+        size_t malloc_size = safe_multiply_size_t(sizeof(char), MAC_ADDRESS_STRING_LENGTH);
 
-        if ((result->mac_address = (char*)malloc(sizeof(char) * MAC_ADDRESS_STRING_LENGTH)) == NULL)
+        if (malloc_size == SIZE_MAX ||
+                (result->mac_address = (char*)malloc(malloc_size)) == NULL)
         {
-            LogError("failed formatting mac address (malloc failed)");
+            LogError("failed formatting mac address (malloc failed) size:%zu", malloc_size);
             destroy_network_interface_descriptions(result);
             result = NULL;
         }
@@ -349,7 +365,13 @@ static NETWORK_INTERFACE_DESCRIPTION* create_network_interface_description(struc
             destroy_network_interface_descriptions(result);
             result = NULL;
         }
-        else if ((result->ip_address = (char*)malloc(sizeof(char) * (strlen(ip_address) + 1))) == NULL)
+        else if ((malloc_size = safe_multiply_size_t(safe_add_size_t(strlen(ip_address), 1), sizeof(char))) == SIZE_MAX)
+        {
+            LogError("invalid malloc size");
+            destroy_network_interface_descriptions(result);
+            result = NULL;
+        }
+        else if ((result->ip_address = (char*)malloc(malloc_size)) == NULL)
         {
             LogError("failed setting the ip address (malloc failed)");
             destroy_network_interface_descriptions(result);
@@ -742,10 +764,19 @@ CONCRETE_IO_HANDLE socketio_create(void* io_create_parameters)
             {
                 if (socket_io_config->hostname != NULL)
                 {
-                    result->hostname = (char*)malloc(strlen(socket_io_config->hostname) + 1);
-                    if (result->hostname != NULL)
+                    size_t malloc_size = safe_add_size_t(strlen(socket_io_config->hostname), 1);
+                    if (malloc_size == SIZE_MAX)
                     {
-                        (void)strcpy(result->hostname, socket_io_config->hostname);
+                        LogError("invalid malloc size");
+                        result->hostname = NULL;
+                    }
+                    else
+                    {
+                        result->hostname = (char*)malloc(malloc_size);
+                        if (result->hostname != NULL)
+                        {
+                            (void)strcpy(result->hostname, socket_io_config->hostname);
+                        }
                     }
 
                     result->socket = INVALID_SOCKET;
@@ -1205,12 +1236,19 @@ int socketio_setoption(CONCRETE_IO_HANDLE socket_io, const char* optionName, con
             LogError("option not supported.");
             result = MU_FAILURE;
 #else
+            size_t malloc_size;
             if (strlen(value) == 0)
             {
                 LogError("option value must be a valid mac address");
                 result = MU_FAILURE;
             }
-            else if ((socket_io_instance->target_mac_address = (char*)malloc(sizeof(char) * (strlen(value) + 1))) == NULL)
+            else if ((malloc_size = safe_multiply_size_t(safe_add_size_t(strlen(value), 1), sizeof(char))) == SIZE_MAX)
+            {
+                LogError("invalid malloc size");
+                result = MU_FAILURE;
+                socket_io_instance->target_mac_address = NULL;
+            }
+            else if ((socket_io_instance->target_mac_address = (char*)malloc(malloc_size)) == NULL)
             {
                 LogError("failed setting net_interface_mac_address option (malloc failed)");
                 result = MU_FAILURE;

programming_language: C
filename: socketio_win32.c
change_type: ModificationType.MODIFY
diff: @@ -18,6 +18,7 @@
 #include "azure_c_shared_utility/shared_util_options.h"
 #include "azure_c_shared_utility/xlogging.h"
 #include "azure_c_shared_utility/dns_resolver.h"
+#include "azure_c_shared_utility/safe_math.h"
 
 typedef enum IO_STATE_TAG
 {
@@ -336,10 +337,19 @@ CONCRETE_IO_HANDLE socketio_create(void* io_create_parameters)
             {
                 if (socket_io_config->hostname != NULL)
                 {
-                    result->hostname = (char*)malloc(strlen(socket_io_config->hostname) + 1);
-                    if (result->hostname != NULL)
+                    size_t malloc_size = safe_add_size_t(strlen(socket_io_config->hostname), 1);
+                    if (malloc_size == SIZE_MAX)
                     {
-                        (void)strcpy(result->hostname, socket_io_config->hostname);
+                        LogError("Invalid malloc size");
+                        result->hostname = NULL;
+                    }
+                    else
+                    {
+                        result->hostname = (char*)malloc(malloc_size);
+                        if (result->hostname != NULL)
+                        {
+                            (void)strcpy(result->hostname, socket_io_config->hostname);
+                        }
                     }
 
                     result->socket = INVALID_SOCKET;

programming_language: C
filename: string_utils.c
change_type: ModificationType.MODIFY
diff: @@ -10,6 +10,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_c_shared_utility/string_utils.h"
 
@@ -24,8 +25,15 @@ IMPLEMENT_MOCKABLE_FUNCTION(, char*, vsprintf_char, const char*, format, va_list
     }
     else
     {
-        result = (char*)malloc(((unsigned long long)neededSize + 1) * sizeof(char));
-        if (result == NULL)
+        size_t malloc_size = safe_add_size_t((unsigned long long)neededSize, 1);
+        malloc_size = safe_multiply_size_t(malloc_size, sizeof(char));
+        if (malloc_size == SIZE_MAX)
+        {
+            LogError("invalid malloc size");
+            result = NULL;
+            /*return as is*/
+        }
+        else if ((result = (char*)malloc(malloc_size)) == NULL)
         {
             LogError("failure in malloc");
             /*return as is*/
@@ -54,8 +62,15 @@ IMPLEMENT_MOCKABLE_FUNCTION(, wchar_t*, vsprintf_wchar, const wchar_t*, format,
     }
     else
     {
-        result = (wchar_t*)malloc(((unsigned long long)neededSize + 1)*sizeof(wchar_t));
-        if (result == NULL)
+        size_t malloc_size = safe_add_size_t((unsigned long long)neededSize, 1);
+        malloc_size = safe_multiply_size_t(malloc_size, sizeof(wchar_t));
+        if (malloc_size == SIZE_MAX)
+        {
+            LogError("invalid malloc size");
+            result = NULL;
+            /*return as is*/
+        }
+        else if ((result = (wchar_t*)malloc(malloc_size)) == NULL)
         {
             LogError("failure in malloc");
             /*return as is*/
@@ -169,8 +184,15 @@ IMPLEMENT_MOCKABLE_FUNCTION(, wchar_t*, mbs_to_wcs, const char*, source)
         }
         else
         {
-            result = (wchar_t*)malloc(sizeof(wchar_t)*(nwc+1));
-            if (result == NULL)
+            size_t malloc_size = safe_add_size_t(nwc, 1);
+            malloc_size = safe_multiply_size_t(malloc_size, sizeof(wchar_t));
+            if (malloc_size == SIZE_MAX)
+            {
+                LogError("invalid malloc size");
+                result = NULL;
+                /*return as is*/
+            }
+            else if ((result = (wchar_t*)malloc(malloc_size)) == NULL)
             {
                 LogError("failure in malloc");
                 /*return as is*/
@@ -216,8 +238,15 @@ IMPLEMENT_MOCKABLE_FUNCTION(, char*, wcs_to_mbs, const wchar_t*, source)
         }
         else
         {
-            result = (char*)malloc(sizeof(char)*(nc + 1));
-            if (result == NULL)
+            size_t malloc_size = safe_add_size_t(nc, 1);
+            malloc_size = safe_multiply_size_t(malloc_size, sizeof(char));
+            if (malloc_size == SIZE_MAX)
+            {
+                LogError("invalid malloc size");
+                result = NULL;
+                /*return as is*/
+            }
+            else if ((result = (char*)malloc(malloc_size)) == NULL)
             {
                 LogError("failure in malloc");
                 /*return as is*/

programming_language: C
filename: tlsio_mbedtls.c
change_type: ModificationType.MODIFY
diff: @@ -24,6 +24,7 @@
 #include "azure_c_shared_utility/crt_abstractions.h"
 #include "azure_c_shared_utility/shared_util_options.h"
 #include "azure_c_shared_utility/threadapi.h"
+#include "azure_c_shared_utility/safe_math.h"
 
 static const char *const OPTION_UNDERLYING_IO_OPTIONS = "underlying_io_options";
 
@@ -206,12 +207,19 @@ static void on_underlying_io_bytes_received(void *context, const unsigned char *
 {
     if (context != NULL)
     {
+        unsigned char* new_socket_io_read_bytes;
         TLS_IO_INSTANCE *tls_io_instance = (TLS_IO_INSTANCE *)context;
 
-        unsigned char *new_socket_io_read_bytes = (unsigned char *)realloc(tls_io_instance->socket_io_read_bytes, tls_io_instance->socket_io_read_byte_count + size);
-
-        if (new_socket_io_read_bytes == NULL)
+        size_t realloc_size = safe_add_size_t(tls_io_instance->socket_io_read_byte_count, size);
+        if (realloc_size == SIZE_MAX)
+        {
+            LogError("Invalid realloc size");
+            tls_io_instance->tlsio_state = TLSIO_STATE_ERROR;
+            indicate_error(tls_io_instance);
+        }
+        else if ((new_socket_io_read_bytes = (unsigned char*)realloc(tls_io_instance->socket_io_read_bytes, realloc_size)) == NULL)
         {
+            LogError("realloc failed");
             tls_io_instance->tlsio_state = TLSIO_STATE_ERROR;
             indicate_error(tls_io_instance);
         }

programming_language: C
filename: tlsio_openssl.c
change_type: ModificationType.MODIFY
diff: @@ -21,6 +21,7 @@
 #include "azure_c_shared_utility/shared_util_options.h"
 #include "azure_c_shared_utility/gballoc.h"
 #include "azure_c_shared_utility/const_defines.h"
+#include "azure_c_shared_utility/safe_math.h"
 
 typedef enum TLSIO_STATE_TAG
 {
@@ -607,10 +608,11 @@ static int openssl_static_locks_install(void)
     }
     else
     {
-        openssl_locks = malloc(CRYPTO_num_locks() * sizeof(LOCK_HANDLE));
-        if (openssl_locks == NULL)
+        size_t malloc_size = safe_multiply_size_t(CRYPTO_num_locks(), sizeof(LOCK_HANDLE));
+        if (malloc_size == SIZE_MAX ||
+            (openssl_locks = malloc(malloc_size)) == NULL)
         {
-            LogError("Failed to allocate locks");
+            LogError("Failed to allocate locks, size:%zu", malloc_size);
             result = MU_FAILURE;
         }
         else
@@ -1654,9 +1656,11 @@ int tlsio_openssl_setoption(CONCRETE_IO_HANDLE tls_io, const char* optionName, c
 
             // Store the certificate
             len = strlen(cert);
-            tls_io_instance->certificate = malloc(len + 1);
-            if (tls_io_instance->certificate == NULL)
+            size_t malloc_size = safe_add_size_t(len, 1);
+            if (malloc_size == SIZE_MAX ||
+                (tls_io_instance->certificate = malloc(malloc_size)) == NULL)
             {
+                LogError("malloc failure, size:%zu", malloc_size);
                 result = MU_FAILURE;
             }
             else

programming_language: C
filename: tlsio_schannel.c
change_type: ModificationType.MODIFY
diff: @@ -21,6 +21,7 @@
 #include "azure_c_shared_utility/singlylinkedlist.h"
 #include "azure_c_shared_utility/shared_util_options.h"
 #include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/safe_math.h"
 
 #define TLSIO_STATE_VALUES                        \
     TLSIO_STATE_NOT_OPEN,                         \
@@ -515,13 +516,15 @@ static int send_chunk(CONCRETE_IO_HANDLE tls_io, const void* buffer, size_t size
             }
             else
             {
+                unsigned char* out_buffer;
                 SecBuffer security_buffers[4];
                 SecBufferDesc security_buffers_desc;
-                size_t needed_buffer = sizes.cbHeader + size + sizes.cbTrailer;
-                unsigned char* out_buffer = (unsigned char*)malloc(needed_buffer);
-                if (out_buffer == NULL)
+                size_t needed_buffer = safe_add_size_t(sizes.cbHeader, size);
+                needed_buffer = safe_add_size_t(needed_buffer, sizes.cbTrailer);
+                if (needed_buffer == SIZE_MAX ||
+                    (out_buffer = (unsigned char*)malloc(needed_buffer)) == NULL)
                 {
-                    LogError("malloc failed");
+                    LogError("malloc failed, size:%zu", needed_buffer);
                     result = MU_FAILURE;
                 }
                 else
@@ -1089,10 +1092,12 @@ CONCRETE_IO_HANDLE tlsio_schannel_create(void* io_create_parameters)
         {
             (void)memset(result, 0, sizeof(TLS_IO_INSTANCE));
 
-            result->host_name = (SEC_TCHAR*)malloc(sizeof(SEC_TCHAR) * (1 + strlen(tls_io_config->hostname)));
-            if (result->host_name == NULL)
+            size_t malloc_size = safe_add_size_t(strlen(tls_io_config->hostname), 1);
+            malloc_size = safe_multiply_size_t(malloc_size, sizeof(SEC_TCHAR));
+            if (malloc_size == SIZE_MAX ||
+                (result->host_name = (SEC_TCHAR*)malloc(malloc_size)) == NULL)
             {
-                LogError("malloc failed");
+                LogError("malloc failed, size:%zu", malloc_size);
                 free(result);
                 result = NULL;
             }

programming_language: C
filename: tlsio_wolfssl.c
change_type: ModificationType.MODIFY
diff: @@ -18,6 +18,7 @@
 #include "azure_c_shared_utility/optimize_size.h"
 #include "azure_c_shared_utility/xlogging.h"
 #include "azure_c_shared_utility/shared_util_options.h"
+#include "azure_c_shared_utility/safe_math.h"
 
 typedef enum TLSIO_STATE_ENUM_TAG
 {
@@ -303,11 +304,13 @@ static void on_underlying_io_bytes_received(void* context, const unsigned char*
     if (context != NULL)
     {
         TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context;
+        unsigned char* new_socket_io_read_bytes;
 
-        unsigned char* new_socket_io_read_bytes = (unsigned char*)realloc(tls_io_instance->socket_io_read_bytes, tls_io_instance->socket_io_read_byte_count + size);
-        if (new_socket_io_read_bytes == NULL)
+        size_t realloc_size = safe_add_size_t(tls_io_instance->socket_io_read_byte_count, size);
+        if (realloc_size == SIZE_MAX ||
+            (new_socket_io_read_bytes = (unsigned char*)realloc(tls_io_instance->socket_io_read_bytes, realloc_size)) == NULL)
         {
-            LogError("Failed allocating memory for received bytes");
+            LogError("Failed allocating memory for received bytes, size:%zu", realloc_size);
             tls_io_instance->tlsio_state = TLSIO_STATE_ERROR;
             indicate_error(tls_io_instance);
         }

programming_language: C
filename: x509_schannel.c
change_type: ModificationType.MODIFY
diff: @@ -6,6 +6,8 @@
 #include "azure_c_shared_utility/gballoc.h"
 #include "azure_c_shared_utility/x509_schannel.h"
 #include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/safe_math.h"
+
 #if _MSC_VER > 1500
 #include <ncrypt.h>
 #endif
@@ -153,19 +155,21 @@ static int set_ecc_certificate_info(X509_SCHANNEL_HANDLE_DATA* x509_handle, unsi
 {
     int result;
 #if _MSC_VER > 1500
+    BCRYPT_ECCKEY_BLOB* pKeyBlob;
     SECURITY_STATUS status;
     CRYPT_BIT_BLOB* pPubKeyBlob = &x509_handle->x509certificate_context->pCertInfo->SubjectPublicKeyInfo.PublicKey;
     CRYPT_ECC_PRIVATE_KEY_INFO* pPrivKeyInfo = (CRYPT_ECC_PRIVATE_KEY_INFO*)x509privatekeyBlob;
     DWORD pubSize = pPubKeyBlob->cbData - 1;
     DWORD privSize = pPrivKeyInfo->PrivateKey.cbData;
-    DWORD keyBlobSize = sizeof(BCRYPT_ECCKEY_BLOB) + pubSize + privSize;
+    size_t keyBlobSize = safe_add_size_t(safe_add_size_t(sizeof(BCRYPT_ECCKEY_BLOB), pubSize), privSize);
     BYTE* pubKeyBuf = pPubKeyBlob->pbData + 1;
     BYTE* privKeyBuf = pPrivKeyInfo->PrivateKey.pbData;
-    BCRYPT_ECCKEY_BLOB* pKeyBlob = (BCRYPT_ECCKEY_BLOB*)malloc(keyBlobSize);
-    if (pKeyBlob == NULL)
+
+    if (keyBlobSize == SIZE_MAX ||
+        (pKeyBlob = (BCRYPT_ECCKEY_BLOB*)malloc(keyBlobSize)) == NULL)
     {
         /*Codes_SRS_X509_SCHANNEL_02_010: [ Otherwise, x509_schannel_create shall fail and return a NULL X509_SCHANNEL_HANDLE. ]*/
-        LogError("Failed to malloc NCrypt private key blob");
+        LogError("Failed to malloc NCrypt private key blob, size:%zu", keyBlobSize);
         result = MU_FAILURE;
     }
     else
@@ -200,7 +204,7 @@ static int set_ecc_certificate_info(X509_SCHANNEL_HANDLE_DATA* x509_handle, unsi
 
             /*Codes_SRS_X509_SCHANNEL_02_006: [ x509_schannel_create shall import the private key by calling CryptImportKey. ] */
             /*NOTE: As no WinCrypt key storage provider supports ECC keys, NCrypt is used instead*/
-            status = NCryptImportKey(x509_handle->hProv, 0, BCRYPT_ECCPRIVATE_BLOB, &ncBufDesc, &x509_handle->x509hcryptkey, (BYTE*)pKeyBlob, keyBlobSize, NCRYPT_OVERWRITE_KEY_FLAG);
+            status = NCryptImportKey(x509_handle->hProv, 0, BCRYPT_ECCPRIVATE_BLOB, &ncBufDesc, &x509_handle->x509hcryptkey, (BYTE*)pKeyBlob, (DWORD)keyBlobSize, NCRYPT_OVERWRITE_KEY_FLAG);
             if (status == ERROR_SUCCESS)
             {
                 status2 = NCryptFreeObject(x509_handle->x509hcryptkey);

programming_language: C++
filename: xlogging.h
change_type: ModificationType.MODIFY
diff: @@ -136,9 +136,11 @@ typedef void(*LOGGER_LOG_GETLASTERROR)(const char* file, const char* func, int l
             }                                                                                                                                                           \
             else                                                                                                                                                        \
             {                                                                                                                                                           \
+                char* formatWithStack;                                                                                                                                  \
                 size_t formatSize = strlen(format);                                                                                                                     \
-                char* formatWithStack = (char*)logging_malloc(formatSize + sizeof("STACK_PRINT_FORMAT"));                                                               \
-                if (formatWithStack == NULL)                                                                                                                            \
+                size_t mallocSize = formatSize + sizeof("STACK_PRINT_FORMAT");                                                                                          \
+                if (mallocSize < formatSize ||   /* int overflow check */                                                                                               \
+                    (formatWithStack = (char*)logging_malloc(mallocSize)) == NULL)                                                                                      \
                 {                                                                                                                                                       \
                     l(log_category, __FILE__, FUNC_NAME, __LINE__, log_options, format, __VA_ARGS__);                                                                   \
                 }                                                                                                                                                       \

programming_language: C
filename: buffer.c
change_type: ModificationType.MODIFY
diff: @@ -228,11 +228,13 @@ int BUFFER_append_build(BUFFER_HANDLE handle, const unsigned char* source, size_
         else
         {
             /* Codes_SRS_BUFFER_07_032: [ if handle->buffer is not NULL BUFFER_append_build shall realloc the buffer to be the handle->size + size ] */
-            unsigned char* temp = (unsigned char*)realloc(handle->buffer, handle->size + size);
-            if (temp == NULL)
+            unsigned char* temp;
+            size_t malloc_size = safe_add_size_t(handle->size, size);
+            if (malloc_size == SIZE_MAX || 
+                (temp = (unsigned char*)realloc(handle->buffer, malloc_size)) == NULL)
             {
                 /* Codes_SRS_BUFFER_07_035: [ If any error is encountered BUFFER_append_build shall return a non-null value. ] */
-                LogError("Failure reallocating temporary buffer");
+                LogError("Failure reallocating temporary buffer, size:%zu", malloc_size);
                 result = MU_FAILURE;
             }
             else
@@ -357,12 +359,14 @@ int BUFFER_enlarge(BUFFER_HANDLE handle, size_t enlargeSize)
     }
     else
     {
+        unsigned char* temp;
         BUFFER* b = (BUFFER*)handle;
-        unsigned char* temp = (unsigned char*)realloc(b->buffer, b->size + enlargeSize);
-        if (temp == NULL)
+        size_t malloc_size = safe_add_size_t(b->size, enlargeSize);
+        if (malloc_size == SIZE_MAX ||
+            (temp = (unsigned char*)realloc(b->buffer, malloc_size)) == NULL)
         {
             /* Codes_SRS_BUFFER_07_018: [BUFFER_enlarge shall return a nonzero result if any error is encountered.] */
-            LogError("Failure: allocating temp buffer.");
+            LogError("Failure: allocating temp buffer, size:%zu", malloc_size);
             result = MU_FAILURE;
         }
         else
@@ -494,8 +498,10 @@ int BUFFER_append(BUFFER_HANDLE handle1, BUFFER_HANDLE handle2)
             else
             {
                 // b2->size != 0, whatever b1->size is
-                unsigned char* temp = (unsigned char*)realloc(b1->buffer, b1->size + b2->size);
-                if (temp == NULL)
+                unsigned char* temp;
+                size_t malloc_size = safe_add_size_t(b1->size, b2->size);
+                if (malloc_size == SIZE_MAX || 
+                    (temp = (unsigned char*)realloc(b1->buffer, malloc_size)) == NULL)
                 {
                     /* Codes_SRS_BUFFER_07_023: [BUFFER_append shall return a nonzero upon any error that is encountered.] */
                     LogError("Failure: allocating temp buffer.");

programming_language: C
filename: constbuffer.c
change_type: ModificationType.MODIFY
diff: @@ -33,7 +33,18 @@ static CONSTBUFFER_HANDLE CONSTBUFFER_Create_Internal(const unsigned char* sourc
     CONSTBUFFER_HANDLE result;
     /*Codes_SRS_CONSTBUFFER_02_005: [The non-NULL handle returned by CONSTBUFFER_Create shall have its ref count set to "1".]*/
     /*Codes_SRS_CONSTBUFFER_02_010: [The non-NULL handle returned by CONSTBUFFER_CreateFromBuffer shall have its ref count set to "1".]*/
-    result = (CONSTBUFFER_HANDLE)calloc(1, (sizeof(CONSTBUFFER_HANDLE_DATA) + size));
+    size_t malloc_size = sizeof(CONSTBUFFER_HANDLE_DATA) + size;
+    if (malloc_size < size)
+    {
+        result = NULL;
+        LogError("invalid size parameter");
+        /*return as is*/
+    }
+    else
+    {
+        result = (CONSTBUFFER_HANDLE)calloc(1, malloc_size);
+    }
+
     if (result == NULL)
     {
         /*Codes_SRS_CONSTBUFFER_02_003: [If creating the copy fails then CONSTBUFFER_Create shall return NULL.]*/

programming_language: C