aboutsummaryrefslogtreecommitdiffstats
path: root/main/strongswan/0002-ike-sa-manager-Safely-access-the-RNG-instance-with-a.patch
diff options
context:
space:
mode:
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.patch91
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
+