new file mode 100644
@@ -0,0 +1,218 @@
+From b9bebc0d74998195422d104e4d430e2511d6c40f Mon Sep 17 00:00:00 2001
+From: Michael Zillgith <michael.zillgith@mz-automation.de>
+Date: Mon, 22 Jul 2024 16:34:03 +0100
+Subject: [PATCH] CVE-2024-45971
+
+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 <ankur.tyagi85@gmail.com>
+---
+ 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);
+
@@ -20,6 +20,7 @@ SRC_URI = "git://github.com/mz-automation/${BPN}.git;branch=v1.5;protocol=https
file://0001-pyiec61850-Use-CMAKE_INSTALL_LIBDIR-from-GNUInstallD.patch \
file://CVE-2024-26529.patch \
file://CVE-2024-45970.patch \
+ file://CVE-2024-45971.patch \
"
S = "${WORKDIR}/git"
Details https://nvd.nist.gov/vuln/detail/CVE-2024-45971 Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com> --- .../libiec61850/files/CVE-2024-45971.patch | 218 ++++++++++++++++++ .../libiec61850/libiec61850_1.5.3.bb | 1 + 2 files changed, 219 insertions(+) create mode 100644 meta-networking/recipes-connectivity/libiec61850/files/CVE-2024-45971.patch