From: Tobias Brunner Date: Fri, 23 Dec 2011 09:38:10 +0000 (+0100) Subject: Fixed flush() method of trap_manager_t. X-Git-Tag: 4.6.2~83 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d6656f11e48d9b545738d5f40e59f3c3dd90ef97;p=thirdparty%2Fstrongswan.git Fixed flush() method of trap_manager_t. A segmentation fault could have happened during destruction of the trap manager after calling flush(). --- diff --git a/src/libcharon/sa/trap_manager.c b/src/libcharon/sa/trap_manager.c index bf9f8432c7..c7a8a6e0c6 100644 --- a/src/libcharon/sa/trap_manager.c +++ b/src/libcharon/sa/trap_manager.c @@ -353,15 +353,21 @@ METHOD(listener_t, child_state_change, bool, METHOD(trap_manager_t, flush, void, private_trap_manager_t *this) { - this->traps->invoke_function(this->traps, (void*)destroy_entry); + linked_list_t *traps; + /* since destroying the CHILD_SA results in events which require a read + * lock we cannot destroy the list while holding the write lock */ + this->lock->write_lock(this->lock); + traps = this->traps; + this->traps = linked_list_create(); + this->lock->unlock(this->lock); + traps->destroy_function(traps, (void*)destroy_entry); } METHOD(trap_manager_t, destroy, void, private_trap_manager_t *this) { charon->bus->remove_listener(charon->bus, &this->listener.listener); - this->traps->invoke_function(this->traps, (void*)destroy_entry); - this->traps->destroy(this->traps); + this->traps->destroy_function(this->traps, (void*)destroy_entry); this->lock->destroy(this->lock); free(this); }