public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/pacemaker] rawhide: * Wed Jun 17 2026 Klaus Wenninger <klaus.wenninger@aon.at> - 3.0.2-2
@ 2026-06-17 20:44 Klaus Wenninger
0 siblings, 0 replies; only message in thread
From: Klaus Wenninger @ 2026-06-17 20:44 UTC (permalink / raw)
To: git-commits
A new commit has been pushed.
Repo : rpms/pacemaker
Branch : rawhide
Commit : fc9ed09880fce492139b2245fe4db87f96451f16
Author : Klaus Wenninger <klaus.wenninger@aon.at>
Date : 2026-06-17T15:59:20+02:00
Stats : +356/-1 in 6 file(s)
URL : https://src.fedoraproject.org/rpms/pacemaker/c/fc9ed09880fce492139b2245fe4db87f96451f16?branch=rawhide
Log:
* Wed Jun 17 2026 Klaus Wenninger <klaus.wenninger@aon.at> - 3.0.2-2
- fix CVE-2026-10649: Fix integer overflows in remote message code
---
diff --git a/0001-Med-libcrmcommon-Fix-checks-in-localized_remote_head.patch b/0001-Med-libcrmcommon-Fix-checks-in-localized_remote_head.patch
new file mode 100644
index 0000000..72d1479
--- /dev/null
+++ b/0001-Med-libcrmcommon-Fix-checks-in-localized_remote_head.patch
@@ -0,0 +1,89 @@
+From 8e667ef87ac4bc66ab8c64599334b521655925f7 Mon Sep 17 00:00:00 2001
+From: Chris Lumens <clumens@redhat.com>
+Date: Thu, 14 May 2026 12:57:17 -0400
+Subject: [PATCH 1/5] Med: libcrmcommon: Fix checks in localized_remote_header.
+
+The size_total check is incorrect. The expectation here is that it will
+be equal to the size of the amount of data that was received over the
+network - that is, the size of the header plus the size of the payload.
+If the payload is compressed, we need that size.
+
+Previously, there was an unwritten assumption in this check that one of
+payload_compressed or payload_uncompressed would be 0, but that's not
+true in the compressed case. If the payload is compressed,
+payload_uncompressed is still set because we need to know how big of a
+buffer to allocate to decompress the payload.
+
+Additionally, improve the error messages and prevent an integer overflow
+when adding these sizes together before comparing.
+
+These checks haven't failed in the past because nothing is using the
+compressed payload code.
+---
+ lib/common/remote.c | 34 ++++++++++++++++++++++++++++++----
+ 1 file changed, 30 insertions(+), 4 deletions(-)
+
+diff --git a/lib/common/remote.c b/lib/common/remote.c
+index a9ce088f3f..f428c4ceda 100644
+--- a/lib/common/remote.c
++++ b/lib/common/remote.c
+@@ -24,7 +24,7 @@
+ #include <netdb.h>
+ #include <stdlib.h>
+ #include <errno.h>
+-#include <inttypes.h> // PRIx32
++#include <inttypes.h> // PRIu32, PRIx32
+
+ #include <glib.h>
+ #include <bzlib.h>
+@@ -66,6 +66,7 @@ static struct remote_header_v0 *
+ localized_remote_header(pcmk__remote_t *remote)
+ {
+ struct remote_header_v0 *header = NULL;
++ size_t expected_size = 0;
+
+ if ((remote == NULL) || (remote->buffer == NULL)
+ || (remote->buffer_offset < sizeof(struct remote_header_v0))) {
+@@ -100,11 +101,36 @@ localized_remote_header(pcmk__remote_t *remote)
+
+ // Sanity checks
+ if (header->payload_offset != sizeof(struct remote_header_v0)) {
++ pcmk__err("Header payload offset %" PRIu32 " does not have expected "
++ "size %zu", header->payload_offset,
++ sizeof(struct remote_header_v0));
+ return NULL;
+ }
+- if ((header->payload_offset
+- + header->payload_compressed
+- + header->payload_uncompressed) != header->size_total) {
++
++ if (header->payload_compressed != 0) {
++ if (header->payload_compressed > (SIZE_MAX - header->payload_offset)) {
++ pcmk__err("Header compressed size %" PRIu32 " is too large",
++ header->payload_compressed);
++ return NULL;
++ }
++
++ expected_size = (size_t) header->payload_offset
++ + header->payload_compressed;
++
++ } else {
++ if (header->payload_uncompressed > (SIZE_MAX - header->payload_offset)) {
++ pcmk__err("Header uncompressed size %" PRIu32 " is too large",
++ header->payload_uncompressed);
++ return NULL;
++ }
++
++ expected_size = (size_t) header->payload_offset
++ + header->payload_uncompressed;
++ }
++
++ if (expected_size != header->size_total) {
++ pcmk__err("Header total size %" PRIu32 " does not match calculated "
++ "size %zu", header->size_total, expected_size);
+ return NULL;
+ }
+
+--
+2.54.0
+
diff --git a/0002-High-libcrmcommon-Fix-integer-overflow-in-remote-mes.patch b/0002-High-libcrmcommon-Fix-integer-overflow-in-remote-mes.patch
new file mode 100644
index 0000000..fe230df
--- /dev/null
+++ b/0002-High-libcrmcommon-Fix-integer-overflow-in-remote-mes.patch
@@ -0,0 +1,95 @@
+From 1e1825bf2c28a349c576521fbda4393455297987 Mon Sep 17 00:00:00 2001
+From: Chris Lumens <clumens@redhat.com>
+Date: Thu, 14 May 2026 13:06:57 -0400
+Subject: [PATCH 2/5] High: libcrmcommon: Fix integer overflow in remote
+ message code.
+
+It's possible for a client to send a specifically constructed header
+packet that will cause our size checks in pcmk__remote_message_xml to
+overflow, which could result in crashes (potentially leading to a node
+being fenced) or memory corruption problems.
+
+Such a header would have to indicate that the payload is compressed,
+which nothing in pacemaker is doing. In fact, we haven't used any of
+the remote message compression code since it was introduced in 2013
+which explains why we haven't seen any problems with it. Thus, it would
+require a malicious client to cause this to happen.
+
+It would also require remote CIB administration to be enabled via
+remote-clear-port or remote-tls-port, which we do not do by default.
+Additionally, if remote-tls-port is in use, it requires the client to
+complete the gnutls handshake procedure (pcmk__remote_message_xml is
+only called in cib_remote_msg after the handshake but before the client
+has authenticated).
+
+Co-Authored-By: Reid Wahl <nrwahl@protonmail.com>
+---
+ lib/common/remote.c | 49 ++++++++++++++++++++++++++++++++++++++-------
+ 1 file changed, 42 insertions(+), 7 deletions(-)
+
+diff --git a/lib/common/remote.c b/lib/common/remote.c
+index f428c4ceda..d15f980f62 100644
+--- a/lib/common/remote.c
++++ b/lib/common/remote.c
+@@ -315,16 +315,51 @@ pcmk__remote_message_xml(pcmk__remote_t *remote)
+ }
+
+ /* Support compression on the receiving end now, in case we ever want to add it later */
+- if (header->payload_compressed) {
++ if (header->payload_compressed != 0) {
+ int rc = 0;
+- unsigned int size_u = 1 + header->payload_uncompressed;
+- char *uncompressed =
+- pcmk__assert_alloc(header->payload_offset + size_u, sizeof(char));
++ unsigned int size_u = 0;
++ char *uncompressed = NULL;
++
++#if (UINT32_MAX < UINT_MAX)
++ if (header->payload_uncompressed >= UINT_MAX) {
++ pcmk__err("Couldn't decompress message because uncompressed "
++ "payload size (%" PRIu32 ") is greater than UINT_MAX "
++ "(%u)", header->payload_uncompressed, UINT_MAX);
++ return NULL;
++ }
++#endif
++
++ /* @TODO Is the extra byte for the null terminator?
++ * pcmk__remote_send_xml() also adds one byte to the iov length.
++ * (However, we do need to account for the possibility of receiving a
++ * message from an untrusted sender.)
++ */
++ size_u = 1 + header->payload_uncompressed;
++
++ /* Header and uncompressed payload must fit in the destination buffer.
++ * We do not need to separately check the header size here since
++ * localized_remote_header will return NULL if it's incorrect.
++ */
++#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;
++ }
++
++ pcmk__trace("Decompressing message data %" PRIu32 " bytes into %u "
++ "bytes", header->payload_compressed, size_u);
+
+- pcmk__trace("Decompressing message data %d bytes into %d bytes",
+- header->payload_compressed, size_u);
++ uncompressed = pcmk__assert_alloc(header->payload_offset + size_u,
++ sizeof(char));
+
+- rc = BZ2_bzBuffToBuffDecompress(uncompressed + header->payload_offset, &size_u,
++ rc = BZ2_bzBuffToBuffDecompress(uncompressed + header->payload_offset,
++ &size_u,
+ remote->buffer + header->payload_offset,
+ header->payload_compressed, 1, 0);
+ rc = pcmk__bzlib2rc(rc);
+--
+2.54.0
+
diff --git a/0003-High-libcrmcommon-Limit-the-max-size-of-a-remote-mes.patch b/0003-High-libcrmcommon-Limit-the-max-size-of-a-remote-mes.patch
new file mode 100644
index 0000000..3fd679e
--- /dev/null
+++ b/0003-High-libcrmcommon-Limit-the-max-size-of-a-remote-mes.patch
@@ -0,0 +1,91 @@
+From bb37829e00c782071906305d2cf50247179f0fd7 Mon Sep 17 00:00:00 2001
+From: Chris Lumens <clumens@redhat.com>
+Date: Thu, 14 May 2026 13:26:07 -0400
+Subject: [PATCH 3/5] High: libcrmcommon: Limit the max size of a remote
+ message.
+
+Previously, we were just taking the sizes straight from the message
+header and allocating however much memory was asked for without
+checking. It's possible for a malicious client to ask for a very large
+amount of memory (say, 4 GB since that'll fit in the uint32_t value for
+header->size_total).
+
+In that case, due to the use of pcmk__assert_alloc, we'll crash due to
+an out of memory error and the node could potentially be fenced.
+
+The fix is to simply check that the client isn't asking for too much
+memory. This does unfortunately impose a size restriction on the
+message. It's doubly unfortunate given how much work we've recently put
+into removing restrictions on IPC messages allowing for much larger
+clusters.
+
+I think the biggest thing these messages will ever contain is a CIB, so
+for now I'm going with a limit of 20 MB. It is not my intention that
+this become a tuneable parameter that is exposed to the user.
+---
+ include/crm/common/remote_internal.h | 3 +++
+ lib/common/remote.c | 17 +++++++++++++++--
+ 2 files changed, 18 insertions(+), 2 deletions(-)
+
+diff --git a/include/crm/common/remote_internal.h b/include/crm/common/remote_internal.h
+index 2fad3a79f4..5f200272de 100644
+--- a/include/crm/common/remote_internal.h
++++ b/include/crm/common/remote_internal.h
+@@ -29,6 +29,9 @@
+ extern "C" {
+ #endif
+
++// The maximum payload size for a remote message (in bytes)
++#define PCMK__REMOTE_MSG_MAX_SIZE (20 * 1024 * 1024)
++
+ // internal functions from remote.c
+
+ typedef struct {
+diff --git a/lib/common/remote.c b/lib/common/remote.c
+index d15f980f62..9f36827c5b 100644
+--- a/lib/common/remote.c
++++ b/lib/common/remote.c
+@@ -319,6 +319,7 @@ pcmk__remote_message_xml(pcmk__remote_t *remote)
+ int rc = 0;
+ unsigned int size_u = 0;
+ char *uncompressed = NULL;
++ size_t buffer_size = 0;
+
+ #if (UINT32_MAX < UINT_MAX)
+ if (header->payload_uncompressed >= UINT_MAX) {
+@@ -352,11 +353,17 @@ pcmk__remote_message_xml(pcmk__remote_t *remote)
+ return NULL;
+ }
+
++ buffer_size = (size_t) header->payload_offset + size_u;
++ if (buffer_size > PCMK__REMOTE_MSG_MAX_SIZE) {
++ pcmk__err("Message size %zu is larger than max allowed %u bytes",
++ buffer_size, PCMK__REMOTE_MSG_MAX_SIZE);
++ return NULL;
++ }
++
+ pcmk__trace("Decompressing message data %" PRIu32 " bytes into %u "
+ "bytes", header->payload_compressed, size_u);
+
+- uncompressed = pcmk__assert_alloc(header->payload_offset + size_u,
+- sizeof(char));
++ uncompressed = pcmk__assert_alloc(buffer_size, sizeof(char));
+
+ rc = BZ2_bzBuffToBuffDecompress(uncompressed + header->payload_offset,
+ &size_u,
+@@ -510,6 +517,12 @@ pcmk__read_available_remote_data(pcmk__remote_t *remote)
+ read_len = header->size_total;
+ }
+
++ if (read_len > PCMK__REMOTE_MSG_MAX_SIZE) {
++ pcmk__err("Message size %zu is larger than max allowed %u bytes",
++ read_len, PCMK__REMOTE_MSG_MAX_SIZE);
++ return EINVAL;
++ }
++
+ /* automatically grow the buffer when needed */
+ if(remote->buffer_size < read_len) {
+ remote->buffer_size = 2 * read_len;
+--
+2.54.0
+
diff --git a/0004-High-libcrmcommon-Fix-an-integer-overflow-in-pcmk__r.patch b/0004-High-libcrmcommon-Fix-an-integer-overflow-in-pcmk__r.patch
new file mode 100644
index 0000000..33a1254
--- /dev/null
+++ b/0004-High-libcrmcommon-Fix-an-integer-overflow-in-pcmk__r.patch
@@ -0,0 +1,45 @@
+From 6dd7ce8e656b6c629d3268038d6606041460fae7 Mon Sep 17 00:00:00 2001
+From: Chris Lumens <clumens@redhat.com>
+Date: Fri, 15 May 2026 10:19:33 -0400
+Subject: [PATCH 4/5] High: libcrmcommon: Fix an integer overflow in
+ pcmk__remote_send_xml.
+
+iov[0].iov_len is a size_t. iov[1].iov_len is also a size_t (which
+comes from the length of a GString, which is a gsize, which is also a
+size_t). We're adding those together and storing them in a uint32_t, so
+make sure the result will fit.
+
+Fixes RHEL-181155
+---
+ lib/common/remote.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/lib/common/remote.c b/lib/common/remote.c
+index 9f36827c5b..cf093b0db1 100644
+--- a/lib/common/remote.c
++++ b/lib/common/remote.c
+@@ -280,6 +280,13 @@ pcmk__remote_send_xml(pcmk__remote_t *remote, const xmlNode *msg)
+ header->version = REMOTE_MSG_VERSION;
+ header->payload_offset = iov[0].iov_len;
+ header->payload_uncompressed = iov[1].iov_len;
++
++ if ((UINT32_MAX - iov[0].iov_len) < iov[1].iov_len) {
++ pcmk__err("Remote message size %zu + %zu exceeds maximum of %" PRIu32,
++ iov[0].iov_len, iov[1].iov_len, UINT32_MAX);
++ goto done;
++ }
++
+ header->size_total = iov[0].iov_len + iov[1].iov_len;
+
+ rc = remote_send_iovs(remote, iov, 2);
+@@ -288,6 +295,7 @@ pcmk__remote_send_xml(pcmk__remote_t *remote, const xmlNode *msg)
+ pcmk_rc_str(rc), rc);
+ }
+
++done:
+ free(iov[0].iov_base);
+ g_free((gchar *) iov[1].iov_base);
+ return rc;
+--
+2.54.0
+
diff --git a/0005-Refactor-libcib-Remove-an-unnecessary-coverity-suppr.patch b/0005-Refactor-libcib-Remove-an-unnecessary-coverity-suppr.patch
new file mode 100644
index 0000000..499b3a6
--- /dev/null
+++ b/0005-Refactor-libcib-Remove-an-unnecessary-coverity-suppr.patch
@@ -0,0 +1,27 @@
+From c49b26cb1e11bb160198a28ac5567b0154b49121 Mon Sep 17 00:00:00 2001
+From: Chris Lumens <clumens@redhat.com>
+Date: Thu, 28 May 2026 12:56:57 -0400
+Subject: [PATCH 5/5] Refactor: libcib: Remove an unnecessary coverity
+ suppression.
+
+With all the previous changes, this suppression is no longer necessary
+and can be removed.
+---
+ lib/cib/cib_remote.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/lib/cib/cib_remote.c b/lib/cib/cib_remote.c
+index 8ba9bb8909..b9eb393afa 100644
+--- a/lib/cib/cib_remote.c
++++ b/lib/cib/cib_remote.c
+@@ -258,7 +258,6 @@ cib_remote_callback_dispatch(void *user_data)
+ return -1;
+ }
+
+- // coverity[tainted_data] This can't easily be changed right now
+ msg = pcmk__remote_message_xml(&private->callback);
+ if (msg == NULL) {
+ private->start_time = 0;
+--
+2.54.0
+
diff --git a/pacemaker.spec b/pacemaker.spec
index 04ac4a0..d10db37 100644
--- a/pacemaker.spec
+++ b/pacemaker.spec
@@ -41,7 +41,7 @@
## can be incremented to build packages reliably considered "newer"
## than previously built packages with the same pcmkversion)
%global pcmkversion 3.0.2
-%global baserelease 2
+%global baserelease 3
## Upstream commit (full commit ID, abbreviated commit ID, or tag) to build
%global commit c75e25851c05c6b0ff48caeaa15854d5868ce428
@@ -193,6 +193,11 @@ Source0: https://codeload.github.com/%{github_owner}/%{name}/tar.gz/%{arch
Source1: pacemaker.sysusers
# upstream commits
+Patch0: 0001-Med-libcrmcommon-Fix-checks-in-localized_remote_head.patch
+Patch1: 0002-High-libcrmcommon-Fix-integer-overflow-in-remote-mes.patch
+Patch2: 0003-High-libcrmcommon-Limit-the-max-size-of-a-remote-mes.patch
+Patch3: 0004-High-libcrmcommon-Fix-an-integer-overflow-in-pcmk__r.patch
+Patch4: 0005-Refactor-libcib-Remove-an-unnecessary-coverity-suppr.patch
Requires: resource-agents
Requires: %{pkgname_pcmk_libs}%{?_isa} = %{version}-%{release}
@@ -764,6 +769,9 @@ fi
%{_datadir}/pkgconfig/pacemaker-schemas.pc
%changelog
+* Wed Jun 17 2026 Klaus Wenninger <klaus.wenninger@aon.at> - 3.0.2-3
+- fix CVE-2026-10649: Fix integer overflows in remote message code
+
* Thu Jun 04 2026 Python Maint <python-maint@redhat.com> - 3.0.2-2
- Rebuilt for Python 3.15
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-06-17 20:44 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-06-17 20:44 [rpms/pacemaker] rawhide: * Wed Jun 17 2026 Klaus Wenninger <klaus.wenninger@aon.at> - 3.0.2-2 Klaus Wenninger
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox