pidgin: 337967ea: Fix a possible use-after-free.
qulogic at pidgin.im
qulogic at pidgin.im
Mon Apr 19 20:10:56 EDT 2010
-----------------------------------------------------------------
Revision: 337967ea94c0d00f8a069e94718933d47a9d9c80
Ancestor: a9383bb27d9c9dc76837b30e02e50fbc03686fa5
Author: qulogic at pidgin.im
Date: 2010-04-20T00:05:34
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/337967ea94c0d00f8a069e94718933d47a9d9c80
Modified files:
libpurple/protocols/msn/msn.c
libpurple/protocols/msn/slplink.c
libpurple/protocols/msn/slplink.h
ChangeLog:
Fix a possible use-after-free.
If the user initiated a file transfer while a display pic transfer was in
progress, and that transfer finished before the user selected a file, then
the MsnSlpLink to that user could be used after it's freed. Also, if there
were a conversation open to that user, then the slplink would not be
freed, so the FT must be started from the buddy list.
Fixes #6453.
-------------- next part --------------
============================================================
--- libpurple/protocols/msn/msn.c 0205dcf3d844d78a817d199f83932331bcd4f41c
+++ libpurple/protocols/msn/msn.c 1f196cd3ab1a5d239bb9d1cb00f7c5626ce6b951
@@ -589,8 +589,16 @@ t_msn_xfer_init(PurpleXfer *xfer)
{
MsnSlpLink *slplink = xfer->data;
msn_slplink_request_ft(slplink, xfer);
+ msn_slplink_unref(slplink);
}
+static void
+t_msn_xfer_cancel_send(PurpleXfer *xfer)
+{
+ MsnSlpLink *slplink = xfer->data;
+ msn_slplink_unref(slplink);
+}
+
static PurpleXfer*
msn_new_xfer(PurpleConnection *gc, const char *who)
{
@@ -603,9 +611,10 @@ msn_new_xfer(PurpleConnection *gc, const
g_return_val_if_fail(xfer != NULL, NULL);
- xfer->data = msn_session_get_slplink(session, who);
+ xfer->data = msn_slplink_ref(msn_session_get_slplink(session, who));
purple_xfer_set_init_fnc(xfer, t_msn_xfer_init);
+ purple_xfer_set_cancel_send_fnc(xfer, t_msn_xfer_cancel_send);
return xfer;
}
============================================================
--- libpurple/protocols/msn/slplink.c d4aefb42cb2a3334a2dda05c1e016848f7484141
+++ libpurple/protocols/msn/slplink.c a19cf8f9a0e609e5e57e127eeaedbc62fef6a1a9
@@ -78,7 +78,7 @@ msn_slplink_new(MsnSession *session, con
session->slplinks =
g_list_append(session->slplinks, slplink);
- return slplink;
+ return msn_slplink_ref(slplink);
}
void
@@ -94,6 +94,11 @@ msn_slplink_destroy(MsnSlpLink *slplink)
if (slplink->swboard != NULL)
slplink->swboard->slplinks = g_list_remove(slplink->swboard->slplinks, slplink);
+ if (slplink->refs > 1) {
+ slplink->refs--;
+ return;
+ }
+
session = slplink->session;
#if 0
@@ -115,6 +120,31 @@ MsnSlpLink *
}
MsnSlpLink *
+msn_slplink_ref(MsnSlpLink *slplink)
+{
+ g_return_val_if_fail(slplink != NULL, NULL);
+
+ slplink->refs++;
+ if (purple_debug_is_verbose())
+ purple_debug_info("msn", "slplink ref (%p)[%d]\n", slplink, slplink->refs);
+
+ return slplink;
+}
+
+void
+msn_slplink_unref(MsnSlpLink *slplink)
+{
+ g_return_if_fail(slplink != NULL);
+
+ slplink->refs--;
+ if (purple_debug_is_verbose())
+ purple_debug_info("msn", "slplink unref (%p)[%d]\n", slplink, slplink->refs);
+
+ if (slplink->refs == 0)
+ msn_slplink_destroy(slplink);
+}
+
+MsnSlpLink *
msn_session_find_slplink(MsnSession *session, const char *who)
{
GList *l;
============================================================
--- libpurple/protocols/msn/slplink.h 45e42061dd6c5fa0c89c80de95eea64a23a09fab
+++ libpurple/protocols/msn/slplink.h 5b5b693c7e8847dfa1a81b2da6b03a9fcc7dcffc
@@ -43,6 +43,8 @@ struct _MsnSlpLink
MsnSession *session;
MsnSwitchBoard *swboard;
+ int refs;
+
char *remote_user;
int slp_seq_id;
@@ -55,6 +57,9 @@ struct _MsnSlpLink
GQueue *slp_msg_queue;
};
+MsnSlpLink *msn_slplink_ref(MsnSlpLink *slplink);
+void msn_slplink_unref(MsnSlpLink *slplink);
+
void msn_slplink_destroy(MsnSlpLink *slplink);
/**
More information about the Commits
mailing list