|
|
97a979 |
From ed8b2c86ab77aaa3d7fd688c049ad5e1b922a9c6 Mon Sep 17 00:00:00 2001
|
|
|
97a979 |
From: Reid Wahl <nrwahl@protonmail.com>
|
|
|
97a979 |
Date: Thu, 13 Jan 2022 02:56:55 -0800
|
|
|
97a979 |
Subject: [PATCH] Fix: liblrmd: Avoid double-free during notify operation
|
|
|
97a979 |
|
|
|
97a979 |
This commit fixes a regression introduced by 31c7fa8a, causing a
|
|
|
97a979 |
double-free in notify operations. lrmd_dispatch_internal() assigns the
|
|
|
97a979 |
exit_reason string directly from an XML node to a new lrmd_event_data_t
|
|
|
97a979 |
object (without duplicating), and this string gets freed twice.
|
|
|
97a979 |
|
|
|
97a979 |
Free #1: pcmk__create_history_xml() (reached via callback) calls
|
|
|
97a979 |
lrmd__set_result(), which frees event.exit_reason and sets it to NULL.
|
|
|
97a979 |
Free #2: lrmd_ipc_dispatch() frees the XML node, which contains a
|
|
|
97a979 |
pointer to the exit_reason string just freed, after
|
|
|
97a979 |
lrmd_dispatch_internal() returns.
|
|
|
97a979 |
|
|
|
97a979 |
Prior to 31c7fa8a, pcmk__create_history_xml reset event.rc and
|
|
|
97a979 |
event.op_status but **not** event.exit_reason.
|
|
|
97a979 |
|
|
|
97a979 |
In this commit we simply make a copy of event.exit_reason in
|
|
|
97a979 |
lrmd_dispatch_internal() before the callback. This way we don't have to
|
|
|
97a979 |
worry about whatever happens in the callback, and we can continue to
|
|
|
97a979 |
unset the exit_reason alongside the rc and op_status. The added overhead
|
|
|
97a979 |
should be minimal.
|
|
|
97a979 |
|
|
|
97a979 |
This commit also makes a copy of output. That's not strictly necessary
|
|
|
97a979 |
but adds some futureproofing and allows us to call lrmd__reset_result()
|
|
|
97a979 |
at the end of lrmd_dispatch_internal().
|
|
|
97a979 |
|
|
|
97a979 |
Resolves: RHBZ#2039675
|
|
|
97a979 |
|
|
|
97a979 |
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
|
|
|
97a979 |
---
|
|
|
97a979 |
lib/lrmd/lrmd_client.c | 8 +++++---
|
|
|
97a979 |
1 file changed, 5 insertions(+), 3 deletions(-)
|
|
|
97a979 |
|
|
|
97a979 |
diff --git a/lib/lrmd/lrmd_client.c b/lib/lrmd/lrmd_client.c
|
|
|
97a979 |
index ee31bb5ae9..5131a648b7 100644
|
|
|
97a979 |
--- a/lib/lrmd/lrmd_client.c
|
|
|
97a979 |
+++ b/lib/lrmd/lrmd_client.c
|
|
|
97a979 |
@@ -305,9 +305,10 @@ lrmd_dispatch_internal(lrmd_t * lrmd, xmlNode * msg)
|
|
|
97a979 |
event.user_data = crm_element_value(msg, F_LRMD_RSC_USERDATA_STR);
|
|
|
97a979 |
event.type = lrmd_event_exec_complete;
|
|
|
97a979 |
|
|
|
97a979 |
- // No need to duplicate the memory, so don't use setter functions
|
|
|
97a979 |
- event.output = crm_element_value(msg, F_LRMD_RSC_OUTPUT);
|
|
|
97a979 |
- event.exit_reason = crm_element_value(msg, F_LRMD_RSC_EXIT_REASON);
|
|
|
97a979 |
+ /* output and exit_reason may be freed by a callback */
|
|
|
97a979 |
+ event.output = crm_element_value_copy(msg, F_LRMD_RSC_OUTPUT);
|
|
|
97a979 |
+ lrmd__set_result(&event, event.rc, event.op_status,
|
|
|
97a979 |
+ crm_element_value(msg, F_LRMD_RSC_EXIT_REASON));
|
|
|
97a979 |
|
|
|
97a979 |
event.params = xml2list(msg);
|
|
|
97a979 |
} else if (pcmk__str_eq(type, LRMD_OP_NEW_CLIENT, pcmk__str_none)) {
|
|
|
97a979 |
@@ -324,6 +325,7 @@ lrmd_dispatch_internal(lrmd_t * lrmd, xmlNode * msg)
|
|
|
97a979 |
if (event.params) {
|
|
|
97a979 |
g_hash_table_destroy(event.params);
|
|
|
97a979 |
}
|
|
|
97a979 |
+ lrmd__reset_result(&event);
|
|
|
97a979 |
}
|
|
|
97a979 |
|
|
|
97a979 |
// \return Always 0, to indicate that IPC mainloop source should be kept
|
|
|
97a979 |
--
|
|
|
97a979 |
2.27.0
|
|
|
97a979 |
|