aboutsummaryrefslogtreecommitdiffstats
path: root/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2016-05-04 15:39:51 +0200
committerTobias Brunner <tobias@strongswan.org>2016-05-06 16:00:32 +0200
commitfee991c2597abbb6de75fb4a256f4fd8fe5b5f1b (patch)
treeb27ed9992bc64775970b35fd21b1dcd475e0dcef /src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c
parent9c01e0142070d3e93c0dc2687020acd51879f7cd (diff)
downloadstrongswan-fee991c2597abbb6de75fb4a256f4fd8fe5b5f1b.tar.bz2
strongswan-fee991c2597abbb6de75fb4a256f4fd8fe5b5f1b.tar.xz
kernel-netlink: Check proper watcher state in parallel mode
After adding the read callback the state is WATCHER_QUEUED and it is switched to WATCHER_RUNNING only later by an asynchronous job. This means that a thread that sent a Netlink message shortly after registration might see the state as WATCHER_QUEUED. If it then tries to read the response and the watcher thread is quicker to actually read the message from the socket, it could block on recv() while still holding the lock. And the asynchronous job that actually read the message and tries to queue it will block while trying to acquire the lock, so we'd end up in a deadlock. This is probably mostly a problem in the unit tests.
Diffstat (limited to 'src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c')
-rw-r--r--src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c
index f7ce992a3..0e49987f6 100644
--- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c
+++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c
@@ -309,7 +309,7 @@ static status_t send_once(private_netlink_socket_t *this, struct nlmsghdr *in,
while (!entry->complete)
{
if (this->parallel &&
- lib->watcher->get_state(lib->watcher) == WATCHER_RUNNING)
+ lib->watcher->get_state(lib->watcher) != WATCHER_STOPPED)
{
if (this->timeout)
{