[Pkg-telepathy-maintainers] Bug#495199: telepathy-haze: often crashes on connection errors, such as an incorrect password
Will Thompson
will at willthompson.co.uk
Fri Aug 15 09:43:17 UTC 2008
Package: telepathy-haze
Version: 0.2.0-1
Severity: important
Tags: patch
The currently released version of telepathy-haze may access (and
possibly try to free) already-released memory after a connection error
occurs. This will be fixed in the next release, but the attached patch
fixes the problem with only a few lines of non-boilerplate and -comment
code. (It replaces using a flag in libpurple which does not actually
have the right semantics with a new flag which does.)
It would be great if this could make it into Lenny!
Thanks,
Will
-- System Information:
Debian Release: lenny/sid
APT prefers testing
APT policy: (900, 'testing'), (800, 'unstable'), (700, 'experimental')
Architecture: i386 (i686)
Kernel: Linux 2.6.25-2-686 (SMP w/1 CPU core)
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash
-------------- next part --------------
commit 41a82cc4e33b646630203223c204ace8ae1d9f49
Author: Will Thompson <will.thompson at collabora.co.uk>
Date: Thu Aug 14 11:37:38 2008 +0100
Keep track of whether purple_account_disconnect needs to be called.
This fixes #14933. When libpurple reports a connection error, it
schedules an idle callback for purple_account_disconnect. Haze's
implementation of TpBaseConnection->shut_down checked
PurpleAccount->disconnecting before calling purple_account_disconnect,
but that flag is only set once purple_account_disconnect is actually
called. So purple_account_disconnect would be called twice, and if you
got unlucky the account have been freed before the second call, causing
catastrophe.
---
src/connection.c | 24 +++++++++++++++++++++++-
1 files changed, 23 insertions(+), 1 deletions(-)
diff --git a/src/connection.c b/src/connection.c
index 14a1051..c0863e1 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -63,6 +63,11 @@ typedef struct _HazeConnectionPrivate
HazeProtocolInfo *protocol_info;
+ /* Set if purple_account_disconnect has been called or is scheduled to be
+ * called, so should not be called again.
+ */
+ gboolean disconnecting;
+
gboolean dispose_has_run;
} HazeConnectionPrivate;
@@ -115,10 +120,17 @@ haze_report_disconnect_reason (PurpleConnection *gc,
const char *text)
{
PurpleAccount *account = purple_connection_get_account (gc);
+ HazeConnection *conn = ACCOUNT_GET_HAZE_CONNECTION (account);
+ HazeConnectionPrivate *priv = HAZE_CONNECTION_GET_PRIVATE (conn);
TpBaseConnection *base_conn = ACCOUNT_GET_TP_BASE_CONNECTION (account);
TpConnectionStatusReason tp_reason;
+ /* When a connection error is reported by libpurple, an idle callback to
+ * purple_account_disconnect is added.
+ */
+ priv->disconnecting = TRUE;
+
switch (reason)
{
case PURPLE_CONNECTION_ERROR_NETWORK_ERROR:
@@ -196,8 +208,12 @@ void
disconnected_cb (PurpleConnection *pc)
{
PurpleAccount *account = purple_connection_get_account (pc);
+ HazeConnection *conn = ACCOUNT_GET_HAZE_CONNECTION (account);
+ HazeConnectionPrivate *priv = HAZE_CONNECTION_GET_PRIVATE (conn);
TpBaseConnection *base_conn = ACCOUNT_GET_TP_BASE_CONNECTION (account);
+ priv->disconnecting = TRUE;
+
if(base_conn->status != TP_CONNECTION_STATUS_DISCONNECTED)
{
tp_base_connection_change_status (base_conn,
@@ -326,8 +342,12 @@ static void
_haze_connection_shut_down (TpBaseConnection *base)
{
HazeConnection *self = HAZE_CONNECTION(base);
- if(!self->account->disconnecting)
+ HazeConnectionPrivate *priv = HAZE_CONNECTION_GET_PRIVATE (self);
+ if(!priv->disconnecting)
+ {
+ priv->disconnecting = TRUE;
purple_account_disconnect(self->account);
+ }
}
/* Must be in the same order as HazeListHandle in connection.h */
@@ -452,6 +472,8 @@ haze_connection_constructor (GType type,
priv->dispose_has_run = FALSE;
+ priv->disconnecting = FALSE;
+
_create_account (self);
return (GObject *)self;
More information about the Pkg-telepathy-maintainers
mailing list