File pacemaker-libcrmservice-memory-leak-on-DBus-error.patch of Package pacemaker.14737
commit b1c7ceef9a60a06f6acee13504a32077065a4f61
Author: Ken Gaillot <kgaillot@redhat.com>
Date: Thu Dec 14 10:36:20 2017 -0600
Low: libcrmservice: avoid memory leak on DBus error
Index: pacemaker/lib/services/dbus.c
===================================================================
--- pacemaker.orig/lib/services/dbus.c
+++ pacemaker/lib/services/dbus.c
@@ -35,6 +35,15 @@ pcmk_dbus_error_check(DBusError *err, co
return FALSE;
}
+static void
+free_db_getall_data(struct db_getall_data *data)
+{
+ free(data->target);
+ free(data->object);
+ free(data->name);
+ free(data);
+}
+
DBusConnection *
pcmk_dbus_connect(void)
{
@@ -171,6 +180,20 @@ pcmk_dbus_send_recv(DBusMessage *msg, DB
return reply;
}
+/*!
+ * \internal
+ * \brief Send a DBus message with a callback for the reply
+ *
+ * \param[in] msg DBus message to send
+ * \param[in,out] connection DBus connection to send on
+ * \param[in] done Function to call when pending call completes
+ * \param[in] user_data Data to pass to done callback
+ *
+ * \return Handle for reply on success, NULL on error
+ * \note The caller can assume that the done callback is called always and
+ * only when the return value is non-NULL. (This allows the caller to
+ * know where it should free dynamically allocated user_data.)
+ */
DBusPendingCall *
pcmk_dbus_send(DBusMessage *msg, DBusConnection *connection,
void(*done)(DBusPendingCall *pending, void *user_data),
@@ -335,11 +358,7 @@ pcmk_dbus_lookup_result(DBusMessage *rep
}
cleanup:
- free(data->target);
- free(data->object);
- free(data->name);
- free(data);
-
+ free_db_getall_data(data);
return output;
}
@@ -400,11 +419,19 @@ pcmk_dbus_get_property(DBusConnection *c
query_data->name = strdup(name);
}
- if(query_data->callback) {
- DBusPendingCall* _pending;
- _pending = pcmk_dbus_send(msg, connection, pcmk_dbus_lookup_cb, query_data, timeout);
- if (pending != NULL) {
- *pending = _pending;
+ if (query_data->callback) {
+ DBusPendingCall *local_pending;
+
+ local_pending = pcmk_dbus_send(msg, connection, pcmk_dbus_lookup_cb,
+ query_data, timeout);
+ if (local_pending == NULL) {
+ // pcmk_dbus_lookup_cb() was not called in this case
+ free_db_getall_data(query_data);
+ query_data = NULL;
+ }
+
+ if (pending) {
+ *pending = local_pending;
}
} else {