diff mbox series

[meta-networking,wrynose,18/22] libiec61850: patch CVE-2026-19108

Message ID 20260903094954.3240723-18-ankur.tyagi85@gmail.com
State New
Headers show
Series [meta-oe,wrynose,1/22] jq: ignore CVE-2025-49014 | expand

Commit Message

Ankur Tyagi Sept. 3, 2026, 9:49 a.m. UTC
From: Ankur Tyagi <ankur.tyagi85@gmail.com>

Details:
https://nvd.nist.gov/vuln/detail/cve-2026-19108

Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
---
 .../libiec61850/files/CVE-2026-19108.patch    | 208 ++++++++++++++++++
 .../libiec61850/libiec61850_1.6.1.bb          |   1 +
 2 files changed, 209 insertions(+)
 create mode 100644 meta-networking/recipes-connectivity/libiec61850/files/CVE-2026-19108.patch
diff mbox series

Patch

diff --git a/meta-networking/recipes-connectivity/libiec61850/files/CVE-2026-19108.patch b/meta-networking/recipes-connectivity/libiec61850/files/CVE-2026-19108.patch
new file mode 100644
index 0000000000..673ce29af0
--- /dev/null
+++ b/meta-networking/recipes-connectivity/libiec61850/files/CVE-2026-19108.patch
@@ -0,0 +1,208 @@ 
+From 846bd407527061665a3c109eaa6ee7e870ae6bc1 Mon Sep 17 00:00:00 2001
+From: Michael Zillgith <michael.zillgith@mz-automation.de>
+Date: Tue, 21 Jul 2026 10:26:33 +0000
+Subject: [PATCH] - MMS server: fixed - Update URCB that used an association
+ specific dataset of another connection can cause heap-use-after-free
+ (LIB61850-577)(#596) - fixed bitbucket sonarcloud pipeline
+
+(cherry picked from commit 486fd57f3aed65bb9d636ff00f9ddce2e450b168)
+
+CVE: CVE-2026-19108
+Upstream-Status: Backport [https://github.com/mz-automation/libiec61850/commit/486fd57f3aed65bb9d636ff00f9ddce2e450b168]
+
+Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
+---
+ bitbucket-pipelines.yml                       | 11 +++----
+ src/iec61850/inc_private/reporting.h          |  1 +
+ src/iec61850/server/mms_mapping/mms_mapping.c | 29 +++++++++++++++++--
+ src/iec61850/server/mms_mapping/reporting.c   | 17 +++++++----
+ .../iso_mms/server/mms_server_connection.c    | 19 ++++++++++++
+ 5 files changed, 65 insertions(+), 12 deletions(-)
+
+diff --git a/bitbucket-pipelines.yml b/bitbucket-pipelines.yml
+index a7493663..30dce281 100644
+--- a/bitbucket-pipelines.yml
++++ b/bitbucket-pipelines.yml
+@@ -1,4 +1,4 @@
+-image:  atlassian/default-image:4
++image:  atlassian/default-image:5
+ 
+ clone:
+   depth: full              # SonarCloud scanner needs the full history to assign issues properly
+@@ -12,12 +12,13 @@ definitions:
+         caches:
+           - sonar
+         script:
+-          - export SONAR_SCANNER_VERSION=5.0.1.3006
+-          - export SONAR_SCANNER_OPTS="-Dsonar.javaHome=/usr/lib/jvm/java-17-openjdk-amd64"
+-          - export SONAR_SCANNER_HOME=$HOME/.sonar/sonar-scanner-$SONAR_SCANNER_VERSION-linux
++          - export SONAR_SCANNER_VERSION=6.2.1.4610
++          - export SONAR_SCANNER_HOME=$HOME/.sonar/sonar-scanner-$SONAR_SCANNER_VERSION-linux-x64
+           - export BW_OUTPUT=$HOME/.sonar/bw-output
+           - mkdir -p $BW_OUTPUT
+-          - curl --create-dirs -sSLo $HOME/.sonar/sonar-scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$SONAR_SCANNER_VERSION-linux.zip
++          - apt-get update -qq
++          - apt-get install openjdk-21-jre cmake -y
++          - curl --create-dirs -sSLo $HOME/.sonar/sonar-scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$SONAR_SCANNER_VERSION-linux-x64.zip
+           - unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/
+           - export PATH=$SONAR_SCANNER_HOME/bin:$PATH
+           - curl --create-dirs -sSLo $HOME/.sonar/build-wrapper-linux-x86.zip https://sonarcloud.io/static/cpp/build-wrapper-linux-x86.zip
+diff --git a/src/iec61850/inc_private/reporting.h b/src/iec61850/inc_private/reporting.h
+index eddeb2d1..bc23f937 100644
+--- a/src/iec61850/inc_private/reporting.h
++++ b/src/iec61850/inc_private/reporting.h
+@@ -67,6 +67,7 @@ typedef struct {
+     bool buffered; /* true if report is a buffered report */
+ 
+     MmsValue** bufferedDataSetValues; /* used to buffer values during bufTm time */
++    int bufferedDataSetValuesSize; /* number of dataset entries */
+ 
+     MmsValue** valueReferences; /* array to store value references for fast access */
+ 
+diff --git a/src/iec61850/server/mms_mapping/mms_mapping.c b/src/iec61850/server/mms_mapping/mms_mapping.c
+index 5620f63f..ef6f3580 100644
+--- a/src/iec61850/server/mms_mapping/mms_mapping.c
++++ b/src/iec61850/server/mms_mapping/mms_mapping.c
+@@ -3912,6 +3912,10 @@ variableListAccessHandler (void* parameter, MmsVariableListAccessType accessType
+             {
+                 ReportControl* rc = (ReportControl*) rcElement->data;
+ 
++#if (CONFIG_MMS_THREADLESS_STACK != 1)
++                Semaphore_wait(rc->rcbValuesLock);
++#endif
++
+                 if (rc->isDynamicDataSet)
+                 {
+                     if (rc->dataSet != NULL)
+@@ -3924,6 +3928,11 @@ variableListAccessHandler (void* parameter, MmsVariableListAccessType accessType
+                                 {
+                                     if (strcmp(rc->dataSet->logicalDeviceName, MmsDomain_getName(domain) + strlen(self->model->name)) == 0)
+                                     {
++#if (CONFIG_MMS_THREADLESS_STACK != 1)
++                                        Semaphore_post(rc->rcbValuesLock);
++#endif
++
++                                        /* dataset is in use and cannot be deleted */
+                                         allow = MMS_ERROR_SERVICE_OBJECT_CONSTRAINT_CONFLICT;
+                                         break;
+                                     }
+@@ -3936,6 +3945,10 @@ variableListAccessHandler (void* parameter, MmsVariableListAccessType accessType
+                             {
+                                 if (strcmp(rc->dataSet->name, listName) == 0)
+                                 {
++#if (CONFIG_MMS_THREADLESS_STACK != 1)
++                                    Semaphore_post(rc->rcbValuesLock);
++#endif
++                                    /* dataset is in use and cannot be deleted */
+                                     allow = MMS_ERROR_SERVICE_OBJECT_CONSTRAINT_CONFLICT;
+                                     break;
+                                 }
+@@ -3947,13 +3960,22 @@ variableListAccessHandler (void* parameter, MmsVariableListAccessType accessType
+                             {
+                                 if (strcmp(rc->dataSet->name, listName) == 0)
+                                 {
+-                                    allow = MMS_ERROR_SERVICE_OBJECT_CONSTRAINT_CONFLICT;
+-                                    break;
++                                    /* this is usually called when the connection is closed -> RCB has already been disabled by connection handler */
++
++                                    MmsMapping_freeDynamicallyCreatedDataSet(rc->dataSet);
++
++                                    /* cleanup dataset information in RCB instance */
++                                    rc->dataSet = NULL;
++                                    rc->isDynamicDataSet = false;
+                                 }
+                             }
+                         }
+                     }
+                 }
++
++#if (CONFIG_MMS_THREADLESS_STACK != 1)
++                Semaphore_post(rc->rcbValuesLock);
++#endif
+             }
+ 
+ #if (CONFIG_IEC61850_LOG_SERVICE == 1)
+@@ -4729,6 +4751,9 @@ MmsMapping_getDomainSpecificDataSet(MmsMapping* self, const char* dataSetName)
+ void
+ MmsMapping_freeDynamicallyCreatedDataSet(DataSet* dataSet)
+ {
++    if (dataSet == NULL)
++        return;
++
+     DataSetEntry* dataSetEntry = dataSet->fcdas;
+ 
+     while (dataSetEntry)
+diff --git a/src/iec61850/server/mms_mapping/reporting.c b/src/iec61850/server/mms_mapping/reporting.c
+index a44f0583..03add555 100644
+--- a/src/iec61850/server/mms_mapping/reporting.c
++++ b/src/iec61850/server/mms_mapping/reporting.c
+@@ -193,13 +193,9 @@ deleteDataSetValuesShadowBuffer(ReportControl* self)
+ {
+     if (self->bufferedDataSetValues != NULL)
+     {
+-        assert(self->dataSet != NULL);
+-
+-        int dataSetSize = DataSet_getSize(self->dataSet);
+-
+         int i;
+ 
+-        for (i = 0; i < dataSetSize; i++)
++        for (i = 0; i < self->bufferedDataSetValuesSize; i++)
+         {
+             if (self->bufferedDataSetValues[i] != NULL)
+                 MmsValue_delete(self->bufferedDataSetValues[i]);
+@@ -698,13 +694,24 @@ static void
+ createDataSetValuesShadowBuffer(ReportControl* rc)
+ {
+     int dataSetSize = DataSet_getSize(rc->dataSet);
++    rc->bufferedDataSetValuesSize = dataSetSize;
+ 
+     MmsValue** dataSetValues = (MmsValue**)GLOBAL_CALLOC(dataSetSize, sizeof(MmsValue*));
+ 
++    if (dataSetValues == NULL)
++        return;
++
+     rc->bufferedDataSetValues = dataSetValues;
+ 
+     rc->valueReferences = (MmsValue**)GLOBAL_MALLOC(dataSetSize * sizeof(MmsValue*));
+ 
++    if (rc->valueReferences == NULL)
++    {
++        GLOBAL_FREEMEM(dataSetValues);
++        rc->bufferedDataSetValues = NULL;
++        return;
++    }
++
+     DataSetEntry* dataSetEntry = rc->dataSet->fcdas;
+ 
+     int i;
+diff --git a/src/mms/iso_mms/server/mms_server_connection.c b/src/mms/iso_mms/server/mms_server_connection.c
+index 644fcdb1..401ad40b 100644
+--- a/src/mms/iso_mms/server/mms_server_connection.c
++++ b/src/mms/iso_mms/server/mms_server_connection.c
+@@ -829,6 +829,25 @@ MmsServerConnection_destroy(MmsServerConnection self)
+ #endif
+ 
+ #if (MMS_DYNAMIC_DATA_SETS == 1)
++    /* notify IEC 61850 layer BEFORE destroying named variable lists */
++    if (self->namedVariableLists)
++    {
++        LinkedList element = LinkedList_getNext(self->namedVariableLists);
++
++        while (element)
++        {
++            MmsNamedVariableList variableList = (MmsNamedVariableList)element->data;
++
++            if (variableList && variableList->name)
++            {
++                mmsServer_callVariableListChangedHandler(MMS_VARLIST_DELETE, MMS_ASSOCIATION_SPECIFIC,
++                                                            NULL, /* domain (NULL for aa-specific) */
++                                                            variableList->name, self);
++            }
++            element = LinkedList_getNext(element);
++        }
++    }
++
+     LinkedList_destroyDeep(self->namedVariableLists, (LinkedListValueDeleteFunction) MmsNamedVariableList_destroy);
+ #endif
+ 
diff --git a/meta-networking/recipes-connectivity/libiec61850/libiec61850_1.6.1.bb b/meta-networking/recipes-connectivity/libiec61850/libiec61850_1.6.1.bb
index 408b4d2d11..c0e6efedd6 100644
--- a/meta-networking/recipes-connectivity/libiec61850/libiec61850_1.6.1.bb
+++ b/meta-networking/recipes-connectivity/libiec61850/libiec61850_1.6.1.bb
@@ -19,6 +19,7 @@  SRC_URI = "git://github.com/mz-automation/${BPN}.git;branch=v1.6;protocol=https;
            file://0001-pyiec61850-Use-CMAKE_INSTALL_LIBDIR-from-GNUInstallD.patch \
            file://CVE-2026-18582.patch \
            file://CVE-2026-18583.patch \
+           file://CVE-2026-19108.patch \
 "