[libgnome-keyring] Fix issue where an operation could be cancelled or completed twice
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgnome-keyring] Fix issue where an operation could be cancelled or completed twice
- Date: Tue, 31 Jan 2012 12:50:14 +0000 (UTC)
commit 627895abba1b34fbd436968f775134cc5f62754c
Author: Stef Walter <stefw gnome org>
Date: Tue Jan 31 13:46:03 2012 +0100
Fix issue where an operation could be cancelled or completed twice
* Ensure that an operation can only be completed or cancelled
once. Depending on circumstances, this could cause access
to freed memory.
library/gkr-callback.c | 21 ++++++++++++++++-----
library/gkr-callback.h | 3 +++
library/gkr-operation.c | 12 +++++++-----
3 files changed, 26 insertions(+), 10 deletions(-)
---
diff --git a/library/gkr-callback.c b/library/gkr-callback.c
index 5c45d22..acaa705 100644
--- a/library/gkr-callback.c
+++ b/library/gkr-callback.c
@@ -96,16 +96,27 @@ gkr_callback_invoke_op_string (GkrCallback *cb, const gchar *value)
}
void
-gkr_callback_invoke_res (GkrCallback *cb, GnomeKeyringResult res)
+gkr_callback_invoke_res (GkrCallback *cb,
+ GnomeKeyringResult res)
{
- gint type;
-
- g_assert (cb);
- g_assert (cb->callback);
+ g_assert (cb != NULL);
+ g_assert (cb->callback != NULL);
if (cb->operation && !gkr_operation_set_result (cb->operation, res))
return;
+ gkr_callback_invoke_bare (cb, res);
+}
+
+void
+gkr_callback_invoke_bare (GkrCallback *cb,
+ GnomeKeyringResult res)
+{
+ gint type;
+
+ g_assert (cb != NULL);
+ g_assert (cb->callback != NULL);
+
/* When successful can only call one kind of callback */
if (res == GNOME_KEYRING_RESULT_OK) {
g_assert (cb->type == GKR_CALLBACK_RES);
diff --git a/library/gkr-callback.h b/library/gkr-callback.h
index 1c66cbf..bec9440 100644
--- a/library/gkr-callback.h
+++ b/library/gkr-callback.h
@@ -74,6 +74,9 @@ void gkr_callback_invoke_op_session (GkrCallback *cb,
void gkr_callback_invoke_op_string (GkrCallback *cb,
const gchar *value);
+void gkr_callback_invoke_bare (GkrCallback *cb,
+ GnomeKeyringResult res);
+
void gkr_callback_invoke_res (GkrCallback *cb,
GnomeKeyringResult res);
diff --git a/library/gkr-operation.c b/library/gkr-operation.c
index d3792b3..fc3ecc9 100644
--- a/library/gkr-operation.c
+++ b/library/gkr-operation.c
@@ -218,8 +218,7 @@ gkr_operation_set_result (GkrOperation *op, GnomeKeyringResult res)
{
g_assert (op);
g_assert ((int) res != INCOMPLETE);
- g_atomic_int_compare_and_exchange (&op->result, INCOMPLETE, res);
- return g_atomic_int_get (&op->result) == res; /* Success when already set to res */
+ return g_atomic_int_compare_and_exchange (&op->result, INCOMPLETE, res);
}
static void
@@ -237,7 +236,7 @@ on_complete (GkrOperation *op)
/* Free all the other callbacks */
operation_clear_callbacks (op);
- gkr_callback_invoke_res (cb, gkr_operation_get_result (op));
+ gkr_callback_invoke_bare (cb, gkr_operation_get_result (op));
gkr_callback_free (cb);
}
@@ -366,8 +365,8 @@ callback_with_message (GkrOperation *op, DBusMessage *message)
{
GkrCallback *cb;
- g_assert (op);
- g_assert (message);
+ g_assert (op != NULL);
+ g_assert (message != NULL);
cb = g_queue_peek_head (&op->callbacks);
g_assert (cb);
@@ -390,6 +389,9 @@ on_pending_call_notify (DBusPendingCall *pending, void *user_data)
gkr_debug ("%p: notified: %p", op, pending);
g_assert (pending == op->pending);
+ if ((int) gkr_operation_get_result (op) != INCOMPLETE)
+ return;
+
reply = dbus_pending_call_steal_reply (pending);
g_return_if_fail (reply);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]