diff options
Diffstat (limited to 'main/strongswan/0002-ike-sa-manager-Safely-access-the-RNG-instance-with-a.patch')
-rw-r--r-- | main/strongswan/0002-ike-sa-manager-Safely-access-the-RNG-instance-with-a.patch | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/main/strongswan/0002-ike-sa-manager-Safely-access-the-RNG-instance-with-a.patch b/main/strongswan/0002-ike-sa-manager-Safely-access-the-RNG-instance-with-a.patch new file mode 100644 index 0000000000..c17141460a --- /dev/null +++ b/main/strongswan/0002-ike-sa-manager-Safely-access-the-RNG-instance-with-a.patch @@ -0,0 +1,91 @@ +From 390ae7a2c2f899122e722241cb261f53dfc81b9a Mon Sep 17 00:00:00 2001 +From: Tobias Brunner <tobias@strongswan.org> +Date: Wed, 8 Jul 2015 15:28:46 +0200 +Subject: [PATCH] ike-sa-manager: Safely access the RNG instance with an rwlock + +Threads might still be allocating SPIs (e.g. triggered by an acquire or +an inbound message) while the main thread calls flush(). If there is a +context switch right after such a thread successfully checked this->rng +in get_spi() and the main thread destroys the RNG instance right then, +that worker thread will cause a segmentation fault when it continues and +attempts to call get_bytes(). + +Fixes #1014. +--- + src/libcharon/sa/ike_sa_manager.c | 21 ++++++++++++++++----- + 1 file changed, 16 insertions(+), 5 deletions(-) + +diff --git a/src/libcharon/sa/ike_sa_manager.c b/src/libcharon/sa/ike_sa_manager.c +index 938f784..987260d 100644 +--- a/src/libcharon/sa/ike_sa_manager.c ++++ b/src/libcharon/sa/ike_sa_manager.c +@@ -1,7 +1,7 @@ + /* + * Copyright (C) 2005-2011 Martin Willi + * Copyright (C) 2011 revosec AG +- * Copyright (C) 2008-2012 Tobias Brunner ++ * Copyright (C) 2008-2015 Tobias Brunner + * Copyright (C) 2005 Jan Hutter + * Hochschule fuer Technik Rapperswil + * +@@ -384,6 +384,11 @@ struct private_ike_sa_manager_t { + rng_t *rng; + + /** ++ * Lock to access the RNG instance ++ */ ++ rwlock_t *rng_lock; ++ ++ /** + * reuse existing IKE_SAs in checkout_by_config + */ + bool reuse_ikesa; +@@ -943,12 +948,14 @@ static u_int64_t get_spi(private_ike_sa_manager_t *this) + { + u_int64_t spi; + +- if (this->rng && +- this->rng->get_bytes(this->rng, sizeof(spi), (u_int8_t*)&spi)) ++ this->rng_lock->read_lock(this->rng_lock); ++ if (!this->rng || ++ !this->rng->get_bytes(this->rng, sizeof(spi), (u_int8_t*)&spi)) + { +- return spi; ++ spi = 0; + } +- return 0; ++ this->rng_lock->unlock(this->rng_lock); ++ return spi; + } + + /** +@@ -2055,8 +2062,10 @@ METHOD(ike_sa_manager_t, flush, void, + charon->bus->set_sa(charon->bus, NULL); + unlock_all_segments(this); + ++ this->rng_lock->write_lock(this->rng_lock); + this->rng->destroy(this->rng); + this->rng = NULL; ++ this->rng_lock->unlock(this->rng_lock); + } + + METHOD(ike_sa_manager_t, destroy, void, +@@ -2081,6 +2090,7 @@ METHOD(ike_sa_manager_t, destroy, void, + free(this->connected_peers_segments); + free(this->init_hashes_segments); + ++ this->rng_lock->destroy(this->rng_lock); + free(this); + } + +@@ -2138,6 +2148,7 @@ ike_sa_manager_t *ike_sa_manager_create() + free(this); + return NULL; + } ++ this->rng_lock = rwlock_create(RWLOCK_TYPE_DEFAULT); + + this->ikesa_limit = lib->settings->get_int(lib->settings, + "%s.ikesa_limit", 0, lib->ns); +-- +2.4.6 + |