import Oracle_OSS pacemaker-2.1.10-3.0.1.el9_8

This commit is contained in:
AlmaLinux RelEng Bot 2026-07-20 03:26:34 -04:00
parent 48b3808443
commit bd9348bff9
6 changed files with 744 additions and 7 deletions

View File

@ -0,0 +1,131 @@
From 17a2d7acffc86e06b2fa8b49c96c33d72466e7f7 Mon Sep 17 00:00:00 2001
From: Reid Wahl <nrwahl@protonmail.com>
Date: Fri, 5 Sep 2025 20:35:31 -0700
Subject: [PATCH] Fix: tools: Handle large timeouts correctly in crm_resource
--wait
Previously, if the --timeout value parsed to a value greater than
(UINT_MAX - 999), the wait timeout would overflow. The effective timeout
would be either 0 seconds or 1 second. This is because 999 was added to
the guint value before passing it to pcmk__timeout_ms2s().
Now, we simply pass the timeout in milliseconds to
pcmk__timeout_ms2s(), without adding 999.
This implies a slight behavior change. Previously, timeouts were always
rounded up to the next greatest second. Now, they're rounded to the
nearest second. For example, previously:
* timeout values between 1ms and 500ms => wait timeout of 1 second
* timeout values between 501ms and 1500ms => wait timeout of 2 seconds
* timeout values between 1501ms and 2500ms => wait timeout of 3 seconds
* and so on
Now:
* timeout values between 1ms and 1499ms => wait timeout of 1 second
* timeout values between 1500ms and 2499ms => wait timeout of 2 seconds
* timeout values between 2500ms and 3499ms => wait timeout of 3 seconds
* and so on
The previous rounding behavior has existed since crm_resource --wait was
added by 424afcdf.
Update the help text to note the granularity and rounding behavior. The
exact behavior of the restart command is confusing, and its logic should
be cleaned up in the future.
Fixes RHEL-45869
Fixes RHEL-86148
Closes T841
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
---
include/crm/common/internal.h | 1 +
lib/common/utils.c | 30 ++++++++++++++++++++++++++++++
tools/crm_resource.c | 4 +++-
tools/crm_resource_runtime.c | 2 +-
4 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/include/crm/common/internal.h b/include/crm/common/internal.h
index 7d1e95f..ee26321 100644
--- a/include/crm/common/internal.h
+++ b/include/crm/common/internal.h
@@ -249,6 +249,7 @@ void pcmk__daemonize(const char *name, const char *pidfile);
void pcmk__panic(const char *origin);
pid_t pcmk__locate_sbd(void);
void pcmk__sleep_ms(unsigned int ms);
+guint pcmk__timeout_ms2s(guint timeout_ms);
extern int pcmk__score_red;
extern int pcmk__score_green;
diff --git a/lib/common/utils.c b/lib/common/utils.c
index 9e44c22..0a38811 100644
--- a/lib/common/utils.c
+++ b/lib/common/utils.c
@@ -413,6 +413,36 @@ pcmk__sleep_ms(unsigned int ms)
#endif
}
+/*!
+ * \internal
+ * \brief Convert milliseconds to seconds
+ *
+ * \param[in] timeout_ms The interval, in ms
+ *
+ * \return If \p timeout_ms is 0, return 0. Otherwise, return the number of
+ * seconds, rounded to the nearest integer, with a minimum of 1.
+ */
+guint
+pcmk__timeout_ms2s(guint timeout_ms)
+{
+ guint quot, rem;
+
+ if (timeout_ms == 0) {
+ return 0;
+ } else if (timeout_ms < 1000) {
+ return 1;
+ }
+
+ quot = timeout_ms / 1000;
+ rem = timeout_ms % 1000;
+
+ if (rem >= 500) {
+ quot += 1;
+ }
+
+ return quot;
+}
+
// Deprecated functions kept only for backward API compatibility
// LCOV_EXCL_START
diff --git a/tools/crm_resource.c b/tools/crm_resource.c
index 898c21e..ac50c5e 100644
--- a/tools/crm_resource.c
+++ b/tools/crm_resource.c
@@ -766,7 +766,9 @@ static GOptionEntry addl_entries[] = {
"ID" },
{ "timeout", 'T', G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, timeout_cb,
"(Advanced) Abort if command does not finish in this time (with\n"
- INDENT "--restart, --wait, --force-*)",
+ INDENT "--restart, --wait, --force-*). The --restart command uses a\n"
+ INDENT "two-second granularity and the --wait command uses a one-second\n"
+ INDENT "granularity, with rounding.",
"N" },
{ "all", 0, G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &options.all,
"List all options, including advanced and deprecated (with\n"
diff --git a/tools/crm_resource_runtime.c b/tools/crm_resource_runtime.c
index 7350f07..286c10c 100644
--- a/tools/crm_resource_runtime.c
+++ b/tools/crm_resource_runtime.c
@@ -1977,7 +1977,7 @@ wait_till_stable(pcmk__output_t *out, guint timeout_ms, cib_t * cib)
if (timeout_ms == 0) {
expire_time += WAIT_DEFAULT_TIMEOUT_S;
} else {
- expire_time += (timeout_ms + 999) / 1000;
+ expire_time += pcmk__timeout_ms2s(timeout_ms);
}
scheduler = pe_new_working_set();
--
2.47.1

View File

@ -0,0 +1,178 @@
From 8ff58d786907b64c32350e72e341cdd0f5026813 Mon Sep 17 00:00:00 2001
From: Thomas Jones <thomas.jones@ibm.com>
Date: Fri, 30 May 2025 16:40:13 -0400
Subject: [PATCH 1/2] Fix: libcrmcommon: Add retries on connect to avoid fatal
errors when sub-daemons communicate Add pcmk__connect_ipc_retry_conrefused()
and use it where it makes sense Add retry loop to
connect_and_send_attrd_request() that retries connect and send.
---
daemons/controld/controld_schedulerd.c | 2 +-
include/crm/common/ipc_internal.h | 4 ++++
lib/common/ipc_attrd.c | 19 ++++++++++++----
lib/common/ipc_client.c | 30 ++++++++++++++++++++++++++
lib/pacemaker/pcmk_cluster_queries.c | 2 +-
5 files changed, 51 insertions(+), 6 deletions(-)
diff --git a/daemons/controld/controld_schedulerd.c b/daemons/controld/controld_schedulerd.c
index 22b37b8..444bdef 100644
--- a/daemons/controld/controld_schedulerd.c
+++ b/daemons/controld/controld_schedulerd.c
@@ -197,7 +197,7 @@ new_schedulerd_ipc_connection(void)
pcmk_register_ipc_callback(schedulerd_api, scheduler_event_callback, NULL);
- rc = pcmk__connect_ipc(schedulerd_api, pcmk_ipc_dispatch_main, 3);
+ rc = pcmk__connect_ipc_retry_conrefused(schedulerd_api, pcmk_ipc_dispatch_main, 3);
if (rc != pcmk_rc_ok) {
crm_err("Error connecting to %s: %s",
pcmk_ipc_name(schedulerd_api, true), pcmk_rc_str(rc));
diff --git a/include/crm/common/ipc_internal.h b/include/crm/common/ipc_internal.h
index 27b8bfc..09145ba 100644
--- a/include/crm/common/ipc_internal.h
+++ b/include/crm/common/ipc_internal.h
@@ -101,6 +101,10 @@ int pcmk__ipc_fd(crm_ipc_t *ipc, int *fd);
int pcmk__connect_ipc(pcmk_ipc_api_t *api, enum pcmk_ipc_dispatch dispatch_type,
int attempts);
+int pcmk__connect_ipc_retry_conrefused(pcmk_ipc_api_t *api,
+ enum pcmk_ipc_dispatch dispatch_type,
+ int attempts);
+
/*
* Server-related
*/
diff --git a/lib/common/ipc_attrd.c b/lib/common/ipc_attrd.c
index 5ab0f2d..60a92a0 100644
--- a/lib/common/ipc_attrd.c
+++ b/lib/common/ipc_attrd.c
@@ -152,6 +152,8 @@ create_attrd_op(const char *user_name)
static int
connect_and_send_attrd_request(pcmk_ipc_api_t *api, const xmlNode *request)
{
+ static const int max_retries = 5;
+ int remaining_attempts = max_retries;
int rc = pcmk_rc_ok;
bool created_api = false;
@@ -163,10 +165,19 @@ connect_and_send_attrd_request(pcmk_ipc_api_t *api, const xmlNode *request)
created_api = true;
}
- rc = pcmk__connect_ipc(api, pcmk_ipc_dispatch_sync, 5);
- if (rc == pcmk_rc_ok) {
- rc = pcmk__send_ipc_request(api, request);
- }
+ // If attrd is killed and is being restarted we will temporarily get
+ // ECONNREFUSED on connect if it is already dead or ENOTCONN if it died
+ // after we connected to it. We should wait a bit and retry in those cases.
+ do {
+ if (rc == ENOTCONN || rc == ECONNREFUSED) {
+ sleep(max_retries - remaining_attempts);
+ }
+ rc = pcmk__connect_ipc(api, pcmk_ipc_dispatch_sync, remaining_attempts);
+ if (rc == pcmk_rc_ok) {
+ rc = pcmk__send_ipc_request(api, request);
+ }
+ remaining_attempts--;
+ } while ((rc == ENOTCONN || rc == ECONNREFUSED) && remaining_attempts >= 0);
if (created_api) {
pcmk_free_ipc_api(api);
diff --git a/lib/common/ipc_client.c b/lib/common/ipc_client.c
index 24d7745..4ac7810 100644
--- a/lib/common/ipc_client.c
+++ b/lib/common/ipc_client.c
@@ -488,6 +488,36 @@ connect_without_main_loop(pcmk_ipc_api_t *api)
return rc;
}
+/*!
+ * \internal
+ * \brief Connect to a Pacemaker daemon via IPC (retrying after soft errors
+ * and ECONNREFUSED)
+ *
+ * \param[in,out] api IPC API instance
+ * \param[in] dispatch_type How IPC replies should be dispatched
+ * \param[in] attempts How many times to try (in case of soft error)
+ *
+ * \return Standard Pacemaker return code
+*/
+int
+pcmk__connect_ipc_retry_conrefused(pcmk_ipc_api_t *api,
+ enum pcmk_ipc_dispatch dispatch_type,
+ int attempts)
+{
+ int remaining = attempts;
+ int rc = pcmk_rc_ok;
+
+ do {
+ if (rc == ECONNREFUSED) {
+ pcmk__sleep_ms((attempts - remaining) * 500);
+ }
+ rc = pcmk__connect_ipc(api, dispatch_type, remaining);
+ remaining--;
+ } while (rc == ECONNREFUSED && remaining >= 0);
+
+ return rc;
+}
+
/*!
* \internal
* \brief Connect to a Pacemaker daemon via IPC (retrying after soft errors)
diff --git a/lib/pacemaker/pcmk_cluster_queries.c b/lib/pacemaker/pcmk_cluster_queries.c
index bbefcda..c1fcf73 100644
--- a/lib/pacemaker/pcmk_cluster_queries.c
+++ b/lib/pacemaker/pcmk_cluster_queries.c
@@ -360,7 +360,7 @@ ipc_connect(data_t *data, enum pcmk_ipc_server server, pcmk_ipc_callback_t cb,
pcmk_register_ipc_callback(api, cb, data);
}
- rc = pcmk__connect_ipc(api, dispatch_type, 5);
+ rc = pcmk__connect_ipc_retry_conrefused(api, dispatch_type, 5);
if (rc != pcmk_rc_ok) {
if (rc == EREMOTEIO) {
data->pcmkd_state = pcmk_pacemakerd_state_remote;
--
2.47.1
From 2e46b914fb08d346d7b022ba75302f9290034507 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Mon, 4 Aug 2025 10:38:00 -0400
Subject: [PATCH 2/2] Med: libpacemaker: Do not retry on ECONNREFUSED in tools.
This is a regression introduced by e438946787. In that patch, what
we're trying to do is retry IPC connections between daemons. If a
daemon gets ECONNREFUSED when it initiates an IPC connection, the most
likely reason is that another daemon has been killed and is restarting
but is not yet ready to accept connections. Waiting and retrying
repeatedly is an acceptable way to deal with this.
However, if a command line tool gets ECONNREFUSED, it's more likely that
the problem is the cluster isn't running at all. In this case, waiting
and retrying just introduces a delay for a situation that will never be
resolved. Reverting just the part in pcmk_cluster_queries.c should fix
this problem without affecting any of the daemons - they don't call this
code.
Fixes RHEL-106594
---
lib/pacemaker/pcmk_cluster_queries.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/pacemaker/pcmk_cluster_queries.c b/lib/pacemaker/pcmk_cluster_queries.c
index c1fcf73..bbefcda 100644
--- a/lib/pacemaker/pcmk_cluster_queries.c
+++ b/lib/pacemaker/pcmk_cluster_queries.c
@@ -360,7 +360,7 @@ ipc_connect(data_t *data, enum pcmk_ipc_server server, pcmk_ipc_callback_t cb,
pcmk_register_ipc_callback(api, cb, data);
}
- rc = pcmk__connect_ipc_retry_conrefused(api, dispatch_type, 5);
+ rc = pcmk__connect_ipc(api, dispatch_type, 5);
if (rc != pcmk_rc_ok) {
if (rc == EREMOTEIO) {
data->pcmkd_state = pcmk_pacemakerd_state_remote;
--
2.47.1

View File

@ -0,0 +1,413 @@
From 264d94dcdb4c6739355f7251b4e9e81256938dbf 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/6] Med: libcrmcommon: Add sanity checks to
localized_remote_header.
These checks are present in the main and 3.0 branches, and they make
sense here as well.
---
lib/common/remote.c | 52 ++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 47 insertions(+), 5 deletions(-)
diff --git a/lib/common/remote.c b/lib/common/remote.c
index b25e5ce..a4c8b8a 100644
--- a/lib/common/remote.c
+++ b/lib/common/remote.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2024 the Pacemaker project contributors
+ * Copyright 2008-2026 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -23,7 +23,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>
@@ -97,11 +97,18 @@ struct remote_header_v0 {
static struct remote_header_v0 *
localized_remote_header(pcmk__remote_t *remote)
{
- struct remote_header_v0 *header = (struct remote_header_v0 *)remote->buffer;
- if(remote->buffer_offset < sizeof(struct remote_header_v0)) {
+ 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))) {
+
+ // Caller error or we haven't received the full header yet
return NULL;
+ }
- } else if(header->endian != ENDIAN_LOCAL) {
+ header = (struct remote_header_v0 *) remote->buffer;
+ if (header->endian != ENDIAN_LOCAL) {
uint32_t endian = __swab32(header->endian);
CRM_LOG_ASSERT(endian == ENDIAN_LOCAL);
@@ -123,6 +130,41 @@ localized_remote_header(pcmk__remote_t *remote)
header->payload_uncompressed = __swab32(header->payload_uncompressed);
}
+ // Sanity checks
+ if (header->payload_offset != sizeof(struct remote_header_v0)) {
+ crm_err("Header payload offset %" PRIu32 " does not have expected "
+ "size %zu", header->payload_offset,
+ sizeof(struct remote_header_v0));
+ return NULL;
+ }
+
+ if (header->payload_compressed != 0) {
+ if (header->payload_compressed > (SIZE_MAX - header->payload_offset)) {
+ crm_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)) {
+ crm_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) {
+ crm_err("Header total size %" PRIu32 " does not match calculated "
+ "size %zu", header->size_total, expected_size);
+ return NULL;
+ }
+
return header;
}
--
2.53.0
From 8d21d297629bcc8aebf71bb171c550bcc4532c3f 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/6] 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 a4c8b8a..aa8e762 100644
--- a/lib/common/remote.c
+++ b/lib/common/remote.c
@@ -619,16 +619,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(1, header->payload_offset + size_u);
+ unsigned int size_u = 0;
+ char *uncompressed = NULL;
+
+#if (UINT32_MAX < UINT_MAX)
+ if (header->payload_uncompressed >= UINT_MAX) {
+ crm_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
+ crm_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;
+ }
+
+ crm_trace("Decompressing message data %" PRIu32 " bytes into %u "
+ "bytes", header->payload_compressed, size_u);
- crm_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.53.0
From 77a530d1bb867264fa0d42752da44d75ee063830 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/6] 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 | 5 ++++-
lib/common/remote.c | 17 +++++++++++++++--
2 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/include/crm/common/remote_internal.h b/include/crm/common/remote_internal.h
index f8c0bea..00f5918 100644
--- a/include/crm/common/remote_internal.h
+++ b/include/crm/common/remote_internal.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2024 the Pacemaker project contributors
+ * Copyright 2008-2026 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -15,6 +15,9 @@
#include <crm/common/nodes.h> // pcmk_node_variant_remote
#include <crm/common/scheduler_types.h> // pcmk_node_t
+// 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 pcmk__remote_s pcmk__remote_t;
diff --git a/lib/common/remote.c b/lib/common/remote.c
index aa8e762..08b6988 100644
--- a/lib/common/remote.c
+++ b/lib/common/remote.c
@@ -623,6 +623,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) {
@@ -656,11 +657,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) {
+ crm_err("Message size %zu is larger than max allowed %u bytes",
+ buffer_size, PCMK__REMOTE_MSG_MAX_SIZE);
+ return NULL;
+ }
+
crm_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,
@@ -805,6 +812,12 @@ pcmk__read_available_remote_data(pcmk__remote_t *remote)
read_len = header->size_total;
}
+ if (read_len > PCMK__REMOTE_MSG_MAX_SIZE) {
+ crm_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.53.0
From eaae2d00a2d29c0187832a55a81cf42b39d93a25 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/6] 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 08b6988..83f050d 100644
--- a/lib/common/remote.c
+++ b/lib/common/remote.c
@@ -586,6 +586,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) {
+ crm_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);
@@ -594,6 +601,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.53.0
From 2e097d03f1d93f95162a37a5c21ec46d911af176 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/6] 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 baed17b..a64ff95 100644
--- a/lib/cib/cib_remote.c
+++ b/lib/cib/cib_remote.c
@@ -243,7 +243,6 @@ cib_remote_callback_dispatch(gpointer 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.53.0
From 2a3c713c3ceab8f5aded9693d09203d18b33bf55 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Wed, 17 Jun 2026 15:55:28 -0400
Subject: [PATCH 6/6] Med: libcrmcommon: Add additional checks to
pcmk__remote_message_xml.
coverity flags the existing code for using a tainted expression as an
index to a pointer. While we're fixing other range errors and overflows
in this code, we should fix this one as well by porting the existing
code from the main branch.
---
lib/common/remote.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/lib/common/remote.c b/lib/common/remote.c
index 83f050d..9ad4b17 100644
--- a/lib/common/remote.c
+++ b/lib/common/remote.c
@@ -620,6 +620,7 @@ xmlNode *
pcmk__remote_message_xml(pcmk__remote_t *remote)
{
xmlNode *xml = NULL;
+ size_t data_size = 0;
struct remote_header_v0 *header = localized_remote_header(remote);
if (header == NULL) {
@@ -709,7 +710,18 @@ pcmk__remote_message_xml(pcmk__remote_t *remote)
/* take ownership of the buffer */
remote->buffer_offset = 0;
- CRM_LOG_ASSERT(remote->buffer[sizeof(struct remote_header_v0) + header->payload_uncompressed - 1] == 0);
+ data_size = (size_t) header->payload_offset + header->payload_uncompressed;
+
+ // Ensure the buffer is as big as it should be
+ CRM_CHECK(remote->buffer_size >= data_size, return NULL);
+
+ /* Ensure the buffer is null-terminated (see
+ * pcmk__read_available_remote_data()).
+ *
+ * Note that payload_uncompressed contains the payload size including the
+ * null byte (see pcmk__remote_send_xml()).
+ */
+ CRM_CHECK(remote->buffer[data_size] == '\0', return NULL);
xml = pcmk__xml_parse(remote->buffer + header->payload_offset);
if (xml == NULL && header->version > REMOTE_MSG_VERSION) {
--
2.53.0

View File

@ -22,7 +22,7 @@
## Where bug reports should be submitted
## Leave bug_url undefined to use ClusterLabs default, others define it here
%if 0%{?rhel}
%global bug_url https://issues.redhat.com/
%global bug_url https://github.com/oracle/oracle-linux/
%else
%if 0%{?fedora}
%global bug_url https://bugz.fedoraproject.org/%{name}
@ -36,7 +36,7 @@
## can be incremented to build packages reliably considered "newer"
## than previously built packages with the same pcmkversion)
%global pcmkversion 2.1.10
%global specversion 1
%global specversion 3
## Upstream commit (full commit ID, abbreviated commit ID, or tag) to build
%global commit 5693eaeeef06faa1622515963082b5a1731d9fc0
@ -230,7 +230,7 @@
Name: pacemaker
Summary: Scalable High-Availability cluster resource manager
Version: %{pcmkversion}
Release: %{pcmk_release}.1%{?dist}
Release: %{pcmk_release}.0.1%{?dist}
License: GPL-2.0-or-later AND LGPL-2.1-or-later
Url: https://www.clusterlabs.org/
@ -247,8 +247,11 @@ Source1: https://codeload.github.com/%{github_owner}/%{nagios_name}/tar.gz
Source2: pacemaker.sysusers
# upstream commits
Patch001: 001-ipc_evict.patch
Patch002: 002-fewer_messages.patch
Patch001: 001-crm_resource_wait.patch
Patch002: 002-ipc_connect_retry.patch
Patch003: 003-ipc_evict.patch
Patch004: 004-fewer_messages.patch
Patch005: 005-remote_overflow.patch
Requires: resource-agents
Requires: %{pkgname_pcmk_libs}%{?_isa} = %{version}-%{release}
@ -915,10 +918,22 @@ exit 0
%license %{nagios_name}-%{nagios_hash}/COPYING
%changelog
* Wed Feb 18 2026 Chris Lumens <clumens@redhat.com> - 2.1.10-1.1
* Tue Jul 14 2026 EL Errata <el-errata_ww@oracle.com> - 2.1.10-3.0.1
- Replace bug url [Orabug: 34202300]
- Upstream reference in pacemaker crm_report binary [Orabug: 32825154]
* Tue Jun 30 2026 Chris Lumens <clumens@redhat.com> - 2.1.10-3
- Fix integer overflows in remote message decompression code (CVE-2026-10649)
- Resolves: RHEL-181150
* Wed Nov 12 2025 Chris Lumens <clumens@redhat.com> - 2.1.10-2
- Handle large timeouts correctly in crm_resource --wait
- Do not try to connect to subdaemons before they're respawned
- Don't evict IPC clients as long as they're still processing messages
- Don't overwhelm the FSA queue with repeated CIB queries
- Resolves: RHEL-150167
- Resolves: RHEL-45869
- Resolves: RHEL-87484
- Resolves: RHEL-114894
* Mon Jun 23 2025 Chris Lumens <clumens@redhat.com> - 2.1.10-1
- Rebase on upstream 2.1.10-rc1 release