~network-manager/network-manager/ubuntu.hardy-backports.07

« back to all changes in this revision

Viewing changes to debian/patches/80_lp259503_access_to_freed_device_struct.patch

(merge 2892 from lp:~network-manager/network-manager/ubuntu.0.7)
  * fix LP: #xxxx - "network manager always crashes on resume"; these crashes
    are a regression introduced by fix for LP: #259503 which was first
    released in 0.7~~svn20080908t183521+eni0-0ubuntu1. To fix we redo the patch
    in a way that will eliminate any idle callbacks as soon as they
    become irrelevant.
    - update debian/patches/80_lp259503_access_to_freed_device_struct.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
=== modified file 'src/nm-device-wifi.c'
2
2
---
3
 
 src/nm-device-ethernet.c |    4 ++--
4
 
 src/nm-device-wifi.c     |    4 ++--
5
 
 2 files changed, 4 insertions(+), 4 deletions(-)
 
3
 src/nm-device-ethernet.c |   40 +++++++++++++++++++++++++++++++++++++---
 
4
 src/nm-device-wifi.c     |   34 +++++++++++++++++++++++++++++++++-
 
5
 2 files changed, 70 insertions(+), 4 deletions(-)
6
6
 
7
 
Index: network-manager.07.ubuntu/src/nm-device-wifi.c
 
7
Index: network-manager.ubuntu.07/src/nm-device-wifi.c
8
8
===================================================================
9
 
--- network-manager.07.ubuntu.orig/src/nm-device-wifi.c
10
 
+++ network-manager.07.ubuntu/src/nm-device-wifi.c
11
 
@@ -2097,21 +2097,21 @@
12
 
 
 
9
--- network-manager.ubuntu.07.orig/src/nm-device-wifi.c
 
10
+++ network-manager.ubuntu.07/src/nm-device-wifi.c
 
11
@@ -148,16 +148,18 @@
 
12
        guint               pending_scan_id;
 
13
 
 
14
        Supplicant          supplicant;
 
15
 
 
16
        guint32             failed_link_count;
 
17
        guint               periodic_source_id;
 
18
        guint               link_timeout_id;
 
19
 
 
20
+       GSList *        timeouts;
 
21
+
 
22
        /* Static options from driver */
 
23
        guint8                  we_version;
 
24
        guint32                 capabilities;
 
25
        gboolean                has_scan_capa_ssid;
 
26
 };
 
27
 
 
28
 static guint32 nm_device_wifi_get_frequency (NMDeviceWifi *self);
 
29
 
 
30
@@ -2074,44 +2076,54 @@
 
31
        return FALSE;
 
32
 }
 
33
 
 
34
 
 
35
 struct state_cb_data {
 
36
        NMDeviceWifi * self;
 
37
        guint32 new_state;
 
38
        guint32 old_state;
 
39
+       guint source_id;
 
40
+       GSList *source_link;
 
41
 };
 
42
 
 
43
 static gboolean
 
44
 schedule_state_handler (NMDeviceWifi * self,
 
45
                         GSourceFunc handler,
 
46
                         guint32 new_state,
 
47
                         guint32 old_state)
 
48
 {
 
49
        struct state_cb_data * cb_data;
 
50
+       NMDeviceWifiPrivate *priv;
 
51
 
 
52
        g_return_val_if_fail (self != NULL, FALSE);
 
53
        g_return_val_if_fail (handler != NULL, FALSE);
 
54
 
 
55
        if (new_state == old_state)
 
56
                return TRUE;
 
57
 
 
58
+       priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
 
59
+
13
60
        cb_data = g_slice_new0 (struct state_cb_data);
14
61
        if (cb_data == NULL) {
15
62
                nm_warning ("Not enough memory to process supplicant manager state"
17
64
                return FALSE;
18
65
        }
19
66
 
20
 
-       cb_data->self = self;
21
 
+       cb_data->self = g_object_ref (self);
 
67
        cb_data->self = self;
22
68
        cb_data->new_state = new_state;
23
69
        cb_data->old_state = old_state;
24
70
 
25
71
-       g_idle_add (handler, cb_data);
26
 
+       g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, handler, cb_data, g_object_unref);
 
72
+       cb_data->source_id = g_idle_add (handler, cb_data);
 
73
+       
 
74
+       if(cb_data->source_id > 0) {
 
75
+               priv->timeouts = g_slist_append(priv->timeouts, GUINT_TO_POINTER(cb_data->source_id));
 
76
+               cb_data->source_link = priv->timeouts;
 
77
+       }
27
78
 
28
79
        return TRUE;
29
80
 }
