oss-sec mailing list archives
libIEC61850: four MMS/GOOSE memory-safety vulnerabilities, including lab RCE
From: Abhinav Agarwal <abhinavagarwal1996 () gmail com>
Date: Thu, 23 Jul 2026 22:08:30 -0700
Hello,
libIEC61850 (MZ Automation), the widely used open-source IEC 61850 stack
for electric-substation MMS and GOOSE, contains four memory-safety
vulnerabilities in its MMS and GOOSE handling: CVE-2026-49035,
CVE-2026-50039, CVE-2026-50032, and CVE-2026-50103. All are fixed in
v1.6.2. In the tested default configurations, the triggering requests or
frames require no application credentials. The issues cause denial of
service under the deployment conditions described below; CVE-2026-49035
additionally produced command execution in a deliberately unhardened
laboratory build.
Affected range: v1.0.0 through v1.6.1. I reproduced all four
issues against commit a1396111, the v1.6.1 tip used for testing.
Coordinated through CISA (advisory ICSA-26-204-06).
The MMS PoCs require no application credentials against the tested
default server configuration; the GOOSE issue is triggered by a single
crafted Layer-2 frame. Applications may separately configure
authentication, TLS, access-control callbacks, or network restrictions.
Remediation: upgrade to v1.6.2, or backport the four referenced fixes.
Deployments that cannot update should restrict MMS reachability, disable
or restrict unnecessary MMS file services, and reject untrusted GOOSE
traffic at the network boundary where operationally possible.
CWE ids and CVSS v3.1 scores/vectors below are the published CISA
advisory values.
CVE Component Class CWE CVSS 3.1
-------------- ----------------- -------------- ---- --------
CVE-2026-49035 MMS file service Heap overflow 122 8.1
CVE-2026-50039 MMS value cache Stack overflow 121 7.5
CVE-2026-50032 MMS write service NULL deref 476 7.5
CVE-2026-50103 GOOSE subscriber Invalid struct 228 6.5
CVE-2026-49035 -- MMS FileRead heap overflow -> RCE (lab)
mms_file_service.c / mms_association_service.c
The server accepts a client-supplied maxPduSize during MMS Initiate
with no lower bound. maxFileChunkSize = maxPduSize - 20 underflows to
a near-maximal uint32_t when maxPduSize < 20 -- an
integer-underflow root cause (CWE-191) underlying the heap overflow --
bypassing the chunk-size guard, so a FileRead response copies an
entire staged file into a fixed 65,100-byte heap buffer. In the
default build profile ObtainFile is compiled in alongside the MMS file
service, allowing a sufficiently large file to be staged remotely when
the application has not disabled or restricted that functionality; the
file is then read back to trigger the overflow. With the file service
reachable and a sufficiently large file available or staged through
ObtainFile, the overflow reliably crashes the server.
In a deliberately unhardened lab build (AArch64, non-PIE, ASLR off,
writable GOT) I reproduced the full chain -- a free@GOT overwrite
reaching system(), end-to-end command execution -- verified by an
strace execve capture and a nonce-stamped proof file. In the tested
environment, enabling PIE and ASLR would require an additional
address-disclosure or equivalent exploit primitive; I did not
demonstrate such a primitive.
Fix status: v1.6.2, commit db35acf6.
CVSS 3.1: 8.1 (CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H)
CVE-2026-50039 -- MMS value-cache stack buffer overflow
mms_value_cache.c
MmsValueCache_lookupValue copies the looked-up item identifier into a
fixed char itemIdCopy[65] with an unbounded copy
(StringUtils_copyStringToBuffer, no destination size). An
unauthenticated ReadRequest overflows the stack buffer when the server
model exposes an object whose item identifier exceeds 64 bytes (ASAN:
stack WRITE of size 87 on an 86-char path; a canary build aborts via
__stack_chk_fail). Deployment-conditional on such a model; the copy is
unsafe regardless.
Fix status: v1.6.2, commit a0bd0aaa
CVSS 3.1: 7.5 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)
CVE-2026-50032 -- MMS Write NULL-pointer dereference
mms_write_service.c
A WriteRequest naming an existing Named Variable List with an empty
listOfData (A0 00, accepted by the decoder) sets the data array to
NULL, which the write loop dereferences. This path iterates on the
server-side member count without checking the client's listOfData
count; the sibling listOfVariable path has that guard, this one does
not. Unauthenticated single-request crash against the tested default
(no access control).
Fix status: v1.6.2, commit bd338f23.
CVSS 3.1: 7.5 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)
CVE-2026-50103 -- GOOSE parser supplies NULL dataset element to callback
goose_receiver.c
The two-pass TLV parser (parseAllDataUnknownValue) allocates a dataset
slot in pass 1 but leaves it NULL in pass 2 when a recognized type
carries an invalid length: 0x87/Float (valid 5, 9), 0x8c/BinaryTime
(valid 4, 6), 0x91/UTCTime (valid 8). The NULL element reaches the
subscriber callback; a callback that reads it with ordinary MmsValue
accessors -- the pattern in the library's own examples and the PoC --
calls MmsValue_getType(NULL) and crashes. One malformed Layer-2 GOOSE
frame, delivered on the local segment, is enough.
The same function backs the optional beta R-GOOSE (UDP) path, disabled
by default (CONFIG_IEC61850_R_GOOSE 0); identified by source review,
not tested.
Fix status: v1.6.2, commit 62f22887.
CVSS 3.1: 6.5 (CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)
Affected:
libIEC61850 v1.0.0 through v1.6.1 (all four). Fixed in v1.6.2.
Note:
Beyond these four, v1.6.2 also ships several other security-related
fixes (see the release notes and CHANGELOG); those do not appear to
carry separate CVE assignments.
Timeline:
2026-05-07 Reported four issues to the maintainer.
2026-05-08 All four fixed on the public v1.6_develop branch.
2026-06-09 CVEs reserved.
2026-07-03 Notified CISA and the vendor of intent to publish PoC
code after the CISA advisory is published.
2026-07-23 v1.6.2 released; CISA advisory ICSA-26-204-06 published;
writeup and PoC published; this disclosure.
PoCs (per-CVE crash harnesses + the Dockerized end-to-end RCE, with
ASAN/GDB logs, pcaps, patch diffs, and negative controls) and the full
write-up -- root cause, exploit chain, and timeline -- are linked below.
References:
Write-up: https://abhinavagarwal07.github.io/posts/libiec61850-mms-goose-cves?src=oss
PoC code: https://github.com/abhinavagarwal07/libiec-security-poc
CISA Advisory: https://www.cisa.gov/news-events/ics-advisories/icsa-26-204-06
Vendor Release:
https://github.com/mz-automation/libiec61850/releases/tag/v1.6.2
Reported and coordinated by Abhinav Agarwal.
-- Abhinav Agarwal
Current thread:
- libIEC61850: four MMS/GOOSE memory-safety vulnerabilities, including lab RCE Abhinav Agarwal (Jul 24)
