ZeroPath at Black Hat USA 2026

Pacemaker CVE-2026-10649: Pre-Auth Integer Overflow in Remote Message Decompression with PoC and Patch Analysis

A brief summary of CVE-2026-10649, a pre-authentication integer overflow in Pacemaker's CIB remote listener that enables remote denial of service. Includes proof of concept details, patch breakdown, and mitigation guidance.

CVE Analysis

10 min read

ZeroPath CVE Analysis
ZeroPath CVE Analysis

2026-06-16

Pacemaker CVE-2026-10649: Pre-Auth Integer Overflow in Remote Message Decompression with PoC and Patch Analysis
Experimental AI-Generated Content

This CVE analysis is an experimental publication that is completely AI-generated. The content may contain errors or inaccuracies and is subject to change as more information becomes available. We are continuously refining our process.

If you have feedback, questions, or notice any errors, please reach out to us.

[email protected]

Introduction

A pre-authentication integer overflow in Pacemaker's CIB remote listener allows an unauthenticated attacker to crash the cluster resource manager with a single crafted network message, turning the very system responsible for ensuring high availability into a vector for unavailability. For organizations running Pacemaker on 32-bit builds with the CIB remote listener exposed, this CVSS 8.6 vulnerability (CVE-2026-10649) represents a direct path to denial of service with no credentials required.

Pacemaker is the de facto standard high availability cluster resource manager for Linux, coordinating service startup, monitoring, and recovery across cluster nodes. It ships as the default HA solution in Red Hat Enterprise Linux and SUSE Linux Enterprise, and is widely deployed in telecommunications, financial services, and data center infrastructure where cluster uptime is paramount. Its GitHub repository has approximately 1.2k stars and 358 forks, reflecting a moderately sized but active open source community.

Technical Information

Root Cause: CWE-190 Integer Overflow in Decompression Path

CVE-2026-10649 is classified under CWE-190 (Integer Overflow or Wraparound). The vulnerability exists in the function pcmk__remote_message_xml() located in lib/common/remote.c, within the code path that handles decompression of incoming remote messages.

The CIB (Cluster Information Base) remote listener accepts connections for remote cluster administration. When a compressed message arrives, the listener parses three header fields directly from the wire: payload_offset, payload_compressed, and payload_uncompressed. These attacker-controlled values are used in arithmetic expressions to calculate buffer sizes, but the vulnerable code performs no bounds or consistency checks before using them.

Here is the vulnerable code from the Bugzilla entry:

