new file mode 100644
@@ -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
+
@@ -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 \
"