diff options
author | Jussi Laakkonen <jussi.laakkonen@jolla.com> | 2020-12-02 11:22:11 +0200 |
---|---|---|
committer | Daniel Wagner <wagi@monom.org> | 2020-12-04 13:53:49 +0100 |
commit | b07112e0428a0272a3ca5951426721c74b293674 (patch) | |
tree | b1347ba041c000f00dd36be1f8a08f92e6bae2ed /vpn | |
parent | 3c9577e3feb0eb034250e974989c7f04827d48aa (diff) | |
download | connman-b07112e0428a0272a3ca5951426721c74b293674.tar.gz |
vpn-provider: Cancel agent requests when removing VPN
If a VPN has a pending request active in the agent and connman-vpnd is
restarted or shutdown it will result in segmentation fault. This happens
because plugins and tasks are cleaned up before vpn-provider and thus,
the removal of agent driver is called after the plugins are gone and
if there is a pending request from any unloaded VPN plugin it needs to
be cancelled. Since the callback set in the agent request points to a
function in the VPN plugin following happens:
Thread 1 "connman-vpnd" received signal SIGSEGV, Segmentation fault.
0xf6716cbc in ?? ()
(gdb) bt
\#0 0xf6716cbc in ?? ()
\#1 0x0002bafc in agent_finalize_pending (reply=reply@entry=0x0,
agent=<optimized out>) at src/agent.c:121
\#2 0x0002bd80 in cancel_all_requests (agent=0x5285a0) at
src/agent.c:483
\#3 agent_unref_debug (file=0x363d4 "src/agent.c", line=647,
caller=<synthetic pointer>, agent=0x5285a0) at src/agent.c:568
\#4 agent_destroy (data=0x5285a0) at src/agent.c:647
\#5 0xf6f6e8d6 in g_hash_table_remove_all_nodes (hash_table=0x4c94e8,
notify=<optimized out>, destruction=<optimized out>) at ghash.c:552
\#6 0xf6f6fe3c in g_hash_table_remove_all_nodes (destruction=0,
notify=1, hash_table=0x4c94e8) at ghash.c:1444
\#7 g_hash_table_remove_all (hash_table=0x4c94e8) at ghash.c:1447
\#8 0x0002c442 in connman_agent_driver_unregister
(driver=driver@entry=0x49784 <agent_driver>) at src/agent.c:629
\#9 0x00024442 in __vpn_provider_cleanup () at vpn/vpn-provider.c:3416
\#10 0x0001a086 in main (argc=1, argv=0xff8c1334) at vpn/main.c:283
Therefore, the requests must be canceled at plugin driver unregister as
that gets eventually called by VPN plugin exit function via
vpn_unregister().
Diffstat (limited to 'vpn')
-rw-r--r-- | vpn/vpn-provider.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/vpn/vpn-provider.c b/vpn/vpn-provider.c index 5d0fb2ce..be25e394 100644 --- a/vpn/vpn-provider.c +++ b/vpn/vpn-provider.c @@ -2984,6 +2984,12 @@ void vpn_provider_driver_unregister(struct vpn_provider_driver *driver) if (provider && provider->driver && g_strcmp0(provider->driver->name, driver->name) == 0) { + /* + * Cancel VPN agent request to avoid segfault at + * shutdown as the callback, if set can point to a + * function in the plugin that is to be removed. + */ + connman_agent_cancel(provider); provider->driver = NULL; } } |