On Wed, 2016-05-04 at 17:27 +0800, Shih-Yuan Lee (FourDollars) wrote:
--- src/devices/nm-device.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index ad6f835..77f8874 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -1990,8 +1990,8 @@ realize_start_setup (NMDevice *self, const NMPlatformLink *plink) } /* trigger initial ip config change to initialize ip-config */ - priv->queued_ip4_config_id = g_idle_add (queued_ip4_config_change, self); - priv->queued_ip6_config_id = g_idle_add (queued_ip6_config_change, self); + priv->queued_ip4_config_id = g_idle_add (queued_ip4_config_change, g_object_ref (self)); + priv->queued_ip6_config_id = g_idle_add (queued_ip6_config_change, g_object_ref (self)); nm_device_update_hw_address (self); nm_device_update_initial_hw_address (self); @@ -6982,6 +6982,7 @@ queued_ip4_config_change_clear (NMDevice *self) _LOGD (LOGD_DEVICE, "clearing queued IP4 config change"); g_source_remove (priv->queued_ip4_config_id); priv->queued_ip4_config_id = 0; + g_object_unref (self); } } @@ -6994,6 +6995,7 @@ queued_ip6_config_change_clear (NMDevice *self) _LOGD (LOGD_DEVICE, "clearing queued IP6 config change"); g_source_remove (priv->queued_ip6_config_id); priv->queued_ip6_config_id = 0; + g_object_unref (self); } } @@ -8942,7 +8944,11 @@ update_ip4_config (NMDevice *self, gboolean initial) if (activation_source_is_scheduled (self, activate_stage5_ip4_conf ig_commit, AF_INET)) { - priv->queued_ip4_config_id = g_idle_add (queued_ip4_config_change, self); + if (priv->queued_ip4_config_id) { + g_source_remove (priv-queued_ip4_config_id);+ g_object_unref (self); + } + priv->queued_ip4_config_id = g_idle_add (queued_ip4_config_change, g_object_ref (self)); _LOGT (LOGD_DEVICE, "IP4 update was postponed"); return; } @@ -9031,7 +9037,11 @@ update_ip6_config (NMDevice *self, gboolean initial) if (activation_source_is_scheduled (self, activate_stage5_ip6_conf ig_commit, AF_INET6)) { - priv->queued_ip6_config_id = g_idle_add (queued_ip6_config_change, self); + if (priv->queued_ip6_config_id) { + g_source_remove (priv-queued_ip6_config_id);+ g_object_unref (self); + } + priv->queued_ip6_config_id = g_idle_add (queued_ip6_config_change, g_object_ref (self)); _LOGT (LOGD_DEVICE, "IP6 update was postponed"); return; } @@ -9109,8 +9119,8 @@ queued_ip4_config_change (gpointer user_data) return TRUE; priv->queued_ip4_config_id = 0; - g_object_ref (self); update_ip4_config (self, FALSE); + g_object_unref (self); set_unmanaged_external_down (self, TRUE); @@ -9131,7 +9141,6 @@ queued_ip6_config_change (gpointer user_data) return TRUE; priv->queued_ip6_config_id = 0; - g_object_ref (self); update_ip6_config (self, FALSE); if ( nm_platform_link_get (NM_PLATFORM_GET, priv->ifindex) @@ -9194,7 +9203,7 @@ device_ipx_changed (NMPlatform *platform, case NMP_OBJECT_TYPE_IP4_ADDRESS: case NMP_OBJECT_TYPE_IP4_ROUTE: if (!priv->queued_ip4_config_id) { - priv->queued_ip4_config_id = g_idle_add (queued_ip4_config_change, self); + priv->queued_ip4_config_id = g_idle_add (queued_ip4_config_change, g_object_ref (self)); _LOGD (LOGD_DEVICE, "queued IP4 config change"); } break; @@ -9211,7 +9220,7 @@ device_ipx_changed (NMPlatform *platform, /* fallthrough */ case NMP_OBJECT_TYPE_IP6_ROUTE: if (!priv->queued_ip6_config_id) { - priv->queued_ip6_config_id = g_idle_add (queued_ip6_config_change, self); + priv->queued_ip6_config_id = g_idle_add (queued_ip6_config_change, g_object_ref (self)); _LOGD (LOGD_DEVICE, "queued IP6 config change"); } break;
Hi, For any pending queued_ip4_config_change(), we track the gsource ID in queued_ip4_config_id. Thus, the right fix is not to take an additional reference for @self, but ensuring that the queued_ip4_config_id is cleared (g_clear_source) before the device object gets destroyed. From looking at the code, it is however unclear how this crash could possibly happen: dispose() -> _cleanup_generic_pre() -> _cleanup_ip4_pre() -> queued_ip4_config_change_clear(). Maybe the right fix for this is https://cgit.freedesktop.org/NetworkManager/NetworkManager/commit/?id=0175056a6d70bafdaf1042eb8f5e1ef57484a3f2 Thomas
Attachment:
signature.asc
Description: This is a digitally signed message part