From: Jukka Rissanen Date: Fri, 3 Feb 2012 11:31:28 +0000 (+0200) Subject: vpn: Reference of provider not taken X-Git-Tag: 0.79~114 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bc61a82c641955f0926cf7644c1f9bbc22dcf13f;p=platform%2Fupstream%2Fconnman.git vpn: Reference of provider not taken VPN plugin hooks itself into rtnl newlink watch and gives provider pointer as user data. We must take reference of the user data pointer as otherwise we might access invalid pointer if provider is already removed when rtnl watch is triggered. This seems to be a rare issue but I had one valgrind crash because of this. --- diff --git a/plugins/vpn.c b/plugins/vpn.c index a6ac5b9..e103d36 100644 --- a/plugins/vpn.c +++ b/plugins/vpn.c @@ -135,6 +135,7 @@ void vpn_died(struct connman_task *task, int exit_code, void *user_data) stop_vpn(provider); connman_provider_set_data(provider, NULL); + connman_provider_unref(provider); connman_rtnl_remove_watch(data->watch); vpn_exit: @@ -226,6 +227,7 @@ static DBusMessage *vpn_notify(struct connman_task *task, case VPN_STATE_CONNECT: case VPN_STATE_READY: index = connman_provider_get_index(provider); + connman_provider_ref(provider); data->watch = connman_rtnl_add_newlink_watch(index, vpn_newlink, provider); connman_inet_ifup(index); @@ -421,10 +423,12 @@ static int vpn_disconnect(struct connman_provider *provider) if (vpn_driver_data->vpn_driver->disconnect) vpn_driver_data->vpn_driver->disconnect(); - if (data->watch != 0) + if (data->watch != 0) { + connman_provider_unref(provider); connman_rtnl_remove_watch(data->watch); + data->watch = 0; + } - data->watch = 0; data->state = VPN_STATE_DISCONNECT; connman_task_stop(data->task); @@ -439,9 +443,12 @@ static int vpn_remove(struct connman_provider *provider) if (data == NULL) return 0; - if (data->watch != 0) + if (data->watch != 0) { + connman_provider_unref(provider); connman_rtnl_remove_watch(data->watch); - data->watch = 0; + data->watch = 0; + } + connman_task_stop(data->task); g_usleep(G_USEC_PER_SEC);