32
83
 supplicant_iface_state_cb_handler (gpointer user_data)
33
84
 {
34
85
        struct state_cb_data *cb_data = (struct state_cb_data *) user_data;
35
 
Index: network-manager.07.ubuntu/src/nm-device-ethernet.c
 
86
@@ -2138,16 +2150,19 @@
 
87
                cancel_pending_scan (self);
 
88
                request_wireless_scan (self);
 
89
        } else if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) {
 
90
                cleanup_association_attempt (self, FALSE);
 
91
                supplicant_interface_release (self);
 
92
                nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_UNAVAILABLE,
 
93
                                         NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
 
94
        }
 
95
+
 
96
+       g_source_remove (cb_data->source_id);
 
97
+       priv->timeouts = g_slist_remove_link (priv->timeouts, cb_data->source_link);
 
98
        
 
99
        g_slice_free (struct state_cb_data, cb_data);
 
100
        return FALSE;
 
101
 }
 
102
 
 
103
 
 
104
 static void
 
105
 supplicant_iface_state_cb (NMSupplicantInterface * iface,
 
106
@@ -2210,16 +2225,19 @@
 
107
                        if (!priv->link_timeout_id) {
 
108
                                priv->link_timeout_id = g_timeout_add (priv->scanning ? 30000 : 15000,
 
109
                                                                       link_timeout_cb, self);
 
110
                        }
 
111
                }
 
112
        }
 
113
 
 
114
 out:
 
115
+       g_source_remove (cb_data->source_id);
 
116
+       priv->timeouts = g_slist_remove_link (priv->timeouts, cb_data->source_link);
 
117
+
 
118
        g_slice_free (struct state_cb_data, cb_data);
 
119
        return FALSE;
 
120
 }
 
121
 
 
122
 
 
123
 static void
 
124
 supplicant_iface_connection_state_cb (NMSupplicantInterface * iface,
 
125
                                       guint32 new_state,
 
126
@@ -2282,16 +2300,19 @@
 
127
                         */
 
128
                        if (priv->supplicant.iface) {
 
129
                                nm_device_state_changed (dev, NM_DEVICE_STATE_DISCONNECTED,
 
130
                                                         NM_DEVICE_STATE_REASON_NONE);
 
131
                        }
 
132
                }
 
133
        }
 
134
 
 
135
+       g_source_remove (cb_data->source_id);
 
136
+       priv->timeouts = g_slist_remove_link (priv->timeouts, cb_data->source_link);
 
137
+
 
138
        g_slice_free (struct state_cb_data, cb_data);
 
139
        return FALSE;
 
140
 }
 
141
 
 
142
 static void
 
