From 12a3f3ca52e9620529b4c71b865f6b3259ec22c4 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Thu, 8 Oct 2020 14:04:36 +0200 Subject: [PATCH] quick-delete: Properly handle failures to restart CHILD_SA If DESTROY_ME is returned from initiate(), we must not touch the IKE_SA anymore. --- src/libcharon/sa/ikev1/tasks/quick_delete.c | 37 +++++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/src/libcharon/sa/ikev1/tasks/quick_delete.c b/src/libcharon/sa/ikev1/tasks/quick_delete.c index 67306912f..7dff247fb 100644 --- a/src/libcharon/sa/ikev1/tasks/quick_delete.c +++ b/src/libcharon/sa/ikev1/tasks/quick_delete.c @@ -86,13 +86,15 @@ struct private_quick_delete_t { /** * Delete the specified CHILD_SA, if found */ -static bool delete_child(private_quick_delete_t *this, protocol_id_t protocol, - uint32_t spi, bool remote_close) +static status_t delete_child(private_quick_delete_t *this, + protocol_id_t protocol, uint32_t spi, + bool remote_close) { uint64_t bytes_in, bytes_out; child_sa_t *child_sa; linked_list_t *my_ts, *other_ts; child_cfg_t *child_cfg; + status_t status = SUCCESS; bool rekeyed; child_sa = this->ike_sa->get_child_sa(this->ike_sa, protocol, spi, TRUE); @@ -101,7 +103,7 @@ static bool delete_child(private_quick_delete_t *this, protocol_id_t protocol, child_sa = this->ike_sa->get_child_sa(this->ike_sa, protocol, spi, FALSE); if (!child_sa) { - return FALSE; + return NOT_FOUND; } this->spi = spi = child_sa->get_spi(child_sa, TRUE); } @@ -154,7 +156,7 @@ static bool delete_child(private_quick_delete_t *this, protocol_id_t protocol, { case ACTION_RESTART: child_cfg->get_ref(child_cfg); - this->ike_sa->initiate(this->ike_sa, child_cfg, + status = this->ike_sa->initiate(this->ike_sa, child_cfg, child_sa->get_reqid(child_sa), NULL, NULL); break; case ACTION_ROUTE: @@ -168,15 +170,18 @@ static bool delete_child(private_quick_delete_t *this, protocol_id_t protocol, child_cfg->destroy(child_cfg); } } - this->ike_sa->destroy_child_sa(this->ike_sa, protocol, spi); - - return TRUE; + if (status == SUCCESS) + { + this->ike_sa->destroy_child_sa(this->ike_sa, protocol, spi); + } + return status; } METHOD(task_t, build_i, status_t, private_quick_delete_t *this, message_t *message) { - if (delete_child(this, this->protocol, this->spi, FALSE) || this->force) + if (delete_child(this, this->protocol, this->spi, FALSE) == SUCCESS || + this->force) { delete_payload_t *delete_payload; @@ -206,6 +211,7 @@ METHOD(task_t, process_r, status_t, payload_t *payload; delete_payload_t *delete_payload; protocol_id_t protocol; + status_t status = SUCCESS; uint32_t spi; payloads = message->create_payload_enumerator(message); @@ -224,18 +230,27 @@ METHOD(task_t, process_r, status_t, { DBG1(DBG_IKE, "received DELETE for %N CHILD_SA with SPI %.8x", protocol_id_names, protocol, ntohl(spi)); - if (!delete_child(this, protocol, spi, TRUE)) + status = delete_child(this, protocol, spi, TRUE); + if (status == NOT_FOUND) { DBG1(DBG_IKE, "CHILD_SA not found, ignored"); - continue; + status = SUCCESS; + } + if (status != SUCCESS) + { + break; } } spis->destroy(spis); } + if (status != SUCCESS) + { + break; + } } payloads->destroy(payloads); - return SUCCESS; + return status; } METHOD(task_t, build_r, status_t,