diff options
author | Tobias Brunner <tobias@strongswan.org> | 2011-06-07 15:21:59 +0200 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2011-07-06 09:43:46 +0200 |
commit | 32fbad4ec22c7050357891a8ff7b3170c07f8850 (patch) | |
tree | a3ae9bc7dcaa0823c13cc02c6c00b8c6bf448e3b /src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c | |
parent | 75fc9d3136ab0f78b2dba91d8463c4af1c23b427 (diff) | |
download | strongswan-32fbad4ec22c7050357891a8ff7b3170c07f8850.tar.bz2 strongswan-32fbad4ec22c7050357891a8ff7b3170c07f8850.tar.xz |
Make sure access to policy is thread-safe during installation of route.
Diffstat (limited to 'src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c')
-rw-r--r-- | src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c index 7d8deeafa..d3f3d1073 100644 --- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c +++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c @@ -385,7 +385,7 @@ struct private_kernel_netlink_ipsec_t { kernel_netlink_ipsec_t public; /** - * mutex to lock access to various lists + * mutex to lock access to installed policies */ mutex_t *mutex; @@ -1785,10 +1785,14 @@ static status_t add_policy_internal(private_kernel_netlink_ipsec_t *this, policy_entry_t *policy, policy_sa_t *sa, bool update) { netlink_buf_t request; + policy_entry_t clone; struct xfrm_userpolicy_info *policy_info; struct nlmsghdr *hdr; int i; + /* clone the policy so we are able to check it out again later */ + memcpy(&clone, policy, sizeof(policy_entry_t)); + memset(&request, 0, sizeof(request)); hdr = (struct nlmsghdr*)request; hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; @@ -1894,7 +1898,15 @@ static status_t add_policy_internal(private_kernel_netlink_ipsec_t *this, return FAILED; } - /* FIXME: accessing policy and sa here is not really thread safe */ + /* find the policy again */ + this->mutex->lock(this->mutex); + policy = this->policies->get(this->policies, &clone); + if (!policy || + policy->sas->find_first(policy->sas, NULL, (void**)&sa) != SUCCESS) + { /* policy or sa is already gone, ignore */ + this->mutex->unlock(this->mutex); + return SUCCESS; + } /* install a route, if: * - this is a forward policy (to just get one for each child) @@ -1921,6 +1933,7 @@ static status_t add_policy_internal(private_kernel_netlink_ipsec_t *this, if (!route->if_name) { + this->mutex->unlock(this->mutex); route_entry_destroy(route); return SUCCESS; } @@ -1930,6 +1943,7 @@ static status_t add_policy_internal(private_kernel_netlink_ipsec_t *this, route_entry_t *old = policy->route; if (route_entry_equals(old, route)) { /* keep previously installed route */ + this->mutex->unlock(this->mutex); route_entry_destroy(route); return SUCCESS; } @@ -1973,6 +1987,7 @@ static status_t add_policy_internal(private_kernel_netlink_ipsec_t *this, free(route); } } + this->mutex->unlock(this->mutex); return SUCCESS; } |