143
 supplicant_mgr_state_cb (NMSupplicantInterface * iface,
 
144
                          guint32 new_state,
 
145
                          guint32 old_state,
 
146
@@ -3071,16 +3092,21 @@
 
147
 
 
148
 
 
149
 static guint32
 
150
 real_get_type_capabilities (NMDevice *dev)
 
151
 {
 
152
        return NM_DEVICE_WIFI_GET_PRIVATE (dev)->capabilities;
 
153
 }
 
154
 
 
155
+static void
 
156
+remove_source_id_pointer (gpointer id, gpointer data)
 
157
+{
 
158
+       g_source_remove (GPOINTER_TO_UINT(id));
 
159
+}
 
160
 
 
161
 static void
 
162
 nm_device_wifi_dispose (GObject *object)
 
163
 {
 
164
        NMDeviceWifi *self = NM_DEVICE_WIFI (object);
 
165
        NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
 
166
 
 
167
        if (priv->dispose_has_run) {
 
168
@@ -3090,16 +3116,22 @@
 
169
 
 
170
        priv->dispose_has_run = TRUE;
 
171
 
 
172
        if (priv->periodic_source_id) {
 
173
                g_source_remove (priv->periodic_source_id);
 
174
                priv->periodic_source_id = 0;
 
175
        }
 
176
 
 
177
+       if (priv->timeouts) {
 
178
+               g_slist_foreach(priv->timeouts, remove_source_id_pointer, NULL);
 
179
+               g_slist_free(priv->timeouts);
 
180
+               priv->timeouts = NULL;
 
181
+       }
 
182
+
 
183
        cleanup_association_attempt (self, TRUE);
 
184
        supplicant_interface_release (self);
 
185
 
 
186
        if (priv->supplicant.mgr_state_id) {
 
187
                g_signal_handler_disconnect (priv->supplicant.mgr, priv->supplicant.mgr_state_id);
 
188
                priv->supplicant.mgr_state_id = 0;
 
189
        }
 
190
 
 
191
Index: network-manager.ubuntu.07/src/nm-device-ethernet.c
36
192
===================================================================
37
 
--- network-manager.07.ubuntu.orig/src/nm-device-ethernet.c
38
 
+++ network-manager.07.ubuntu/src/nm-device-ethernet.c
39
 
@@ -766,21 +766,21 @@
 
193
--- network-manager.ubuntu.07.orig/src/nm-device-ethernet.c
 
194
+++ network-manager.ubuntu.07/src/nm-device-ethernet.c
 
195
@@ -94,16 +94,19 @@
 
196
 
 
197
        char *                  carrier_file_path;
 
198
        gulong                  link_connected_id;
 
199
        gulong                  link_disconnected_id;
 
200
 
 
201
        Supplicant          supplicant;
 
202
        guint               link_timeout_id;
 
203
 
 
204
+       /* state handler timeout source ids */
 
205
+       GSList *        timeouts;
 
206
+
 
207
        /* PPPoE */
 
208
        NMPPPManager *ppp_manager;
 
209
        NMIP4Config  *pending_ip4_config;
 
210
 } NMDeviceEthernetPrivate;
 
211
 
 
212
 enum {
 
213
        PROPERTIES_CHANGED,
 
214
 
 
215
@@ -752,55 +755,69 @@
 
216
 
 
217
        return FALSE;
 
218
 }
 
219
 
 
220
 struct state_cb_data {
 
221
        NMDeviceEthernet *self;
 
222
        guint32 new_state;
 
223
        guint32 old_state;
 
224
+       guint source_id;
 
225
+       GSList *source_link;
 
226
 };
 
227
 
 
228
 static gboolean
 
229
 schedule_state_handler (NMDeviceEthernet *self,
 
230
                         GSourceFunc handler,
 
231
                         guint32 new_state,
40
232
                         guint32 old_state)
41
233
 {
42
234
        struct state_cb_data * cb_data;
 
235
+       NMDeviceEthernetPrivate *priv;
43
236
 
44
237
        if (new_state == old_state)
45
238
                return TRUE;
46
239
 
 
240
+       priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
 
241
+
47
242
        cb_data = g_slice_new0 (struct state_cb_data);
48
 
-       cb_data->self = self;
49
 
+       cb_data->self = g_object_ref(self);
 
243
        cb_data->self = self;
50
244
        cb_data->new_state = new_state;
51
245
        cb_data->old_state = old_state;
52
246
 
53
247
-       g_idle_add (handler, cb_data);
54
 
+       g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, handler, cb_data, g_object_unref);
 
248
+       cb_data->source_id = g_idle_add (handler, cb_data);
 
249
+       
 
250
+       if(cb_data->source_id > 0) {
 
251
+               priv->timeouts = g_slist_append(priv->timeouts, GUINT_TO_POINTER(cb_data->source_id));
 
252
+               cb_data->source_link = priv->timeouts;
 
253
+       }
55
254
 
56
255
        return TRUE;
57
256
 }
60
259
 supplicant_mgr_state_cb_handler (gpointer user_data)
61
260
 {
62
261
        struct state_cb_data *info = (struct state_cb_data *) user_data;
 
262
        NMDevice *device = NM_DEVICE (info->self);
 
263
+       NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (info->self);
 
264
 
 
265
        /* If the supplicant went away, release the supplicant interface */
 
266
        if (info->new_state == NM_SUPPLICANT_MANAGER_STATE_DOWN) {
 
267
                supplicant_interface_clean (info->self);
 
268
 
 
269
                if (nm_device_get_state (device) > NM_DEVICE_STATE_UNAVAILABLE) {
 
270
                        nm_device_state_changed (device, NM_DEVICE_STATE_UNAVAILABLE,
 
271
                                                 NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
 
272
                }
 
273
        }
 
274
 
 
275
+       g_source_remove (info->source_id);
 
276
+       priv->timeouts = g_slist_remove_link (priv->timeouts, info->source_link);
 
277
+
 
278
        g_slice_free (struct state_cb_data, info);
 
279
 
 
280
        return FALSE;
 
281
 }
 
282
 
 
283
 static void
 
284
 supplicant_mgr_state_cb (NMSupplicantInterface * iface,
 
285
                          guint32 new_state,
 
286
@@ -874,16 +891,19 @@
 
287
                NMDeviceState state = nm_device_get_state (device);
 
288
 
 
289
                supplicant_interface_clean (info->self);
 
290
 
 
291
                if (nm_device_is_activating (device) || state == NM_DEVICE_STATE_ACTIVATED)
 
292
                        nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
 
293
        }
 
294
 
 
295
+       g_source_remove (info->source_id);
 
296
+       priv->timeouts = g_slist_remove_link (priv->timeouts, info->source_link);
 
297
+
 
298
        g_slice_free (struct state_cb_data, info);
 
299
 
 
300
        return FALSE;
 
301
 }
 
302
 
 
303
 static void
 
304
 supplicant_iface_state_cb (NMSupplicantInterface * iface,
 
305
                            guint32 new_state,
 
306
@@ -902,39 +922,41 @@
 
307
                                old_state);
 
308
 }
 
