提出 #844921: MZ Automation GmbH libiec61850 1.6.1 Out-of-bounds Read情報

タイトルMZ Automation GmbH libiec61850 1.6.1 Out-of-bounds Read
説明libiec61850 version 1.6.1 contains a server-side memory safety vulnerability in the code path used for association-specific dynamic data set creation. The issue is reachable through normal MMS protocol processing when a server instance enables dynamic data set service and installs a data set access handler. Under those conditions, a remote client can complete a standard ISO-on-TCP / COTP / ACSE / MMS session setup and then send a crafted DefineNamedVariableList request for an association-specific named variable list. Processing of that request eventually reaches the internal function checkDataSetAccess in src/iec61850/server/mms_mapping/mms_mapping.c. In the association-specific branch, the code attempts to construct a data set reference string of the form "@<listName>" inside a local stack buffer named dataSetRef. However, the helper function StringUtils_copyStringToBuffer is invoked with reversed arguments: StringUtils_copyStringToBuffer(dataSetRef + 1, listName). This call is incorrect because the helper prototype expects the first parameter to be the source string and the second parameter to be the destination buffer. As implemented in src/common/string_utilities.c, the helper first performs strlen on the first argument and then uses memcpy to copy the resulting string into the second argument. Because of the reversed call, the function interprets the uninitialized stack region dataSetRef + 1 as a C string source and treats listName as the destination buffer. This argument inversion is the root cause of the vulnerability. At the beginning of checkDataSetAccess, the stack buffer dataSetRef is defined with a fixed length of 130 bytes and only the first byte is initialized in the association-specific case by assigning '@' to dataSetRef[0]. The remaining bytes in dataSetRef are not initialized before dataSetRef + 1 is passed to StringUtils_copyStringToBuffer as the supposed source string. The helper then executes strlen on that uninitialized region. Since strlen searches for a terminating NUL byte without any awareness of the actual size of the local stack object, the scan may continue beyond the bounds of dataSetRef if no early zero byte is encountered. In sanitizer-enabled builds this behavior is reported as a stack-buffer-overflow read originating in strlen. After the length is computed, the helper performs memcpy into listName, meaning that data derived from the uninitialized or out-of-bounds stack read is written back into the caller-provided name buffer. In other words, the defect is not limited to an uninitialized read warning: it combines out-of-bounds stack read behavior with corruption of the caller-side stack buffer used to store the requested list name. The affected request path is part of the real server implementation and is not an artificial fuzzing harness artifact. The reproduced execution flow follows the normal stack from MmsServerConnection_parseMessage to handleConfirmedRequestPdu, then to mmsServer_handleDefineNamedVariableListRequest in src/mms/iso_mms/server/mms_named_variable_list_service.c, followed by mmsServer_callVariableListChangedHandler, variableListAccessHandler, and finally checkDataSetAccess. The caller-side buffer that is passed as listName originates from variableListName[65] inside mmsServer_handleDefineNamedVariableListRequest, which means that the incorrect memcpy destination is itself a stack object created in the higher-level MMS request handling frame. This is important for understanding impact and exploitability: the vulnerability is triggered by a legitimate protocol request, traverses production code used for access control and data set management, and directly affects stack memory within the server process. The issue can be reproduced against the official example program examples/server_example_access_control/server_example_access_control.c without modifying library internals. That example is particularly relevant because it explicitly enables dynamic data set service and registers a data set access callback, which is sufficient to expose the vulnerable path. In a verified reproduction, the server was built with clang, AddressSanitizer, and UndefinedBehaviorSanitizer enabled, using a build configuration that also applied automatic stack variable pattern initialization in order to make the defect easier to observe. A minimal client written in Python then established a TCP connection to the server, sent a COTP Connection Request, followed by an ACSE/MMS initiate request, and finally submitted an association-specific DefineNamedVariableList request with the temporary list name "boom" and a member reference such as simpleIOGenericIO/GGIO1$CF$Mod. After receiving this third request, the server aborted with an AddressSanitizer report indicating a stack-buffer-overflow read of size 193 in strlen. The call stack resolved to StringUtils_copyStringToBuffer at src/common/string_utilities.c:62, checkDataSetAccess at src/iec61850/server/mms_mapping/mms_mapping.c:3810, variableListAccessHandler at line 3868 in the same file, mmsServer_callVariableListChangedHandler at src/mms/iso_mms/server/mms_named_variable_list_service.c:176, and mmsServer_handleDefineNamedVariableListRequest at line 742. AddressSanitizer also identified the overflowing object as dataSetRef within the stack frame of checkDataSetAccess, with the access occurring exactly beyond that variable’s valid extent. On the client side, the observable behavior was a closed TCP connection and a "recv 0 bytes" result, indicating that the server process terminated before a valid MMS response could be generated. From a security perspective, the confirmed impact is a remotely reachable denial of service against affected server configurations. An unauthenticated network client can reach the vulnerable code path by sending a syntactically valid MMS request sequence over the standard protocol stack, provided that the target server exposes the relevant feature set. The evidence currently supports a reliable crash scenario: the out-of-bounds read is deterministic enough under sanitizer-backed reproduction to abort the process before the operation completes. In addition, the semantics of the incorrect copy call mean that caller memory is overwritten with bytes derived from the invalid read source. Debug-level observation indicates that listName no longer retains its original expected value by the time the callback path continues, which is consistent with stack corruption of the caller-owned buffer. Nevertheless, the most defensible characterization, based strictly on currently demonstrated runtime evidence, is remote out-of-bounds stack read with resultant server crash and associated corruption of the caller-side stack name buffer. This makes the vulnerability materially more serious than a benign use of uninitialized memory, because it affects control flow stability and causes service termination through a network-reachable request path. The vulnerability should not be classified as merely an example bug. The example program only provides a convenient and fully public configuration that enables the underlying library logic. The defect resides inside libiec61850’s core server mapping implementation. Specifically, the intended association-specific behavior is to prepend '@' and then copy the client-supplied list name into the internal stack buffer. The actual code does the opposite due to incorrect argument ordering. The logic therefore fails at the abstraction boundary between application-level MMS request handling and internal string construction for data set access decisions. A minimal corrective change would swap the parameters so that listName is used as the source and dataSetRef + 1 is used as the destination. However, from a defensive programming standpoint, a complete fix should go beyond simply correcting argument order. The affected code should also use a size-aware copy primitive or an explicit bounds check against the remaining capacity of dataSetRef, rather than relying on a helper that computes length with strlen and performs a blind memcpy. Even when the argument order is corrected, clear length validation would make the function more robust and easier to audit for future regressions. At the time of analysis, the same incorrect call remained visible not only in the v1.6.1 release tree but also in the current public master branch, which suggests that the defect is still present in the publicly accessible code line and is not merely an already-fixed historical issue. A review of publicly visible repository issues identified other MMS or memory-related defects, such as a null pointer dereference in delete named variable list handling and unrelated client-side crashes, but no prior public report matching this specific root cause, trigger condition, and code path was found. Therefore, based on public evidence, this appears to be a distinct server-side vulnerability in the association-specific dynamic data set creation logic.
ソース⚠️ https://github.com/gff-cw/information/issues/3
ユーザー
 Carnegie (UID 98671)
送信2026年06月01日 15:49 (2 月 ago)
モデレーション2026年08月02日 21:14 (2 months later)
ステータス承諾済み
VulDBエントリ385412 [mz-automation libiec61850 迄 1.6.1 MMS Request mms_mapping.c checkDataSetAccess 情報漏えい]
ポイント20

Want to stay up to date on a daily basis?

Enable the mail alert feature now!