diff --git a/meta-networking/recipes-support/strongswan/strongswan/CVE-2026-78133.patch b/meta-networking/recipes-support/strongswan/strongswan/CVE-2026-78133.patch
new file mode 100644
index 0000000000..126f818023
--- /dev/null
+++ b/meta-networking/recipes-support/strongswan/strongswan/CVE-2026-78133.patch
@@ -0,0 +1,620 @@
+From 3f5768c48bc9dff62511c91157e0a9bd12b2159b Mon Sep 17 00:00:00 2001
+From: Tobias Brunner <tobias@strongswan.org>
+Date: Fri, 5 Jun 2026 08:15:46 +0200
+Subject: [PATCH] ikev2: Prevent use-after-free during collision after passive
+ multi-KE rekeying failed
+
+During a multi-KE rekey collision, where the initial response to the
+active rekeying is delayed (or withheld), the active task already keeps
+track of the passive task to eventually resolve the collision (it can
+only do so once all nonces are known).
+
+If the passive task then fails, e.g. due to a missing or invalid KE
+payload, and completes with SUCCESS, `collide()` previously recognized
+that the passive task is not yet complete returned FALSE, which caused
+the task manager to destroy the task.  However, the reference in the
+active task would remain.  So once the active rekeying progresses and
+the collision is resolved, that dangling pointer would get dereferenced
+for an indirect method call.  This happens via the `get_lower_nonce`
+function pointer of the `child_create_t` instance in the private task
+struct.  So besides having to be authenticated, an attacker has to get
+two indirections right to exploit this flaw for a potential RCE.
+Otherwise, the effects are a crash or basically undefined behavior
+triggered by the method call.
+
+By passing whether the passive task is done (and would get destroyed),
+the active tasks can properly clear the held reference.
+
+Note that this patch includes another fix for a state change during
+Child SA rekeying that's included in 6.1.0 (4611f41b1e14 ("child-rekey:
+Only reset state of SAs not actively rekeyed if passive rekeying
+fails")).
+
+Fixes: d2b2e1b3fae8 ("ikev2: Make CHILD_SAs properly trackable during rekey collisions")
+Fixes: ca3e6d2d144e ("ike-rekey: Support IKE_SA rekeying with multiple key exchanges")
+Fixes: CVE-2026-78133
+
+CVE: CVE-2026-78133
+Upstream-Status: Backport [https://github.com/strongiswan/strongswan/commit/eb615b452539461d57503f50041f01773c1ccf86]
+
+Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
+---
+ src/libcharon/sa/ikev2/task_manager_v2.c      |  13 +-
+ src/libcharon/sa/ikev2/tasks/child_rekey.c    |  47 ++++--
+ src/libcharon/sa/ikev2/tasks/child_rekey.h    |   3 +-
+ src/libcharon/sa/ikev2/tasks/ike_rekey.c      |  40 +++--
+ src/libcharon/sa/ikev2/tasks/ike_rekey.h      |   3 +-
+ src/libcharon/tests/suites/test_child_rekey.c | 136 ++++++++++++++++
+ src/libcharon/tests/suites/test_ike_rekey.c   | 147 ++++++++++++++++++
+ 7 files changed, 361 insertions(+), 28 deletions(-)
+
+diff --git a/src/libcharon/sa/ikev2/task_manager_v2.c b/src/libcharon/sa/ikev2/task_manager_v2.c
+index 0f3b937..5a19ce8 100644
+--- a/src/libcharon/sa/ikev2/task_manager_v2.c
++++ b/src/libcharon/sa/ikev2/task_manager_v2.c
+@@ -927,7 +927,8 @@ static status_t process_response(private_task_manager_t *this,
+  * Handle exchange collisions, returns TRUE if the given passive task was
+  * adopted by the active task and the task manager lost control over it.
+  */
+-static bool handle_collisions(private_task_manager_t *this, task_t *task)
++static bool handle_collisions(private_task_manager_t *this, task_t *task,
++							  bool done)
+ {
+ 	enumerator_t *enumerator;
+ 	task_t *active;
+@@ -951,7 +952,7 @@ static bool handle_collisions(private_task_manager_t *this, task_t *task)
+ 					if (type == TASK_IKE_REKEY || type == TASK_IKE_DELETE)
+ 					{
+ 						ike_rekey_t *rekey = (ike_rekey_t*)active;
+-						adopted = rekey->collide(rekey, task);
++						adopted = rekey->collide(rekey, task, done);
+ 						break;
+ 					}
+ 					continue;
+@@ -959,7 +960,7 @@ static bool handle_collisions(private_task_manager_t *this, task_t *task)
+ 					if (type == TASK_CHILD_REKEY)
+ 					{
+ 						child_rekey_t *rekey = (child_rekey_t*)active;
+-						adopted = rekey->collide(rekey, task);
++						adopted = rekey->collide(rekey, task, done);
+ 						break;
+ 					}
+ 					continue;
+@@ -1011,14 +1012,14 @@ static status_t build_response(private_task_manager_t *this, message_t *request)
+ 			case SUCCESS:
+ 				/* task completed, remove it */
+ 				array_remove_at(this->passive_tasks, enumerator);
+-				if (!handle_collisions(this, task))
++				if (!handle_collisions(this, task, TRUE))
+ 				{
+ 					task->destroy(task);
+ 				}
+ 				break;
+ 			case NEED_MORE:
+ 				/* processed, but task needs another exchange */
+-				if (handle_collisions(this, task))
++				if (handle_collisions(this, task, FALSE))
+ 				{
+ 					array_remove_at(this->passive_tasks, enumerator);
+ 				}
+@@ -1029,7 +1030,7 @@ static status_t build_response(private_task_manager_t *this, message_t *request)
+ 				/* FALL */
+ 			case DESTROY_ME:
+ 				/* destroy IKE_SA, but SEND response first */
+-				if (handle_collisions(this, task))
++				if (handle_collisions(this, task, FALSE))
+ 				{
+ 					array_remove_at(this->passive_tasks, enumerator);
+ 				}
+diff --git a/src/libcharon/sa/ikev2/tasks/child_rekey.c b/src/libcharon/sa/ikev2/tasks/child_rekey.c
+index fb3ba2a..e984668 100644
+--- a/src/libcharon/sa/ikev2/tasks/child_rekey.c
++++ b/src/libcharon/sa/ikev2/tasks/child_rekey.c
+@@ -403,7 +403,7 @@ METHOD(task_t, build_r, status_t,
+ 	child_sa_t *child_sa, *old_replacement;
+ 	child_sa_state_t state = CHILD_INSTALLED;
+ 	uint32_t reqid;
+-	bool followup_sent = FALSE;
++	bool active, followup_sent = FALSE;
+ 
+ 	if (!this->child_sa)
+ 	{
+@@ -423,7 +423,8 @@ METHOD(task_t, build_r, status_t,
+ 		message->add_notify(message, TRUE, TEMPORARY_FAILURE, chunk_empty);
+ 		return SUCCESS;
+ 	}
+-	if (actively_rekeying(this, &followup_sent) && followup_sent)
++	active = actively_rekeying(this, &followup_sent);
++	if (active && followup_sent)
+ 	{
+ 		DBG1(DBG_IKE, "peer initiated rekeying, but we did too and already "
+ 			 "sent IKE_FOLLOWUP_KE");
+@@ -483,8 +484,9 @@ METHOD(task_t, build_r, status_t,
+ 		/* like installing the outbound SA, we only trigger the child-rekey
+ 		 * event once the old SA is deleted */
+ 	}
+-	else if (this->child_sa->get_state(this->child_sa) == CHILD_REKEYING)
+-	{	/* rekeying failed, reuse old child */
++	else if (!active &&
++			 this->child_sa->get_state(this->child_sa) == CHILD_REKEYING)
++	{	/* rekeying failed, reuse old child, unless we are actively rekeying */
+ 		this->child_sa->set_state(this->child_sa, state);
+ 	}
+ 	return SUCCESS;
+@@ -1127,8 +1129,22 @@ METHOD(child_rekey_t, handle_delete, child_rekey_collision_t,
+ 	return CHILD_REKEY_COLLISION_NONE;
+ }
+ 
++/**
++ * Clear the colliding passive task if it did not complete successfully.
++ */
++static void clear_collision(private_child_rekey_t *this, task_t *other)
++{
++	if (this->collision == other)
++	{
++		DBG1(DBG_IKE, "colliding passive rekeying for CHILD_SA %s{%u} "
++			 "failed", this->child_sa->get_name(this->child_sa),
++			 this->child_sa->get_unique_id(this->child_sa));
++		this->collision = NULL;
++	}
++}
++
+ METHOD(child_rekey_t, collide, bool,
+-	private_child_rekey_t *this, task_t *other)
++	private_child_rekey_t *this, task_t *other, bool done)
+ {
+ 	private_child_rekey_t *rekey = (private_child_rekey_t*)other;
+ 	child_sa_t *other_child;
+@@ -1142,16 +1158,25 @@ METHOD(child_rekey_t, collide, bool,
+ 	other_child = rekey->child_create->get_child(rekey->child_create);
+ 	if (!other_child)
+ 	{
+-		/* ignore passive tasks that did not successfully create a CHILD_SA */
++		/* ignore passive tasks that did not successfully create a CHILD_SA,
++		 * if we are already tracking it in the multi-KE case, clear it */
++		clear_collision(this, other);
+ 		return FALSE;
+ 	}
+ 	if (other_child->get_state(other_child) != CHILD_INSTALLED)
+ 	{
+-		DBG1(DBG_IKE, "colliding passive rekeying for CHILD_SA %s{%u} is not "
+-			 "yet complete", this->child_sa->get_name(this->child_sa),
+-			 this->child_sa->get_unique_id(this->child_sa));
+-		/* we do reference the task to check its state later */
+-		this->collision = other;
++		if (done)
++		{	/* passive task failed, clear it if necessary */
++			clear_collision(this, other);
++		}
++		else
++		{
++			DBG1(DBG_IKE, "colliding passive rekeying for CHILD_SA %s{%u} is "
++				 "not yet complete", this->child_sa->get_name(this->child_sa),
++				 this->child_sa->get_unique_id(this->child_sa));
++			/* we do reference the task to check its state later */
++			this->collision = other;
++		}
+ 		return FALSE;
+ 	}
+ 	if (this->collision && this->collision != other)
+diff --git a/src/libcharon/sa/ikev2/tasks/child_rekey.h b/src/libcharon/sa/ikev2/tasks/child_rekey.h
+index a8daed7..fef0bba 100644
+--- a/src/libcharon/sa/ikev2/tasks/child_rekey.h
++++ b/src/libcharon/sa/ikev2/tasks/child_rekey.h
+@@ -79,10 +79,11 @@ struct child_rekey_t {
+ 	 * are going on and notifies the active task by passing the passive.
+ 	 *
+ 	 * @param other		passive task
++	 * @param done		passive task is done and gets destroyed if not adopted
+ 	 * @return			whether the task was adopted and should be removed from
+ 	 *					the task manager's control
+ 	 */
+-	bool (*collide)(child_rekey_t* this, task_t *other);
++	bool (*collide)(child_rekey_t* this, task_t *other, bool done);
+ };
+ 
+ /**
+diff --git a/src/libcharon/sa/ikev2/tasks/ike_rekey.c b/src/libcharon/sa/ikev2/tasks/ike_rekey.c
+index c7e8ffb..f275d2d 100644
+--- a/src/libcharon/sa/ikev2/tasks/ike_rekey.c
++++ b/src/libcharon/sa/ikev2/tasks/ike_rekey.c
+@@ -743,8 +743,23 @@ METHOD(ike_rekey_t, did_collide, bool,
+ 	return this->collision != NULL;
+ }
+ 
++/**
++ * Clear the colliding passive task if it did not complete successfully.
++ */
++static bool clear_collision(private_ike_rekey_t *this,
++							private_ike_rekey_t *other)
++{
++	if (this->collision == other)
++	{
++		DBG1(DBG_IKE, "colliding passive rekeying failed, ignore");
++		this->collision = NULL;
++		return TRUE;
++	}
++	return FALSE;
++}
++
+ METHOD(ike_rekey_t, collide, bool,
+-	private_ike_rekey_t* this, task_t *other)
++	private_ike_rekey_t* this, task_t *other, bool done)
+ {
+ 	DBG1(DBG_IKE, "detected %N collision with %N", task_type_names,
+ 		 TASK_IKE_REKEY, task_type_names, other->get_type(other));
+@@ -760,23 +775,30 @@ METHOD(ike_rekey_t, collide, bool,
+ 
+ 			if (!rekey->ike_init)
+ 			{
+-				DBG1(DBG_IKE, "colliding exchange did not result in an IKE_SA, "
+-					 "ignore");
+-				if (this->collision == rekey)
++				if (!clear_collision(this, rekey))
+ 				{
+-					this->collision = NULL;
++					DBG1(DBG_IKE, "colliding exchange did not result in an "
++						 "IKE_SA, ignore");
+ 				}
+ 				break;
+ 			}
+-			/* we keep track of the passive exchange in any case, if not
+-			 * complete yet, this method might be called again later */
+-			this->collision = rekey;
++			/* we keep track of the passive exchange, if not complete yet, this
++			 * method might be called again later */
+ 			if (rekey->flags & IKE_REKEY_DONE)
+ 			{
++				this->collision = rekey;
+ 				this->flags |= IKE_REKEY_ADOPTED_PASSIVE;
+ 				return TRUE;
+ 			}
+-			DBG1(DBG_IKE, "colliding passive exchange is not yet complete");
++			else if (done)
++			{	/* passive task failed, clear it if necessary */
++				clear_collision(this, rekey);
++			}
++			else
++			{
++				DBG1(DBG_IKE, "colliding passive exchange is not yet complete");
++				this->collision = rekey;
++			}
+ 			break;
+ 		}
+ 		default:
+diff --git a/src/libcharon/sa/ikev2/tasks/ike_rekey.h b/src/libcharon/sa/ikev2/tasks/ike_rekey.h
+index 5fab349..e68fa62 100644
+--- a/src/libcharon/sa/ikev2/tasks/ike_rekey.h
++++ b/src/libcharon/sa/ikev2/tasks/ike_rekey.h
+@@ -54,10 +54,11 @@ struct ike_rekey_t {
+ 	 * are going on and notifies the active task by passing the passive.
+ 	 *
+ 	 * @param other		passive task
++	 * @param done		passive task is done and gets destroyed if not adopted
+ 	 * @return			whether the task was adopted and should be removed from
+ 	 *					the task manager's control
+ 	 */
+-	bool (*collide)(ike_rekey_t* this, task_t *other);
++	bool (*collide)(ike_rekey_t* this, task_t *other, bool done);
+ };
+ 
+ /**
+diff --git a/src/libcharon/tests/suites/test_child_rekey.c b/src/libcharon/tests/suites/test_child_rekey.c
+index 1c81e75..4ef081a 100644
+--- a/src/libcharon/tests/suites/test_child_rekey.c
++++ b/src/libcharon/tests/suites/test_child_rekey.c
+@@ -2546,6 +2546,141 @@ START_TEST(test_collision_delayed_response_multi_ke)
+ }
+ END_TEST
+ 
++/**
++ * Remove the KE payload from the IKE_FOLLOWUP_KE request
++ */
++static bool remove_ke(listener_t *listener, ike_sa_t *ike_sa,
++					  message_t *message, bool incoming, bool plain)
++{
++	if (plain && incoming &&
++		message->get_exchange_type(message) == IKE_FOLLOWUP_KE &&
++		message->get_request(message))
++	{
++		enumerator_t *enumerator = message->create_payload_enumerator(message);
++		payload_t *pld;
++
++		while (enumerator->enumerate(enumerator, &pld))
++		{
++			if (pld->get_type(pld) == PLV2_KEY_EXCHANGE)
++			{
++				message->remove_payload_at(message, enumerator);
++				pld->destroy(pld);
++				break;
++			}
++		}
++		enumerator->destroy(enumerator);
++		free(listener);
++		return FALSE;
++	}
++	return TRUE;
++}
++
++#define remove_ke_from_ike_followup_ke() ({ \
++	listener_t *_ke_listener; \
++	INIT(_ke_listener, \
++		.message = remove_ke, \
++	); \
++	exchange_test_helper->add_listener(exchange_test_helper, _ke_listener); \
++})
++
++/**
++ * This simulates an incorrect behavior by the peer.  It triggers a collision by
++ * not responding to the initial CREATE_CHILD_SA and then sends an invalid
++ * IKE_FOLLOWUP_KE (in this case the KE payload is missing).  The initiator
++ * has to correctly track and then untrack the passive rekey task.
++ *
++ *           Peer A                   Peer B
++ *            rekey ----\       /---- rekey
++ *                       \-----/----> detect collision and withhold response
++ * detect collision <---------/
++ *                  ---------------->
++ *   handle failure <---------------- send invalid additional KE
++ *     handle rekey <---------------- send withheld response
++ */
++START_TEST(test_collision_delayed_response_multi_ke_failure)
++{
++	ike_sa_t *a, *b;
++	message_t *msg;
++
++	assert_track_sas_start();
++
++	exchange_test_helper->establish_sa(exchange_test_helper,
++									   &a, &b, &multi_ke_conf);
++
++	/* make sure the responder wins the collision so it continues */
++	exchange_test_helper->nonce_first_byte = 0x00;
++	initiate_rekey(a, 1);
++	assert_ipsec_sas_installed(a, 1, 2);
++	exchange_test_helper->nonce_first_byte = 0xff;
++	initiate_rekey(b, 2);
++	assert_ipsec_sas_installed(b, 1, 2);
++
++	/* these should not get called as no SA goes down or gets rekeyed */
++	assert_hook_not_called(child_updown);
++	assert_hook_not_called(child_rekey);
++
++	/* CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } --> */
++	exchange_test_helper->nonce_first_byte = 0xff;
++	exchange_test_helper->process_message(exchange_test_helper, b, NULL);
++	assert_child_sa_state(b, 2, CHILD_REKEYING, CHILD_OUTBOUND_INSTALLED);
++	assert_ipsec_sas_installed(b, 1, 2);
++
++	/* <-- CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } */
++	exchange_test_helper->nonce_first_byte = 0xff;
++	exchange_test_helper->process_message(exchange_test_helper, a, NULL);
++	assert_child_sa_state(a, 1, CHILD_REKEYING, CHILD_OUTBOUND_INSTALLED);
++	assert_ipsec_sas_installed(a, 1, 2);
++
++	/* the responder is not responding */
++	msg = exchange_test_helper->sender->dequeue(exchange_test_helper->sender);
++
++	/* CREATE_CHILD_SA { SA, Nr, [KEr,] TSi, TSr } --> */
++	exchange_test_helper->process_message(exchange_test_helper, b, NULL);
++	assert_num_tasks(b, 0, TASK_QUEUE_PASSIVE);
++	assert_num_tasks(b, 1, TASK_QUEUE_ACTIVE);
++	assert_child_sa_state(b, 2, CHILD_REKEYING, CHILD_OUTBOUND_INSTALLED);
++	assert_ipsec_sas_installed(b, 1, 2);
++
++	/* remove the KE payload in the IKE_FOLLOWUP_KE request */
++	remove_ke_from_ike_followup_ke();
++
++	/* <-- IKE_FOLLOWUP_KE { N(ADD_KE) } */
++	assert_no_payload(IN, PLV2_KEY_EXCHANGE);
++	assert_single_notify(OUT, INVALID_SYNTAX);
++	exchange_test_helper->process_message(exchange_test_helper, a, NULL);
++	assert_child_sa_state(a, 1, CHILD_REKEYING, CHILD_OUTBOUND_INSTALLED);
++	assert_ipsec_sas_installed(a, 1, 2);
++	assert_num_tasks(a, 0, TASK_QUEUE_PASSIVE);
++
++	/* <-- CREATE_CHILD_SA { SA, Nr, [KEr,] TSi, TSr } (delayed) */
++	exchange_test_helper->process_message(exchange_test_helper, a, msg);
++	assert_num_tasks(a, 0, TASK_QUEUE_PASSIVE);
++	assert_num_tasks(a, 1, TASK_QUEUE_ACTIVE);
++	assert_child_sa_state(a, 1, CHILD_REKEYING, CHILD_OUTBOUND_INSTALLED);
++	assert_ipsec_sas_installed(a, 1, 2);
++
++	/* drop the STATE_NOT_FOUND error message from the initiator */
++	msg = exchange_test_helper->sender->dequeue(exchange_test_helper->sender);
++	msg->destroy(msg);
++
++	/* since we explicitly forced the responder to win, it already removed
++	 * the passive task it won't accept the request */
++
++	/* IKE_FOLLOWUP_KE { KEi, N(ADD_KE) } --> */
++	assert_payload(IN, PLV2_KEY_EXCHANGE);
++	assert_notify(IN, ADDITIONAL_KEY_EXCHANGE);
++	exchange_test_helper->process_message(exchange_test_helper, b, NULL);
++
++	/* child_rekey/child_updown */
++	assert_hook();
++	assert_hook();
++	assert_track_sas(2, 2);
++
++	call_ikesa(a, destroy);
++	call_ikesa(b, destroy);
++}
++END_TEST
++
+ /**
+  * In this scenario one of the peers does not notice that there is a
+  * rekey collision:
+@@ -4436,6 +4571,7 @@ Suite *child_rekey_suite_create()
+ 	tcase_add_loop_test(tc, test_collision_delayed_response, 0, 4);
+ 	tcase_add_loop_test(tc, test_collision_delayed_response_delete, 0, 4);
+ 	tcase_add_loop_test(tc, test_collision_delayed_response_multi_ke, 0, 4);
++	tcase_add_test(tc, test_collision_delayed_response_multi_ke_failure);
+ 	tcase_add_loop_test(tc, test_collision_delayed_request, 0, 6);
+ 	tcase_add_loop_test(tc, test_collision_delayed_request_more, 0, 3);
+ 	tcase_add_loop_test(tc, test_collision_delayed_request_more_delete, 0, 3);
+diff --git a/src/libcharon/tests/suites/test_ike_rekey.c b/src/libcharon/tests/suites/test_ike_rekey.c
+index c6691ac..2c41022 100644
+--- a/src/libcharon/tests/suites/test_ike_rekey.c
++++ b/src/libcharon/tests/suites/test_ike_rekey.c
+@@ -1784,6 +1784,152 @@ START_TEST(test_collision_delayed_response_multi_ke)
+ }
+ END_TEST
+ 
++/**
++ * Remove the ADDITIONAL_KEY_EXCHANGE notify payload from the IKE_FOLLOWUP_KE
++ * request
++ */
++static bool remove_notify(listener_t *listener, ike_sa_t *ike_sa,
++						  message_t *message, bool incoming, bool plain)
++{
++	if (plain && incoming &&
++		message->get_exchange_type(message) == IKE_FOLLOWUP_KE &&
++		message->get_request(message))
++	{
++		enumerator_t *enumerator = message->create_payload_enumerator(message);
++		payload_t *pld;
++
++		while (enumerator->enumerate(enumerator, &pld))
++		{	/* we only expect one notify, so just remove the first */
++			if (pld->get_type(pld) == PLV2_NOTIFY)
++			{
++				message->remove_payload_at(message, enumerator);
++				pld->destroy(pld);
++				break;
++			}
++		}
++		enumerator->destroy(enumerator);
++		free(listener);
++		return FALSE;
++	}
++	return TRUE;
++}
++
++#define remove_notify_from_ike_followup_ke() ({ \
++	listener_t *_ke_listener; \
++	INIT(_ke_listener, \
++		.message = remove_notify, \
++	); \
++	exchange_test_helper->add_listener(exchange_test_helper, _ke_listener); \
++})
++
++/**
++ * This simulates an incorrect behavior by the peer.  It triggers a collision by
++ * not responding to the initial CREATE_CHILD_SA and then sends an invalid
++ * IKE_FOLLOWUP_KE (in this case by removing the ADDITIONAL_KEY_EXCHANGE
++ * notify).  The initiator has to correctly track and then untrack the passive
++ * rekey task.
++ *
++ *           Peer A                   Peer B
++ *            rekey ----\       /---- rekey
++ *                       \-----/----> detect collision and withhold response
++ * detect collision <---------/
++ *                  ---------------->
++ *   handle failure <---------------- send invalid additional KE
++ *     handle rekey <---------------- send withheld response
++ */
++START_TEST(test_collision_delayed_response_multi_ke_failure)
++{
++	ike_sa_t *a, *b;
++	message_t *msg;
++
++	assert_track_sas_start();
++
++	exchange_test_helper->establish_sa(exchange_test_helper,
++									   &a, &b, &multi_ke_conf);
++
++	/* these should not get called as no SA goes down or gets rekeyed */
++	assert_hook_not_called(ike_updown);
++	assert_hook_not_called(ike_rekey);
++	assert_hook_not_called(child_updown);
++
++	/* make sure the responder wins the collision so it continues */
++	exchange_test_helper->nonce_first_byte = 0x00;
++	initiate_rekey(a);
++	exchange_test_helper->nonce_first_byte = 0xff;
++	initiate_rekey(b);
++
++	/* CREATE_CHILD_SA { SA, Ni, KEi } --> */
++	exchange_test_helper->nonce_first_byte = 0xff;
++	exchange_test_helper->process_message(exchange_test_helper, b, NULL);
++	assert_ike_sa_state(b, IKE_REKEYING);
++	assert_child_sa_count(b, 1);
++	assert_ike_sa_count(0);
++
++	/* <-- CREATE_CHILD_SA { SA, Ni, KEi } */
++	exchange_test_helper->nonce_first_byte = 0xff;
++	exchange_test_helper->process_message(exchange_test_helper, a, NULL);
++	assert_ike_sa_state(a, IKE_REKEYING);
++	assert_child_sa_count(a, 1);
++	assert_ike_sa_count(0);
++
++	/* the responder is not responding */
++	msg = exchange_test_helper->sender->dequeue(exchange_test_helper->sender);
++
++	/* simplify next steps by checking in original IKE_SAs */
++	charon->ike_sa_manager->checkin(charon->ike_sa_manager, a);
++	charon->ike_sa_manager->checkin(charon->ike_sa_manager, b);
++	assert_ike_sa_count(2);
++
++	/* CREATE_CHILD_SA { SA, Nr, KEr, N(ADD_KE) } --> */
++	assert_notify(IN, ADDITIONAL_KEY_EXCHANGE);
++	exchange_test_helper->process_message(exchange_test_helper, b, NULL);
++	assert_num_tasks(b, 0, TASK_QUEUE_PASSIVE);
++	assert_num_tasks(b, 1, TASK_QUEUE_ACTIVE);
++	assert_ike_sa_state(b, IKE_REKEYING);
++	assert_ike_sa_count(2);
++
++	/* remove the ADD_KE notify from the IKE_FOLLOWUP_KE request */
++	remove_notify_from_ike_followup_ke();
++
++	/* <-- IKE_FOLLOWUP_KE { KEi } */
++	assert_payload(IN, PLV2_KEY_EXCHANGE);
++	assert_no_notify(IN, ADDITIONAL_KEY_EXCHANGE);
++	assert_single_notify(OUT, STATE_NOT_FOUND);
++	exchange_test_helper->process_message(exchange_test_helper, a, NULL);
++	assert_ike_sa_state(a, IKE_REKEYING);
++	assert_child_sa_count(a, 1);
++	assert_ike_sa_count(2);
++
++	/* <-- CREATE_CHILD_SA { SA, Nr, KEr } (delayed) */
++	exchange_test_helper->process_message(exchange_test_helper, a, msg);
++	assert_num_tasks(a, 0, TASK_QUEUE_PASSIVE);
++	assert_num_tasks(a, 1, TASK_QUEUE_ACTIVE);
++	assert_ike_sa_state(a, IKE_REKEYING);
++	assert_child_sa_count(a, 1);
++	assert_ike_sa_count(2);
++
++	/* drop the STATE_NOT_FOUND error message from the initiator */
++	msg = exchange_test_helper->sender->dequeue(exchange_test_helper->sender);
++	msg->destroy(msg);
++
++	/* since we explicitly forced the responder to win, it already removed
++	 * the passive task it won't accept the request */
++
++	/* IKE_FOLLOWUP_KE { KEi, N(ADD_KE) } --> */
++	assert_payload(IN, PLV2_KEY_EXCHANGE);
++	assert_notify(IN, ADDITIONAL_KEY_EXCHANGE);
++	exchange_test_helper->process_message(exchange_test_helper, b, NULL);
++
++	/* ike_updown/rekey/child_updown */
++	assert_hook();
++	assert_hook();
++	assert_hook();
++	assert_track_sas(2, 2);
++
++	charon->ike_sa_manager->flush(charon->ike_sa_manager);
++}
++END_TEST
++
+ /**
+  * In this scenario one of the peers does not notice that there is a rekey
+  * collision because the other request is dropped:
+@@ -2590,6 +2736,7 @@ Suite *ike_rekey_suite_create()
+ 	tcase_add_loop_test(tc, test_collision_ke_invalid_delayed_retry, 0, 3);
+ 	tcase_add_loop_test(tc, test_collision_delayed_response, 0, 4);
+ 	tcase_add_loop_test(tc, test_collision_delayed_response_multi_ke, 0, 4);
++	tcase_add_test(tc, test_collision_delayed_response_multi_ke_failure);
+ 	tcase_add_loop_test(tc, test_collision_dropped_request, 0, 3);
+ 	tcase_add_loop_test(tc, test_collision_delayed_request, 0, 3);
+ 	tcase_add_loop_test(tc, test_collision_delayed_request_and_delete, 0, 3);
diff --git a/meta-networking/recipes-support/strongswan/strongswan_6.0.6.bb b/meta-networking/recipes-support/strongswan/strongswan_6.0.6.bb
index c8f956f4d8..4d13507151 100644
--- a/meta-networking/recipes-support/strongswan/strongswan_6.0.6.bb
+++ b/meta-networking/recipes-support/strongswan/strongswan_6.0.6.bb
@@ -15,6 +15,7 @@ SRC_URI = "https://download.strongswan.org/strongswan-${PV}.tar.bz2 \
            file://CVE-2026-78126.patch \
            file://CVE-2026-78127.patch \
            file://CVE-2026-78129.patch \
+           file://CVE-2026-78133.patch \
 "
 
 SRC_URI[sha256sum] = "07df7cedae56a7f3bb07e66d21a1f9f87e961db70e99184e11d3819413e4f87c"
