|
|
b2d430 |
From efb18a2688546db9c6fe7ba75b595a2fc54dff41 Mon Sep 17 00:00:00 2001
|
|
|
b2d430 |
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
|
|
b2d430 |
Date: Fri, 15 Jul 2016 14:50:41 +0200
|
|
|
b2d430 |
Subject: [PATCH 098/102] sbus: allow freeing msg through dbus api when using
|
|
|
b2d430 |
talloc
|
|
|
b2d430 |
MIME-Version: 1.0
|
|
|
b2d430 |
Content-Type: text/plain; charset=UTF-8
|
|
|
b2d430 |
Content-Transfer-Encoding: 8bit
|
|
|
b2d430 |
|
|
|
b2d430 |
When a talloc-bound message was freed by removing all references
|
|
|
b2d430 |
to it with dbus_message_unref we failed to free the talloc context
|
|
|
b2d430 |
and thus leaking memory or unreferencing invalid message when
|
|
|
b2d430 |
the parent context is freed.
|
|
|
b2d430 |
|
|
|
b2d430 |
This patch allows to bound dbus message to talloc in the way that
|
|
|
b2d430 |
allows us to free the message by both talloc and dbus api.
|
|
|
b2d430 |
|
|
|
b2d430 |
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
|
|
|
b2d430 |
(cherry picked from commit 5d556f70f00c43864d8495d7caacfadf962799df)
|
|
|
b2d430 |
---
|
|
|
b2d430 |
src/sbus/sssd_dbus_utils.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
b2d430 |
1 file changed, 51 insertions(+)
|
|
|
b2d430 |
|
|
|
b2d430 |
diff --git a/src/sbus/sssd_dbus_utils.c b/src/sbus/sssd_dbus_utils.c
|
|
|
b2d430 |
index 4c33f9fd75cac2d4a56a5638982f8ecb73da8e2e..b0150e2fe7f829013677e0a4a894d1468e5b9128 100644
|
|
|
b2d430 |
--- a/src/sbus/sssd_dbus_utils.c
|
|
|
b2d430 |
+++ b/src/sbus/sssd_dbus_utils.c
|
|
|
b2d430 |
@@ -25,22 +25,52 @@
|
|
|
b2d430 |
|
|
|
b2d430 |
struct sbus_talloc_msg {
|
|
|
b2d430 |
DBusMessage *msg;
|
|
|
b2d430 |
+ dbus_int32_t data_slot;
|
|
|
b2d430 |
+ bool in_talloc_destructor;
|
|
|
b2d430 |
};
|
|
|
b2d430 |
|
|
|
b2d430 |
static int sbus_talloc_msg_destructor(struct sbus_talloc_msg *talloc_msg)
|
|
|
b2d430 |
{
|
|
|
b2d430 |
+ talloc_msg->in_talloc_destructor = true;
|
|
|
b2d430 |
+
|
|
|
b2d430 |
if (talloc_msg->msg == NULL) {
|
|
|
b2d430 |
return 0;
|
|
|
b2d430 |
}
|
|
|
b2d430 |
|
|
|
b2d430 |
+ /* There may exist more references to this message but this talloc
|
|
|
b2d430 |
+ * context is no longer valid. We remove dbus message data to invoke
|
|
|
b2d430 |
+ * dbus destructor now. */
|
|
|
b2d430 |
+ dbus_message_set_data(talloc_msg->msg, talloc_msg->data_slot, NULL, NULL);
|
|
|
b2d430 |
dbus_message_unref(talloc_msg->msg);
|
|
|
b2d430 |
return 0;
|
|
|
b2d430 |
}
|
|
|
b2d430 |
|
|
|
b2d430 |
+static void sbus_msg_data_destructor(void *ctx)
|
|
|
b2d430 |
+{
|
|
|
b2d430 |
+ struct sbus_talloc_msg *talloc_msg;
|
|
|
b2d430 |
+
|
|
|
b2d430 |
+ talloc_msg = talloc_get_type(ctx, struct sbus_talloc_msg);
|
|
|
b2d430 |
+
|
|
|
b2d430 |
+ dbus_message_free_data_slot(&talloc_msg->data_slot);
|
|
|
b2d430 |
+
|
|
|
b2d430 |
+ if (!talloc_msg->in_talloc_destructor) {
|
|
|
b2d430 |
+ /* References to this message dropped to zero but through
|
|
|
b2d430 |
+ * dbus_message_unref(), not by calling talloc_free(). We need to free
|
|
|
b2d430 |
+ * the talloc context and avoid running talloc desctuctor. */
|
|
|
b2d430 |
+ talloc_set_destructor(talloc_msg, NULL);
|
|
|
b2d430 |
+ talloc_free(talloc_msg);
|
|
|
b2d430 |
+ }
|
|
|
b2d430 |
+}
|
|
|
b2d430 |
+
|
|
|
b2d430 |
errno_t sbus_talloc_bound_message(TALLOC_CTX *mem_ctx, DBusMessage *msg)
|
|
|
b2d430 |
{
|
|
|
b2d430 |
struct sbus_talloc_msg *talloc_msg;
|
|
|
b2d430 |
+ dbus_int32_t data_slot = -1;
|
|
|
b2d430 |
+ DBusFreeFunction free_fn;
|
|
|
b2d430 |
+ dbus_bool_t bret;
|
|
|
b2d430 |
|
|
|
b2d430 |
+ /* Create a talloc context that will unreference this message when
|
|
|
b2d430 |
+ * the parent context is freed. */
|
|
|
b2d430 |
talloc_msg = talloc(mem_ctx, struct sbus_talloc_msg);
|
|
|
b2d430 |
if (talloc_msg == NULL) {
|
|
|
b2d430 |
DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
b2d430 |
@@ -48,7 +78,28 @@ errno_t sbus_talloc_bound_message(TALLOC_CTX *mem_ctx, DBusMessage *msg)
|
|
|
b2d430 |
return ENOMEM;
|
|
|
b2d430 |
}
|
|
|
b2d430 |
|
|
|
b2d430 |
+ /* Allocate a dbus message data slot that will contain point to the
|
|
|
b2d430 |
+ * talloc context so we can pick up cases when the dbus message is
|
|
|
b2d430 |
+ * freed through dbus api. */
|
|
|
b2d430 |
+ bret = dbus_message_allocate_data_slot(&data_slot);
|
|
|
b2d430 |
+ if (!bret) {
|
|
|
b2d430 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to allocate data slot!\n");
|
|
|
b2d430 |
+ talloc_free(talloc_msg);
|
|
|
b2d430 |
+ return ENOMEM;
|
|
|
b2d430 |
+ }
|
|
|
b2d430 |
+
|
|
|
b2d430 |
+ free_fn = sbus_msg_data_destructor;
|
|
|
b2d430 |
+ bret = dbus_message_set_data(msg, data_slot, talloc_msg, free_fn);
|
|
|
b2d430 |
+ if (!bret) {
|
|
|
b2d430 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set message data!\n");
|
|
|
b2d430 |
+ talloc_free(talloc_msg);
|
|
|
b2d430 |
+ dbus_message_free_data_slot(&data_slot);
|
|
|
b2d430 |
+ return ENOMEM;
|
|
|
b2d430 |
+ }
|
|
|
b2d430 |
+
|
|
|
b2d430 |
talloc_msg->msg = msg;
|
|
|
b2d430 |
+ talloc_msg->data_slot = data_slot;
|
|
|
b2d430 |
+ talloc_msg->in_talloc_destructor = false;
|
|
|
b2d430 |
|
|
|
b2d430 |
talloc_set_destructor(talloc_msg, sbus_talloc_msg_destructor);
|
|
|
b2d430 |
|
|
|
b2d430 |
--
|
|
|
b2d430 |
2.4.11
|
|
|
b2d430 |
|