309
 
 
310
 static gboolean
 
311
 supplicant_iface_connection_state_cb_handler (gpointer user_data)
 
312
 {
 
313
        struct state_cb_data *info = (struct state_cb_data *) user_data;
 
314
        NMDevice *dev = NM_DEVICE (info->self);
 
315
+       NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (info->self);
 
316
 
 
317
        if (info->new_state == NM_SUPPLICANT_INTERFACE_CON_STATE_COMPLETED) {
 
318
                remove_supplicant_interface_connection_error_handler (info->self);
 
319
                remove_supplicant_timeouts (info->self);
 
320
 
 
321
                /* If this is the initial association during device activation,
 
322
                 * schedule the next activation stage.
 
323
                 */
 
324
                if (nm_device_get_state (dev) == NM_DEVICE_STATE_CONFIG) {
 
325
                        nm_info ("Activation (%s/wired) Stage 2 of 5 (Device Configure) successful.",
 
326
                                    nm_device_get_iface (dev));
 
327
                        nm_device_activate_schedule_stage3_ip_config_start (dev);
 
328
                }
 
329
        } else if (info->new_state == NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED) {
 
330
                if (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED || nm_device_is_activating (dev)) {
 
331
-                       NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (info->self);
 
332
-
 
333
                        /* Start the link timeout so we allow some time for reauthentication */
 
334
                        if (!priv->link_timeout_id)
 
335
                                priv->link_timeout_id = g_timeout_add (15000, link_timeout_cb, dev);
 
336
                }
 
337
        }
 
338
 
 
339
+       g_source_remove (info->source_id);
 
340
+       priv->timeouts = g_slist_remove_link (priv->timeouts, info->source_link);
 
341
+
 
342
        g_slice_free (struct state_cb_data, info);
 
343
 
 
344
        return FALSE;
 
345
 }
 
346
 
 
347
 static void
 
348
 supplicant_iface_connection_state_cb (NMSupplicantInterface * iface,
 
349
                                       guint32 new_state,
 
350
@@ -1337,28 +1359,40 @@
 
351
        }
 
352
 
 
353
        // FIXME: check bitrate against device capabilities
 
354
 
 
355
        return TRUE;
 
356
 }
 
357
 
 
358
 static void
 
359
+remove_source_id_pointer (gpointer id, gpointer data)
 
360
+{
 
361
+       g_source_remove (GPOINTER_TO_UINT(id));
 
362
+}
 
363
+
 
364
+static void
 
365
 nm_device_ethernet_dispose (GObject *object)
 
366
 {
 
367
        NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (object);
 
368
        NMNetlinkMonitor *monitor;
 
369
 
 
370
        if (priv->dispose_has_run) {
 
371
                G_OBJECT_CLASS (nm_device_ethernet_parent_class)->dispose (object);
 
372
                return;
 
373
        }
 
374
 
 
375
        priv->dispose_has_run = TRUE;
 
376
 
 
377
+       if (priv->timeouts) {
 
378
+               g_slist_foreach(priv->timeouts, remove_source_id_pointer, NULL);
 
379
+               g_slist_free(priv->timeouts);
 
380
+               priv->timeouts = NULL;
 
381
+       }
 
382
+
 
383
        monitor = nm_netlink_monitor_get ();
 
384
        if (priv->link_connected_id) {
 
385
                g_signal_handler_disconnect (monitor, priv->link_connected_id);
 
386
                priv->link_connected_id = 0;
 
387
        }
 
388
        if (priv->link_disconnected_id) {
 
389
                g_signal_handler_disconnect (monitor, priv->link_disconnected_id);
 
390
                priv->link_disconnected_id = 0;