Mercurial > pidgin.yaz
comparison libpurple/protocols/msn/slplink.c @ 30174: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
30173:4ebecacf2fbb | 30174: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 { |