if (header->payload_compressed) { int rc = 0; unsigned int size_u = 1 + header->payload_uncompressed; char *uncompressed = pcmk__assert_alloc(1, header->payload_offset + size_u); ... rc = BZ2_bzBuffToBuffDecompress(uncompressed + header->payload_offset, &size_u, remote->buffer + header->payload_offset, header->payload_compressed, 1, 0);

The critical issue is in two expressions:

  1. size_u = 1 + header->payload_uncompressed: If payload_uncompressed is set to a value near UINT32_MAX (for example, 0xFFFFFFC0), the addition of 1 causes the result to wrap around to a very small number on 32-bit architectures.

  2. header->payload_offset + size_u: After the first wraparound, this second addition can also produce a small value, resulting in a tiny buffer allocation via pcmk__assert_alloc.

The BZ2_bzBuffToBuffDecompress call then attempts to write the full decompressed payload into this undersized buffer, causing out-of-bounds writes, memory corruption, and ultimately a crash.

Pre-Authentication Attack Surface

This is not merely a post-authentication bug. The vulnerability is triggered in the CIB remote listener before cib_remote_auth() completes. This means an attacker needs only network reachability to the CIB remote listener port; no credentials, no prior session, and no user interaction are required. The CVSS v3.1 vector reflects this: AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:H.

Attack Flow

The exploitation sequence proceeds as follows:

  1. The attacker identifies a network-reachable Pacemaker CIB remote listener (enabled via remote-port or remote-tls-port).

  2. The attacker constructs a remote message with a valid header structure but manipulated field values. Specifically, payload_uncompressed is set to a value near UINT32_MAX such that 1 + payload_uncompressed wraps to a small number. payload_offset is set to a normal value (e.g., 0x00000028). payload_compressed is set to the actual length of a small bzip2 compressed payload.

  3. The attacker sends this single crafted message to the CIB remote listener.

  4. The listener's pcmk__remote_message_xml() function processes the message before authentication. It computes a wrapped buffer size, allocates a tiny buffer, and then calls BZ2_bzBuffToBuffDecompress, which writes beyond the buffer boundary.

  5. The resulting memory corruption crashes the CIB remote listener. In a production HA cluster, this crash can trigger node fencing and cascade into service failover events or complete cluster degradation.

32-Bit Architecture Sensitivity

The Bugzilla entry specifically identifies 32-bit builds as affected. On 32-bit architectures, unsigned int is 32 bits wide, making the maximum representable value approximately 4.3 billion. Integer wraparound is achievable with relatively straightforward manipulated values. On 64-bit architectures, the arithmetic operates on larger integer ranges, making wraparound harder (though not necessarily impossible depending on type casting behavior in the specific code path).

CVSS Score Discrepancy

Red Hat's Bugzilla entry rates this vulnerability at CVSS 7.5 (HIGH), while the NVD assigned score is 8.6. Red Hat's lower score likely reflects deployment context assumptions, such as CIB remote listeners being restricted to internal networks. The NVD score assumes worst-case exposure. Organizations should evaluate which score applies based on their actual network architecture.

Proof of Concept

A procedural proof of concept for CVE-2026-10649 exists in the form of detailed packet-level reproduction steps published in Red Hat Bugzilla Bug 2462817. No standalone exploit script has been identified in public repositories (Exploit-DB, GitHub PoC repos) as of June 16, 2026. However, the Bugzilla disclosure provides precise payload construction parameters sufficient for a practitioner to reproduce the denial of service crash without further reverse engineering.

Reproduction Steps

From Bugzilla 2462817:

  1. Build and run a 32-bit pacemaker-based with ASan (or another memory sanitizer), and enable remote-port or remote-tls-port.

  2. Connect to the CIB remote listener and send one packet with the following header values:

    • payload_offset = 0x00000028
    • payload_uncompressed = 0xFFFFFFC0
    • payload_compressed = len(bz2_payload) where bz2_payload = bz2.compress(b"A"*512 + b"\x00")
    • size_total = payload_offset + payload_compressed
  3. Send the header and bz2_payload as a single remote message.

  4. Observe an out-of-bounds write or crash inside or immediately around BZ2_bzBuffToBuffDecompress() from pcmk__remote_message_xml() before authentication completes.

The advisory notes that payload_uncompressed = UINT32_MAX alone is not the optimal trigger; values near UINT32_MAX that make the expression payload_offset + (1 + payload_uncompressed) wrap are more reliable.

Key Observation

The attack requires only a single network packet sent before any authentication exchange. The crafted header values cause the integer wraparound, and the bzip2 payload provides the data that overwrites the undersized buffer. The simplicity of the trigger, combined with the pre-authentication attack surface, makes this vulnerability straightforward to exploit for anyone with the Bugzilla details.

Patch Information

The upstream fix was delivered via PR #4128 in the ClusterLabs/pacemaker GitHub repository, authored by Chris Lumens (Red Hat). The PR was merged into the main branch on June 16, 2026, targeting the upcoming Pacemaker 3.0.3 release. The fix spans 5 commits totaling 96 additions and 12 deletions across 3 files, primarily concentrated in lib/common/remote.c and include/crm/common/remote_internal.h.

Layer 1: Fixing Header Validation (commit 8e667ef)

The previous size_total validation in localized_remote_header() naively added payload_offset + payload_compressed + payload_uncompressed, which was incorrect because in the compressed case both payload_compressed and payload_uncompressed are non-zero. The fix separates the logic: if the payload is compressed, expected size is payload_offset + payload_compressed; otherwise payload_offset + payload_uncompressed. Each addition is now preceded by an overflow guard:

if (header->payload_compressed > (SIZE_MAX - header->payload_offset)) { pcmk__err("Header compressed size %" PRIu32 " is too large", header->payload_compressed); return NULL; }

Layer 2: Core Integer Overflow Fix (commit 1e1825b)

This commit directly addresses the CVE. The vulnerable code previously performed:

// BEFORE (vulnerable) unsigned int size_u = 1 + header->payload_uncompressed; char *uncompressed = pcmk__assert_alloc(header->payload_offset + size_u, sizeof(char));

The fix introduces multiple guard checks before any allocation:

// AFTER (fixed) #if (UINT_MAX >= SIZE_MAX) if ((size_u >= SIZE_MAX) || (header->payload_offset > (SIZE_MAX - size_u))) { #else if (header->payload_offset > (SIZE_MAX - size_u)) { #endif pcmk__err("Couldn't decompress message because the required buffer " "size (%" PRIu32 " + %u) is greater than SIZE_MAX (%zu)", header->payload_offset, size_u, SIZE_MAX); return NULL; }

Only after these checks pass does the code proceed to allocate the buffer and call BZ2_bzBuffToBuffDecompress.

Layer 3: Maximum Message Size (commit bb37829)

As a defense in depth measure, the patch introduces a hard-coded maximum message size:

#define PCMK__REMOTE_MSG_MAX_SIZE (20 * 1024 * 1024) // 20 MB

This 20 MB limit is enforced in the decompression path and in pcmk__read_available_remote_data(). Previously, a malicious client could request up to 4 GB of memory via the uint32_t size_total field. Messages exceeding this limit are now rejected with EINVAL before any allocation occurs.

Layer 4: Send-Side Overflow Fix (commit 6dd7ce8)

A related integer overflow on the send side in pcmk__remote_send_xml() is also fixed. Two size_t I/O vector lengths were previously added and stored into a uint32_t header field without a bounds check. The fix ensures the combined length fits within uint32_t before setting it.

Distribution Status

All RHEL versions 6 through 10 and RHCOS (OpenShift Container Platform 4) are listed as affected. No distribution errata had been released as of the publication date. Organizations building from source should apply PR #4128 directly.

Affected Systems and Versions

Based on the available advisories and Bugzilla entry:

  • Pacemaker version pacemaker-3.0.1-5.el10 on 32-bit builds with the CIB remote listener enabled is explicitly identified as affected.
  • All RHEL versions 6 through 10 and RHCOS (OpenShift Container Platform 4) are listed as affected in the Red Hat advisory.
  • The vulnerability specifically requires the CIB remote listener to be enabled (via remote-port or remote-tls-port configuration).
  • 32-bit builds are most at risk because integer wraparound is more readily achieved with 32-bit arithmetic. The status of 64-bit builds as fully immune versus merely harder to exploit has not been definitively confirmed in the available sources.
  • The upstream fix targets Pacemaker 3.0.3.

Vendor Security History

The ClusterLabs ecosystem has accumulated 27 documented CVEs over its history. Several of these are notable for their severity and the patterns they reveal:

CVECVSSDescription
CVE-2023-399769.8 CriticalBuffer overflow in libqb before 2.0.8 via long log messages
CVE-2020-354589.8 CriticalShell code injection in ClusterLabs Hawk via hawk_remember_me_id
CVE-2023-23199.8 CriticalPCS package failed to include Webpack fix CVE-2023-28154
CVE-2022-10498.8 Highpcs daemon allowed expired accounts/passwords to login via PAM
CVE-2021-30208.8 HighHawk allowed hacluster user to execute interactive shell, escalate to root
CVE-2020-256547.2 HighACL bypass in Pacemaker via IPC by local haclient group members
CVE-2022-27357.8 HighIncorrect Unix socket permissions in PCS allowed privilege escalation
CVE-2022-25536.5 MediumBooth authfile directive ignored, allowing unauthenticated node communication

This history reveals a recurring pattern of authentication bypass, privilege escalation, and input validation weaknesses across the ClusterLabs stack. CVE-2026-10649 continues this trajectory: insufficient input validation on untrusted network data leading to a pre-authentication denial of service. The ecosystem's security posture has historically relied on the assumption that cluster communication occurs on trusted networks, an assumption that pre-authentication vulnerabilities like this one directly violate.

References

Detect & fix
what others miss

Works with
  • GitHub
  • GitLab
  • Bitbucket
  • Azure DevOps Services
  • Jira
  • Linear
  • Slack
  • Security Compass
Security magnifying glass visualization