From a52bccdbc0c0f01a365adbc66b069f74e68ae415 Mon Sep 17 00:00:00 2001 From: Ankur Tyagi Date: Thu, 9 Oct 2025 17:10:48 +1300 Subject: libiec61850: patch CVE-2024-45971 Details https://nvd.nist.gov/vuln/detail/CVE-2024-45971 Signed-off-by: Ankur Tyagi Signed-off-by: Gyorgy Sarvari --- ...7-replaced-unsafe-function-StringUtils_cr.patch | 218 +++++++++++++++++++++ .../libiec61850/libiec61850_1.5.3.bb | 1 + 2 files changed, 219 insertions(+) create mode 100644 meta-networking/recipes-connectivity/libiec61850/files/0004-LIB61850-447-replaced-unsafe-function-StringUtils_cr.patch (limited to 'meta-networking') diff --git a/meta-networking/recipes-connectivity/libiec61850/files/0004-LIB61850-447-replaced-unsafe-function-StringUtils_cr.patch b/meta-networking/recipes-connectivity/libiec61850/files/0004-LIB61850-447-replaced-unsafe-function-StringUtils_cr.patch new file mode 100644 index 0000000000..4d98df490e --- /dev/null +++ b/meta-networking/recipes-connectivity/libiec61850/files/0004-LIB61850-447-replaced-unsafe-function-StringUtils_cr.patch @@ -0,0 +1,218 @@ +From c8fa1fb0e11eb3993faa5f3df09c6d3c4d2305c1 Mon Sep 17 00:00:00 2001 +From: Michael Zillgith +Date: Mon, 22 Jul 2024 16:34:03 +0100 +Subject: [PATCH] LIB61850-447: replaced unsafe function + StringUtils_createStringFromBufferInBuffer with function with length check to + not exceed target buffer + +CVE: CVE-2024-45971 +Upstream-Status: Backport [https://github.com/mz-automation/libiec61850/commit/1f52be9ddeae00e69cd43e4cac3cb4f0c880c4f0] + +(cherry picked from commit 1f52be9ddeae00e69cd43e4cac3cb4f0c880c4f0) +Signed-off-by: Ankur Tyagi +--- + src/common/inc/string_utilities.h | 3 ++ + src/common/string_utilities.c | 12 +++++ + src/iec61850/server/mms_mapping/mms_mapping.c | 6 ++- + src/mms/iso_mms/client/mms_client_identify.c | 6 +-- + .../server/mms_named_variable_list_service.c | 52 +++++++++---------- + 5 files changed, 48 insertions(+), 31 deletions(-) + +diff --git a/src/common/inc/string_utilities.h b/src/common/inc/string_utilities.h +index b6b238ff..9a5d868a 100644 +--- a/src/common/inc/string_utilities.h ++++ b/src/common/inc/string_utilities.h +@@ -63,6 +63,9 @@ StringUtils_createStringFromBuffer(const uint8_t* buf, int size); + LIB61850_INTERNAL char* + StringUtils_createStringFromBufferInBuffer(char* newString, const uint8_t* buf, int size); + ++LIB61850_INTERNAL char* ++StringUtils_createStringFromBufferInBufferMax(char* newString, const uint8_t* buf, int size, int maxBufSize); ++ + LIB61850_INTERNAL void + StringUtils_replace(char* string, char oldChar, char newChar); + +diff --git a/src/common/string_utilities.c b/src/common/string_utilities.c +index 37e62ad7..378acbde 100644 +--- a/src/common/string_utilities.c ++++ b/src/common/string_utilities.c +@@ -85,6 +85,18 @@ StringUtils_createStringFromBufferInBuffer(char* newString, const uint8_t* buf, + return newString; + } + ++char* ++StringUtils_createStringFromBufferInBufferMax(char* newString, const uint8_t* buf, int size, int maxBufSize) ++{ ++ if (size >= maxBufSize) ++ size = maxBufSize - 1; ++ ++ memcpy(newString, buf, size); ++ newString[size] = 0; ++ ++ return newString; ++} ++ + char* + StringUtils_createStringInBuffer(char* newStr, int bufSize, int count, ...) + { +diff --git a/src/iec61850/server/mms_mapping/mms_mapping.c b/src/iec61850/server/mms_mapping/mms_mapping.c +index 707e8b57..4a700a27 100644 +--- a/src/iec61850/server/mms_mapping/mms_mapping.c ++++ b/src/iec61850/server/mms_mapping/mms_mapping.c +@@ -3268,7 +3268,9 @@ mmsReadAccessHandler (void* parameter, MmsDomain* domain, char* variableId, MmsS + } + else + { +- StringUtils_createStringFromBufferInBuffer(str, (uint8_t*) variableId, separator - variableId); ++ char str[65]; ++ ++ StringUtils_createStringFromBufferInBufferMax(str, (uint8_t*) variableId, separator - variableId, sizeof(str)); + + LogicalNode* ln = LogicalDevice_getLogicalNode(ld, str); + +@@ -3286,7 +3288,7 @@ mmsReadAccessHandler (void* parameter, MmsDomain* domain, char* variableId, MmsS + else { + doEnd--; + +- StringUtils_createStringFromBufferInBuffer(str, (uint8_t*) (doStart + 1), doEnd - doStart); ++ StringUtils_createStringFromBufferInBufferMax(str, (uint8_t*) (doStart + 1), doEnd - doStart, sizeof(str)); + } + + if (fc == IEC61850_FC_SP) { +diff --git a/src/mms/iso_mms/client/mms_client_identify.c b/src/mms/iso_mms/client/mms_client_identify.c +index 831b439d..c679a423 100644 +--- a/src/mms/iso_mms/client/mms_client_identify.c ++++ b/src/mms/iso_mms/client/mms_client_identify.c +@@ -84,15 +84,15 @@ mmsClient_parseIdentifyResponse(MmsConnection self, ByteBuffer* response, uint32 + + switch (tag) { + case 0x80: /* vendorName */ +- vendorName = StringUtils_createStringFromBufferInBuffer(vendorNameBuf, buffer + bufPos, length); ++ vendorName = StringUtils_createStringFromBufferInBufferMax(vendorNameBuf, buffer + bufPos, length, sizeof(vendorNameBuf)); + bufPos += length; + break; + case 0x81: /* modelName */ +- modelName = StringUtils_createStringFromBufferInBuffer(modelNameBuf, buffer + bufPos, length); ++ modelName = StringUtils_createStringFromBufferInBufferMax(modelNameBuf, buffer + bufPos, length, sizeof(modelNameBuf)); + bufPos += length; + break; + case 0x82: /* revision */ +- revision = StringUtils_createStringFromBufferInBuffer(revisionBuf, buffer + bufPos, length); ++ revision = StringUtils_createStringFromBufferInBufferMax(revisionBuf, buffer + bufPos, length, sizeof (revisionBuf)); + bufPos += length; + break; + case 0x83: /* list of abstract syntaxes */ +diff --git a/src/mms/iso_mms/server/mms_named_variable_list_service.c b/src/mms/iso_mms/server/mms_named_variable_list_service.c +index 3365f771..757d0ed3 100644 +--- a/src/mms/iso_mms/server/mms_named_variable_list_service.c ++++ b/src/mms/iso_mms/server/mms_named_variable_list_service.c +@@ -401,13 +401,13 @@ createNamedVariableList(MmsServer server, MmsDomain* domain, MmsDevice* device, + char variableName[65]; + char domainId[65]; + +- StringUtils_createStringFromBufferInBuffer(variableName, +- varSpec->choice.name.choice.domainspecific.itemId.buf, +- varSpec->choice.name.choice.domainspecific.itemId.size); ++ StringUtils_createStringFromBufferInBufferMax(variableName, ++ varSpec->choice.name.choice.domainspecific.itemId.buf, ++ varSpec->choice.name.choice.domainspecific.itemId.size, sizeof(variableName)); + +- StringUtils_createStringFromBufferInBuffer(domainId, +- varSpec->choice.name.choice.domainspecific.domainId.buf, +- varSpec->choice.name.choice.domainspecific.domainId.size); ++ StringUtils_createStringFromBufferInBufferMax(domainId, ++ varSpec->choice.name.choice.domainspecific.domainId.buf, ++ varSpec->choice.name.choice.domainspecific.domainId.size, sizeof(domainId)); + + MmsDomain* elementDomain = MmsDevice_getDomain(device, domainId); + +@@ -494,9 +494,9 @@ mmsServer_handleDefineNamedVariableListRequest( + goto exit_free_struct; + } + +- StringUtils_createStringFromBufferInBuffer(domainName, +- request->variableListName.choice.domainspecific.domainId.buf, +- request->variableListName.choice.domainspecific.domainId.size); ++ StringUtils_createStringFromBufferInBufferMax(domainName, ++ request->variableListName.choice.domainspecific.domainId.buf, ++ request->variableListName.choice.domainspecific.domainId.size, sizeof(domainName)); + + MmsDomain* domain = MmsDevice_getDomain(device, domainName); + +@@ -517,9 +517,9 @@ mmsServer_handleDefineNamedVariableListRequest( + goto exit_free_struct; + } + +- StringUtils_createStringFromBufferInBuffer(variableListName, +- request->variableListName.choice.domainspecific.itemId.buf, +- request->variableListName.choice.domainspecific.itemId.size); ++ StringUtils_createStringFromBufferInBufferMax(variableListName, ++ request->variableListName.choice.domainspecific.itemId.buf, ++ request->variableListName.choice.domainspecific.itemId.size, sizeof(variableListName)); + + if (MmsDomain_getNamedVariableList(domain, variableListName) != NULL) { + mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_DEFINITION_OBJECT_EXISTS); +@@ -567,9 +567,9 @@ mmsServer_handleDefineNamedVariableListRequest( + goto exit_free_struct; + } + +- StringUtils_createStringFromBufferInBuffer(variableListName, +- request->variableListName.choice.aaspecific.buf, +- request->variableListName.choice.aaspecific.size); ++ StringUtils_createStringFromBufferInBufferMax(variableListName, ++ request->variableListName.choice.aaspecific.buf, ++ request->variableListName.choice.aaspecific.size, sizeof(variableListName)); + + if (MmsServerConnection_getNamedVariableList(connection, variableListName) != NULL) { + mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_DEFINITION_OBJECT_EXISTS); +@@ -611,9 +611,9 @@ mmsServer_handleDefineNamedVariableListRequest( + goto exit_free_struct; + } + +- StringUtils_createStringFromBufferInBuffer(variableListName, +- request->variableListName.choice.vmdspecific.buf, +- request->variableListName.choice.vmdspecific.size); ++ StringUtils_createStringFromBufferInBufferMax(variableListName, ++ request->variableListName.choice.vmdspecific.buf, ++ request->variableListName.choice.vmdspecific.size, sizeof(variableListName)); + + if (mmsServer_getNamedVariableListWithName(MmsDevice_getNamedVariableLists(connection->server->device), variableListName) != NULL) { + mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_DEFINITION_OBJECT_EXISTS); +@@ -757,11 +757,11 @@ mmsServer_handleGetNamedVariableListAttributesRequest( + goto exit_function; + } + +- StringUtils_createStringFromBufferInBuffer(domainName, request->choice.domainspecific.domainId.buf, +- request->choice.domainspecific.domainId.size); ++ StringUtils_createStringFromBufferInBufferMax(domainName, request->choice.domainspecific.domainId.buf, ++ request->choice.domainspecific.domainId.size, sizeof(domainName)); + +- StringUtils_createStringFromBufferInBuffer(itemName, request->choice.domainspecific.itemId.buf, +- request->choice.domainspecific.itemId.size); ++ StringUtils_createStringFromBufferInBufferMax(itemName, request->choice.domainspecific.itemId.buf, ++ request->choice.domainspecific.itemId.size, sizeof(itemName)); + + MmsDevice* mmsDevice = MmsServer_getDevice(connection->server); + +@@ -798,8 +798,8 @@ mmsServer_handleGetNamedVariableListAttributesRequest( + goto exit_function; + } + +- StringUtils_createStringFromBufferInBuffer(listName, request->choice.aaspecific.buf, +- request->choice.aaspecific.size); ++ StringUtils_createStringFromBufferInBufferMax(listName, request->choice.aaspecific.buf, ++ request->choice.aaspecific.size, sizeof(listName)); + + MmsNamedVariableList varList = MmsServerConnection_getNamedVariableList(connection, listName); + +@@ -817,8 +817,8 @@ mmsServer_handleGetNamedVariableListAttributesRequest( + goto exit_function; + } + +- StringUtils_createStringFromBufferInBuffer(listName, request->choice.vmdspecific.buf, +- request->choice.vmdspecific.size); ++ StringUtils_createStringFromBufferInBufferMax(listName, request->choice.vmdspecific.buf, ++ request->choice.vmdspecific.size, sizeof(listName)); + + MmsDevice* mmsDevice = MmsServer_getDevice(connection->server); + diff --git a/meta-networking/recipes-connectivity/libiec61850/libiec61850_1.5.3.bb b/meta-networking/recipes-connectivity/libiec61850/libiec61850_1.5.3.bb index 3fff45670f..962fca1c07 100644 --- a/meta-networking/recipes-connectivity/libiec61850/libiec61850_1.5.3.bb +++ b/meta-networking/recipes-connectivity/libiec61850/libiec61850_1.5.3.bb @@ -19,6 +19,7 @@ SRC_URI = "git://github.com/mz-automation/${BPN}.git;branch=v1.5;protocol=https file://0001-pyiec61850-don-t-break-CMAKE_INSTALL_PATH-by-trying-.patch \ file://0002-pyiec61850-Use-CMAKE_INSTALL_LIBDIR-from-GNUInstallD.patch \ file://0003-LIB61850-430-fixed-null-pointer-dereference-in-mmsSe.patch \ + file://0004-LIB61850-447-replaced-unsafe-function-StringUtils_cr.patch \ " S = "${WORKDIR}/git" -- cgit v1.2.3-54-g00ecf