comparison libpurple/protocols/msn/slplink.c @ 29762:b0bc67f42027

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.
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Tue, 20 Apr 2010 00:05:34 +0000
parents a0adf0bb19b7
children 2ab17571bf42 31f20c9c7674 7a26ff6c0044
comparison
equal deleted inserted replaced
29761:4ebecacf2fbb 29762:b0bc67f42027
76 slplink->slp_msg_queue = g_queue_new(); 76 slplink->slp_msg_queue = g_queue_new();
77 77
78 session->slplinks = 78 session->slplinks =
79 g_list_append(session->slplinks, slplink); 79 g_list_append(session->slplinks, slplink);
80 80
81 return slplink; 81 return msn_slplink_ref(slplink);
82 } 82 }
83 83
84 void 84 void
85 msn_slplink_destroy(MsnSlpLink *slplink) 85 msn_slplink_destroy(MsnSlpLink *slplink)
86 { 86 {
91 91
92 g_return_if_fail(slplink != NULL); 92 g_return_if_fail(slplink != NULL);
93 93
94 if (slplink->swboard != NULL) 94 if (slplink->swboard != NULL)
95 slplink->swboard->slplinks = g_list_remove(slplink->swboard->slplinks, slplink); 95 slplink->swboard->slplinks = g_list_remove(slplink->swboard->slplinks, slplink);
96
97 if (slplink->refs > 1) {
98 slplink->refs--;
99 return;
100 }
96 101
97 session = slplink->session; 102 session = slplink->session;
98 103
99 #if 0 104 #if 0
100 if (slplink->directconn != NULL) 105 if (slplink->directconn != NULL)
110 g_list_remove(session->slplinks, slplink); 115 g_list_remove(session->slplinks, slplink);
111 116
112 g_free(slplink->remote_user); 117 g_free(slplink->remote_user);
113 118
114 g_free(slplink); 119 g_free(slplink);
120 }
121
122 MsnSlpLink *
123 msn_slplink_ref(MsnSlpLink *slplink)
124 {
125 g_return_val_if_fail(slplink != NULL, NULL);
126
127 slplink->refs++;
128 if (purple_debug_is_verbose())
129 purple_debug_info("msn", "slplink ref (%p)[%d]\n", slplink, slplink->refs);
130
131 return slplink;
132 }
133
134 void
135 msn_slplink_unref(MsnSlpLink *slplink)
136 {
137 g_return_if_fail(slplink != NULL);
138
139 slplink->refs--;
140 if (purple_debug_is_verbose())
141 purple_debug_info("msn", "slplink unref (%p)[%d]\n", slplink, slplink->refs);
142
143 if (slplink->refs == 0)
144 msn_slplink_destroy(slplink);
115 } 145 }
116 146
117 MsnSlpLink * 147 MsnSlpLink *
118 msn_session_find_slplink(MsnSession *session, const char *who) 148 msn_session_find_slplink(MsnSession *session, const char *who)
119 { 149 {