On https://bugs.debian.org/1066059, Salvatore Bonaccorso wrote: > The following vulnerability was published for libreswan. > > CVE-2024-2357[0]: > | The Libreswan Project was notified of an issue causing libreswan to > | restart under some IKEv2 retransmit scenarios when a connection is > | configured to use PreSharedKeys (authby=secret) and the connection > | cannot find a matching configured secret. When such a connection is > | automatically added on startup using the auto= keyword, it can cause > | repeated crashes leading to a Denial of Service.
I'm attaching a proposed debdiff for libreswan for bookworm, from the current 4.10-2+deb12u1 to 4.10-2+deb12u3 (4.10-2+deb12u2 appears to have never made it to publication, which is likely my fault). This is also pushed to the debian/bookworm branch at https://salsa.debian.org/debian/libreswan. In addition to resolving CVE-2024-2357, this debdiff rolls up three other low-priority CVEs as well, using changesets from upstream. If anyone from the security team could confirm this, i would be happy to go ahead with the upload to bookworm-security. Regards, --dkg
diff --git a/debian/changelog b/debian/changelog index f2851b483e..c51e93d091 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,17 @@ +libreswan (4.10-2+deb12u3) bookworm-security; urgency=medium + + * Fix CVE 2024-2357 (Closes: #1066059) + + -- Daniel Kahn Gillmor <d...@fifthhorseman.net> Tue, 12 Mar 2024 00:14:33 -0400 + +libreswan (4.10-2+deb12u2) bookworm-security; urgency=medium + + * Fix CVE-2023-38710 + * Fix CVE-2023-38711 + * Fix CVE-2023-38712 + + -- Daniel Kahn Gillmor <d...@fifthhorseman.net> Mon, 07 Aug 2023 17:46:29 -0400 + libreswan (4.10-2+deb12u1) bookworm; urgency=medium * Fix CVE-2023-30570 (Closes: #1035542) diff --git a/debian/patches/0006-CVE-2023-38710-Invalid-IKEv2-REKEY-proposal-causes-re.patch b/debian/patches/0006-CVE-2023-38710-Invalid-IKEv2-REKEY-proposal-causes-re.patch new file mode 100644 index 0000000000..f930a5761c --- /dev/null +++ b/debian/patches/0006-CVE-2023-38710-Invalid-IKEv2-REKEY-proposal-causes-re.patch @@ -0,0 +1,261 @@ +From: Daniel Kahn Gillmor <d...@fifthhorseman.net> +Date: Mon, 7 Aug 2023 17:40:21 -0400 +Subject: CVE-2023-38710: Invalid IKEv2 REKEY proposal causes restart + +This alert (and any updates) are available at the following URLs: +https://libreswan.org/security/CVE-2023-38710/ + +The Libreswan Project was notified by "X1AOxiang" of an issue with receiving +a malformed IKEv2 REKEY packet would cause a crash and restart of the libreswan +pluto daemon. When sent continuously, this could lead to a denial of service attack. + +Severity: Medium +Vulnerable versions : libreswan 3.20 - 4.11 +Not vulnerable : libreswan 3.0 - 3.19, 4.12+ + +Vulnerability information +========================= +When an IKEv2 Child SA REKEY packet contains an invalid IPsec protocol ID number +of 0 or 1, an error notify INVALID_SPI is sent back. The notify payload's +protocol ID is copied from the incoming packet, but the code that verifies +outgoing packets fails an assertion that the protocol ID must be ESP (2) or AH(3) +and causes the pluto daemon to crash and restart. + +Exploitation +============ +IKEv2 REKEY requests are only processed when received from authenticated peers, +limiting the scope of possible attackers to peers who have successfully +authenticated. + +Workaround +========== +There is no workarounds, please apply the supplied patches or upgrade. + +History +======= +* 2017 Vulnerable code introduced in libreswan 3.20 +* 2023-06-07 Report received via Red Hat +* 2023-07-19 Prerelease of CVE notification and patches to support customers +* 2023-08-04 Release of patch and libreswan 4.12 + +Credits +======= +This vulnerability was found and reported by X1AOxiang to Red Hat. Thanks to +Daiki Ueno for contacting the Libreswan Project. +--- + programs/pluto/ikev2_create_child_sa.c | 149 ++++++++++++++++++++------------- + 1 file changed, 89 insertions(+), 60 deletions(-) + +diff --git a/programs/pluto/ikev2_create_child_sa.c b/programs/pluto/ikev2_create_child_sa.c +index 9e29032..e4bf588 100644 +--- a/programs/pluto/ikev2_create_child_sa.c ++++ b/programs/pluto/ikev2_create_child_sa.c +@@ -175,80 +175,102 @@ static void emancipate_larval_ike_sa(struct ike_sa *old_ike, struct child_sa *ne + release_whack(new_ike->sa.st_logger, HERE); + } + +-static struct child_sa *find_v2N_REKEY_SA_child(struct ike_sa *ike, +- struct msg_digest *md) ++/* ++ * Find the Child SA identified by the v2N_REKEY_SA payload. ++ * ++ * FALSE: payload corrupt; caller should respond with the fatal ++ * v2N_INVALID_SYNTAX. ++ * ++ * TRUE, CHILD==NULL: payload ok but no matching Child SA was ++ * found. The v2N_CHILD_SA_NOT_FOUND response already recorded using ++ * information extracted from the rekey notify payload. ++ * ++ * TRUE, CHILD!=NULL: payload ok, matching Child SA found. ++ */ ++ ++static bool find_v2N_REKEY_SA_child(struct ike_sa *ike, ++ struct msg_digest *md, ++ struct child_sa **child) + { ++ *child = NULL; ++ + /* +- * Previously found by the state machine. ++ * Previously decoded and minimially validated by the state ++ * machine using ikev2_notify_desc (i.e., more validation ++ * required). + */ ++ + const struct payload_digest *rekey_sa_payload = md->pd[PD_v2N_REKEY_SA]; + if (rekey_sa_payload == NULL) { + llog_pexpect(ike->sa.st_logger, HERE, + "rekey child can't find its rekey_sa payload"); +- return NULL; +- } +-#if 0 +- /* XXX: this would require a separate .pd_next link? */ +- if (rekey_sa_payload->next != NULL) { +- /* will tolerate multiple */ +- log_state(RC_LOG_SERIOUS, &ike->sa, +- "ignoring duplicate v2N_REKEY_SA in exchange"); ++ return false; + } +-#endif ++ ++ const struct ikev2_notify *rekey_notify = &rekey_sa_payload->payload.v2n; + + /* +- * find old state to rekey ++ * Check the protocol. ++ * ++ * "ikev2_notify_desc" allows 0, IKE, ESP and AH; reject the ++ * first two. Will also need to check that the protocl ++ * matches that extablished by the Child SA. + */ + +- const struct ikev2_notify *rekey_notify = &rekey_sa_payload->payload.v2n; ++ if (rekey_notify->isan_protoid != PROTO_IPSEC_ESP && ++ rekey_notify->isan_protoid != PROTO_IPSEC_AH) { ++ esb_buf b; ++ llog_sa(RC_LOG, ike, ++ "CREATE_CHILD_SA IPsec SA rekey invalid Protocol ID %s", ++ enum_show(&ikev2_notify_protocol_id_names, rekey_notify->isan_protoid, &b)); ++ return false; ++ } ++ ++#ifndef ldbg_sa ++#define ldbg_sa(SA, ...) ldbg((SA)->sa.st_logger, __VA_ARGS__) ++#endif ++ + esb_buf b; +- dbg("CREATE_CHILD_SA IPsec SA rekey Protocol %s", +- enum_show(&ikev2_notify_protocol_id_names, rekey_notify->isan_protoid, &b)); ++ ldbg_sa(ike, "CREATE_CHILD_SA IPsec SA rekey Protocol %s", ++ enum_show(&ikev2_notify_protocol_id_names, rekey_notify->isan_protoid, &b)); ++ ++ /* ++ * Get the SPI. ++ * ++ * The SPI (and the protoid?) can be used to find the Child SA ++ * to rekey. ++ */ + + if (rekey_notify->isan_spisize != sizeof(ipsec_spi_t)) { +- log_state(RC_LOG, &ike->sa, +- "CREATE_CHILD_SA IPsec SA rekey invalid spi size %u", +- rekey_notify->isan_spisize); +- record_v2N_response(ike->sa.st_logger, ike, md, v2N_INVALID_SYNTAX, +- NULL/*empty data*/, ENCRYPTED_PAYLOAD); +- return NULL; ++ llog_sa(RC_LOG, ike, ++ "CREATE_CHILD_SA IPsec SA rekey invalid spi size %u", ++ rekey_notify->isan_spisize); ++ return false; + } + +- ipsec_spi_t spi = 0; ++#ifndef pbs_in_thing ++#define pbs_in_thing(PBS, THING, NAME) pbs_in_raw(PBS, &(THING), sizeof(THING), NAME) ++#endif ++ ++ ipsec_spi_t spi = 0; /* network ordered */ + struct pbs_in rekey_pbs = rekey_sa_payload->pbs; +- diag_t d = pbs_in_raw(&rekey_pbs, &spi, sizeof(spi), "SPI"); ++ diag_t d = pbs_in_thing(&rekey_pbs, spi, "SPI"); + if (d != NULL) { ++ /* for instance, truncated SPI */ + llog_diag(RC_LOG, ike->sa.st_logger, &d, "%s", ""); +- record_v2N_response(ike->sa.st_logger, ike, md, v2N_INVALID_SYNTAX, +- NULL/*empty data*/, ENCRYPTED_PAYLOAD); +- return NULL; /* cannot happen; XXX: why? */ ++ return false; + } + + if (spi == 0) { +- log_state(RC_LOG, &ike->sa, +- "CREATE_CHILD_SA IPsec SA rekey contains zero SPI"); +- record_v2N_response(ike->sa.st_logger, ike, md, v2N_INVALID_SYNTAX, +- NULL/*empty data*/, ENCRYPTED_PAYLOAD); +- return NULL; +- } +- +- if (rekey_notify->isan_protoid != PROTO_IPSEC_ESP && +- rekey_notify->isan_protoid != PROTO_IPSEC_AH) { +- esb_buf b; +- log_state(RC_LOG, &ike->sa, +- "CREATE_CHILD_SA IPsec SA rekey invalid Protocol ID %s", +- enum_show(&ikev2_notify_protocol_id_names, rekey_notify->isan_protoid, &b)); +- record_v2N_spi_response(ike->sa.st_logger, ike, md, +- rekey_notify->isan_protoid, &spi, +- v2N_CHILD_SA_NOT_FOUND, +- NULL/*empty data*/, ENCRYPTED_PAYLOAD); +- return NULL; ++ llog_sa(RC_LOG, ike, ++ "CREATE_CHILD_SA IPsec SA rekey contains zero SPI"); ++ return false; + } + + esb_buf protoesb; +- dbg("CREATE_CHILD_S to rekey IPsec SA(0x%08" PRIx32 ") Protocol %s", +- ntohl((uint32_t) spi), +- enum_show(&ikev2_notify_protocol_id_names, rekey_notify->isan_protoid, &protoesb)); ++ ldbg_sa(ike, "CREATE_CHILD_SA to rekey IPsec SA(0x%08" PRIx32 ") Protocol %s", ++ ntohl((uint32_t) spi), ++ enum_show(&ikev2_notify_protocol_id_names, rekey_notify->isan_protoid, &protoesb)); + + /* + * From 1.3.3. Rekeying Child SAs with the CREATE_CHILD_SA +@@ -257,29 +279,31 @@ static struct child_sa *find_v2N_REKEY_SA_child(struct ike_sa *ike, + * exchange initiator would expect in inbound ESP or AH + * packets. + * +- * From our POV, that's the outbound SPI. ++ * From our, the responder's POV, that's the outbound SPI. + */ ++ + struct child_sa *replaced_child = find_v2_child_sa_by_outbound_spi(ike, rekey_notify->isan_protoid, spi); + if (replaced_child == NULL) { + esb_buf b; +- log_state(RC_LOG, &ike->sa, +- "CREATE_CHILD_SA no such IPsec SA to rekey SA(0x%08" PRIx32 ") Protocol %s", +- ntohl((uint32_t) spi), +- enum_show(&ikev2_notify_protocol_id_names, rekey_notify->isan_protoid, &b)); ++ llog_sa(RC_LOG, ike, ++ "CREATE_CHILD_SA no such IPsec SA to rekey SA(0x%08" PRIx32 ") Protocol %s", ++ ntohl((uint32_t) spi), ++ enum_show(&ikev2_notify_protocol_id_names, rekey_notify->isan_protoid, &b)); + record_v2N_spi_response(ike->sa.st_logger, ike, md, + rekey_notify->isan_protoid, &spi, + v2N_CHILD_SA_NOT_FOUND, + NULL/*empty data*/, ENCRYPTED_PAYLOAD); +- return NULL; ++ return true; + } + + connection_buf cb; +- dbg("#%lu hasa a rekey request for "PRI_CONNECTION" #%lu TSi TSr", +- ike->sa.st_serialno, +- pri_connection(replaced_child->sa.st_connection, &cb), +- replaced_child->sa.st_serialno); ++ ldbg_sa(ike, "#%lu hasa a rekey request for "PRI_CONNECTION" #%lu TSi TSr", ++ ike->sa.st_serialno, ++ pri_connection(replaced_child->sa.st_connection, &cb), ++ replaced_child->sa.st_serialno); + +- return replaced_child; ++ *child = replaced_child; ++ return true; + } + + static bool record_v2_rekey_ike_message(struct ike_sa *ike, +@@ -628,8 +652,13 @@ stf_status process_v2_CREATE_CHILD_SA_rekey_child_request(struct ike_sa *ike, + struct child_sa *larval_child, + struct msg_digest *md) + { ++ struct child_sa *predecessor = NULL; ++ if (!find_v2N_REKEY_SA_child(ike, md, &predecessor)) { ++ record_v2N_response(ike->sa.st_logger, ike, md, v2N_INVALID_SYNTAX, ++ NULL/*empty data*/, ENCRYPTED_PAYLOAD); ++ return STF_FATAL; ++ } + +- struct child_sa *predecessor = find_v2N_REKEY_SA_child(ike, md); + if (predecessor == NULL) { + /* already logged; already recorded */ + return STF_OK; /*IKE*/ diff --git a/debian/patches/0007-CVE-2023-38711-Invalid-IKEv1-Quick-Mode-ID-causes-res.patch b/debian/patches/0007-CVE-2023-38711-Invalid-IKEv1-Quick-Mode-ID-causes-res.patch new file mode 100644 index 0000000000..728590a0bb --- /dev/null +++ b/debian/patches/0007-CVE-2023-38711-Invalid-IKEv1-Quick-Mode-ID-causes-res.patch @@ -0,0 +1,94 @@ +From: Daniel Kahn Gillmor <d...@fifthhorseman.net> +Date: Mon, 7 Aug 2023 17:42:36 -0400 +Subject: CVE-2023-38711: Invalid IKEv1 Quick Mode ID causes restart + +This alert (and any patch files and updates) are available at: +https://libreswan.org/security/CVE-2023-38711/ + +The Libreswan Project was notified by "X1AOxiang" of an issue with +receiving a malformed IKEv1 Quick Mode packet which would cause a crash +and restart of the libreswan pluto daemon. When sent continuously, +this could lead to a denial of service attack. + +Severity: Medium +Vulnerable versions : libreswan 4.6 - 4.11 +Not vulnerable : libreswan 3.0 - 4.5, 4.12+ + +Vulnerability information +========================= +When an IKEv1 Quick Mode connection configured with ID_IPV4_ADDR or +ID_IPV6_ADDR, receives an IDcr payload with ID_FQDN, a null pointer +dereference causes a crash and restart of the pluto daemon. + +Exploitation +============ +IKEv1 Quick Mode requests are only processed when received from +authenticated peers, limiting the scope of possible attackers to peers +who have successfully authenticated. + +Workaround +========== +There is no workarounds, although in general IKEv1 users are recommended +to migrate to IKEv2 (see also RFC 9395: Deprecation of IKE Version 1). +Please apply the supplied patches or upgrade. + +History +======= +* 2021-10-09 Vulnerable code introduced in libreswan 4.6 +* 2023-06-18 Report received via https://github.com/libreswan/libreswan/issues/1172 +* 2023-07-19 Prerelease of CVE notification and patches to support customers +* 2023-08-04 Updated patch based on feedback by Wolfgang Nothdurft <wolfg...@linogate.de> +* 2023-08-04 Release of patch and libreswan 4.12 + +Credits +======= +This vulnerability was found and reported by X1AOxiang. +--- + programs/pluto/ikev1_quick.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/programs/pluto/ikev1_quick.c b/programs/pluto/ikev1_quick.c +index 95f115f..0e22f1f 100644 +--- a/programs/pluto/ikev1_quick.c ++++ b/programs/pluto/ikev1_quick.c +@@ -1911,6 +1911,11 @@ static struct connection *fc_try(const struct connection *c, + const ip_selector *local_client, + const ip_selector *remote_client) + { ++ if (selector_is_unset(local_client) || ++ selector_is_unset(remote_client)) { ++ return NULL; ++ } ++ + struct connection *best = NULL; + policy_prio_t best_prio = BOTTOM_PRIO; + const bool remote_is_host = selector_eq_address(*remote_client, +@@ -2094,6 +2099,11 @@ static struct connection *fc_try_oppo(const struct connection *c, + const ip_selector *local_client, + const ip_selector *remote_client) + { ++ if (selector_is_unset(local_client) || ++ selector_is_unset(remote_client)) { ++ return NULL; ++ } ++ + struct connection *best = NULL; + policy_prio_t best_prio = BOTTOM_PRIO; + +@@ -2215,6 +2225,16 @@ struct connection *find_v1_client_connection(struct connection *const c, + str_selectors(local_client, remote_client, &sb)); + } + ++ if (selector_is_unset(local_client)) { ++ dbg("peer's local client is not set"); ++ return NULL; ++ } ++ ++ if (selector_is_unset(remote_client)) { ++ dbg("peer's remote client is not set"); ++ return NULL; ++ } ++ + /* + * Give priority to current connection + * but even greater priority to a routed concrete connection. diff --git a/debian/patches/0008-CVE-2023-38712-Invalid-IKEv1-repeat-IKE-SA-delete-cau.patch b/debian/patches/0008-CVE-2023-38712-Invalid-IKEv1-repeat-IKE-SA-delete-cau.patch new file mode 100644 index 0000000000..8c3fe39bbf --- /dev/null +++ b/debian/patches/0008-CVE-2023-38712-Invalid-IKEv1-repeat-IKE-SA-delete-cau.patch @@ -0,0 +1,267 @@ +From: Daniel Kahn Gillmor <d...@fifthhorseman.net> +Date: Mon, 7 Aug 2023 17:45:14 -0400 +Subject: CVE-2023-38712: Invalid IKEv1 repeat IKE SA delete causes crash and + restart + +This alert (and any updates) are available at the following URLs: +https://libreswan.org/security/CVE-2023-38712/ + +The Libreswan Project was notified by "X1AOxiang" of an issue with +receiving a malformed IKEv1 Delete/Notify packet would cause a crash +and restart of the libreswan pluto daemon. When sent continuously, +this could lead to a denial of service attack. + +Severity: Medium +Vulnerable versions : libreswan 3.00 - 4.11 +Not vulnerable : libreswan 4.12+ + +Vulnerability information +========================= +When an IKEv1 ISAKMP SA Informational Exchange packet contains a +Delete/Notify payload followed by further Notifies that act on the ISAKMP +SA, such as a duplicated Delete/Notify message, a null pointer dereference +on the deleted state causes the pluto daemon to crash and restart. + +Exploitation +============ +IKEv1 Delete/Notify requests are only processed when received from authenticated +peers, limiting the scope of possible attackers to peers who have successfully +authenticated. + +Workaround +========== +There is no workarounds, please apply the supplied patches or upgrade. + +History +======= +* 2013 Vulnerable code was present in the first release of libreswan, 3.0 + (likely the same vulnerability exists in all openswan versions) +* 2023-06-07 Report received via Red Hat +* 2023-07-19 Prerelease of CVE notification and patches to support customers +* 2023-08-04 Release of patch and libreswan 4.12 + +Credits +======= +This vulnerability was found and reported by X1AOxiang to Red Hat. Thanks to +Daiki Ueno for contacting the Libreswan Project. +--- + programs/pluto/ikev1.c | 37 ++++++++++++------------ + programs/pluto/ikev1_main.c | 70 +++++++++++++++++++++------------------------ + programs/pluto/ipsec_doi.h | 4 +-- + 3 files changed, 53 insertions(+), 58 deletions(-) + +diff --git a/programs/pluto/ikev1.c b/programs/pluto/ikev1.c +index 401618b..56659a9 100644 +--- a/programs/pluto/ikev1.c ++++ b/programs/pluto/ikev1.c +@@ -1794,7 +1794,6 @@ void process_packet_tail(struct msg_digest *md) + const struct state_v1_microcode *smc = md->smc; + enum state_kind from_state = smc->state; + bool new_iv_set = md->new_iv_set; +- bool self_delete = false; + + if (md->hdr.isa_flags & ISAKMP_FLAGS_v1_ENCRYPTION) { + +@@ -2269,38 +2268,40 @@ void process_packet_tail(struct msg_digest *md) + } + } + ++ pexpect(st == md->v1_st); /* could be NULL */ ++ + for (struct payload_digest *p = md->chain[ISAKMP_NEXT_D]; + p != NULL; p = p->next) { +- self_delete |= accept_delete(md, p); +- if (DBGP(DBG_BASE)) { +- DBG_dump("del:", p->pbs.cur, +- pbs_left(&p->pbs)); ++ if (!accept_delete(&st, md, p)) { ++ ldbg(md->md_logger, "bailing with bad delete message"); ++ return; + } +- if (md->v1_st != st) { +- pexpect(md->v1_st == NULL); +- dbg("zapping ST as accept_delete() zapped MD.ST"); +- st = md->v1_st; ++ if (st == NULL) { ++ ldbg(md->md_logger, "bailing due to self-inflicted delete"); ++ return; + } + } + ++ pexpect(st == md->v1_st); /* could be NULL */ ++ + for (struct payload_digest *p = md->chain[ISAKMP_NEXT_VID]; + p != NULL; p = p->next) { + handle_v1_vendorid(md, pbs_in_left_as_shunk(&p->pbs), + (st != NULL ? st->st_logger : md->md_logger)); + } + +- if (self_delete) { +- accept_self_delete(md); +- st = md->v1_st; +- /* note: st ought to be NULL from here on */ +- } ++ pexpect(st == md->v1_st); /* could be NULL */ + +- pexpect(st == md->v1_st); +- statetime_t start = statetime_start(md->v1_st); + /* +- * XXX: danger - the .informational() processor deletes ST; +- * and then tunnels this loss through MD.ST. ++ * XXX: Danger. ++ * ++ * ++ the .informational() processor deletes ST; and then ++ * tries to tunnel this loss back through MD.ST. ++ * ++ * ++ the .aggressive() processor replaces .V1_ST with the IKE ++ * SA? + */ ++ statetime_t start = statetime_start(st); + stf_status e = smc->processor(st, md); + complete_v1_state_transition(md->v1_st, md, e); + statetime_stop(&start, "%s()", __func__); +diff --git a/programs/pluto/ikev1_main.c b/programs/pluto/ikev1_main.c +index 21765d4..736767f 100644 +--- a/programs/pluto/ikev1_main.c ++++ b/programs/pluto/ikev1_main.c +@@ -1975,19 +1975,25 @@ void send_v1_delete(struct state *st) + * @param md Message Digest + * @param p Payload digest + * +- * returns TRUE to indicate st needs to be deleted. +- * We dare not do that ourselves because st is still in use. +- * accept_self_delete must be called to do this +- * at a more appropriate time. ++ * DANGER: this may stomp on *SDP and md->v1_st. ++ * ++ * Returns FALSE when the payload is crud. + */ +-bool accept_delete(struct msg_digest *md, +- struct payload_digest *p) ++bool accept_delete(struct state **stp, ++ struct msg_digest *md, ++ struct payload_digest *p) + { +- struct state *st = md->v1_st; ++ struct state *st = *stp; + struct isakmp_delete *d = &(p->payload.delete); + size_t sizespi; + int i; +- bool self_delete = false; ++ ++ /* Need state for things to be encrypted */ ++ if (st == NULL) { ++ llog(RC_LOG_SERIOUS, md->md_logger, ++ "ignoring Delete SA with no matching state"); ++ return false; ++ } + + /* We only listen to encrypted notifications */ + if (!md->encrypted) { +@@ -2022,7 +2028,7 @@ bool accept_delete(struct msg_digest *md, + + case PROTO_IPCOMP: + /* nothing interesting to delete */ +- return false; ++ return true; + + default: + { +@@ -2081,21 +2087,20 @@ bool accept_delete(struct msg_digest *md, + * identities + */ + log_state(RC_LOG_SERIOUS, st, "ignoring Delete SA payload: ISAKMP SA used to convey Delete has different IDs from ISAKMP SA it deletes"); +- } else if (dst == st) { +- /* +- * remember this for later: +- * we need st to do any remaining deletes +- */ +- self_delete = true; + } else { + /* note: this code is cloned for handling self_delete */ +- log_state(RC_LOG_SERIOUS, st, "received Delete SA payload: deleting ISAKMP State #%lu", ++ log_state(RC_LOG_SERIOUS, st, "received Delete SA payload: %sdeleting ISAKMP State #%lu", ++ (dst == st ? "self-" : ""), + dst->st_serialno); + if (nat_traversal_enabled && dst->st_connection->ikev1_natt != NATT_NONE) { + nat_traversal_change_port_lookup(md, dst); + v1_maybe_natify_initiator_endpoints(st, HERE); +- } ++ } + delete_state(dst); ++ if (dst == st) { ++ *stp = dst = st = md->v1_st = NULL; ++ return true; ++ } + } + } else { + /* +@@ -2155,12 +2160,15 @@ bool accept_delete(struct msg_digest *md, + event_force(EVENT_SA_REPLACE, dst); + } else { + log_state(RC_LOG_SERIOUS, st, +- "received Delete SA(0x%08" PRIx32 ") payload: deleting IPsec State #%lu", ++ "received Delete SA(0x%08" PRIx32 ") payload: %sdeleting IPsec State #%lu", + ntohl(spi), ++ (st == dst ? "self-" : ""), + dst->st_serialno); + delete_state(dst); +- if (md->v1_st == dst) +- md->v1_st = NULL; ++ if (md->v1_st == dst) { ++ *stp = dst = md->v1_st = NULL; ++ return true; ++ } + } + + /* +@@ -2185,29 +2193,15 @@ bool accept_delete(struct msg_digest *md, + * states tied to the + * connection? + */ ++ dbg("%s() self-inflicted delete of ISAKMP", __func__); + delete_states_by_connection(&rc); +- md->v1_st = NULL; ++ *stp = st = dst = md->v1_st = NULL; ++ return true; + } + } + } + } + } + +- return self_delete; +-} +- +-/* now it is safe to delete our sponsor */ +-void accept_self_delete(struct msg_digest *md) +-{ +- struct state *st = md->v1_st; +- +- /* note: this code is cloned from handling ISAKMP non-self_delete */ +- log_state(RC_LOG_SERIOUS, st, "received Delete SA payload: self-deleting ISAKMP State #%lu", +- st->st_serialno); +- if (nat_traversal_enabled && st->st_connection->ikev1_natt != NATT_NONE) { +- nat_traversal_change_port_lookup(md, st); +- v1_maybe_natify_initiator_endpoints(st, HERE); +- } +- delete_state(st); +- md->v1_st = st = NULL; ++ return true; + } +diff --git a/programs/pluto/ipsec_doi.h b/programs/pluto/ipsec_doi.h +index 41fe5da..dc45602 100644 +--- a/programs/pluto/ipsec_doi.h ++++ b/programs/pluto/ipsec_doi.h +@@ -31,9 +31,9 @@ extern void ipsecdoi_replace(struct state *st, unsigned long try); + + extern void init_phase2_iv(struct state *st, const msgid_t *msgid); + +-extern bool accept_delete(struct msg_digest *md, ++extern bool accept_delete(struct state **st, ++ struct msg_digest *md, + struct payload_digest *p); +-extern void accept_self_delete(struct msg_digest *md); + + extern stf_status send_isakmp_notification(struct state *st, + uint16_t type, const void *data, diff --git a/debian/patches/0009-CVE-2024-2357-Missing-PreSharedKey-for-connection-ca.patch b/debian/patches/0009-CVE-2024-2357-Missing-PreSharedKey-for-connection-ca.patch new file mode 100644 index 0000000000..cda8fa3802 --- /dev/null +++ b/debian/patches/0009-CVE-2024-2357-Missing-PreSharedKey-for-connection-ca.patch @@ -0,0 +1,45 @@ +From: Andrew Cagney <cag...@gnu.org> +Date: Wed, 28 Feb 2024 08:29:53 -0500 +Subject: CVE-2024-2357: Missing PreSharedKey for connection can cause crash + +This is a combination of two upstream commits: + +2ec448884a7467743699803f8a36ee28d237666c + + ikev2: return STF_FATAL when initiator fails to emit AUTH packet + +and: + +16272f2475d25baab58fbed2af7c67cfb459137f + + ikev2: always return STF_FATAL if emitting AUTH fails + + Fix: + ikev2: return STF_FATAL when initiator fails to emit AUTH packet + which really fixed the responder. +--- + programs/pluto/ikev2_ike_auth.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/programs/pluto/ikev2_ike_auth.c b/programs/pluto/ikev2_ike_auth.c +index 192eb1b..491053f 100644 +--- a/programs/pluto/ikev2_ike_auth.c ++++ b/programs/pluto/ikev2_ike_auth.c +@@ -397,7 +397,7 @@ stf_status initiate_v2_IKE_AUTH_request_signature_continue(struct ike_sa *ike, + /* send out the AUTH payload */ + + if (!emit_local_v2AUTH(ike, auth_sig, &ike->sa.st_v2_id_payload.mac, request.pbs)) { +- return STF_INTERNAL_ERROR; ++ return STF_FATAL; + } + + if (LIN(POLICY_MOBIKE, ike->sa.st_connection->policy)) { +@@ -1267,7 +1267,7 @@ static stf_status process_v2_IKE_AUTH_request_auth_signature_continue(struct ike + /* now send AUTH payload */ + + if (!emit_local_v2AUTH(ike, auth_sig, &ike->sa.st_v2_id_payload.mac, response.pbs)) { +- return STF_INTERNAL_ERROR; ++ return STF_FATAL; + } + ike->sa.st_v2_ike_intermediate.used = false; + diff --git a/debian/patches/series b/debian/patches/series index 4620d63e0c..7c65707820 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -3,3 +3,7 @@ 0004-ikev1-policy-defaults-to-drop.patch 0004-Include-features.h-to-enable-NSPR-workaround-for-854.patch 0005-Fix-CVE-2023-30570.patch +0006-CVE-2023-38710-Invalid-IKEv2-REKEY-proposal-causes-re.patch +0007-CVE-2023-38711-Invalid-IKEv1-Quick-Mode-ID-causes-res.patch +0008-CVE-2023-38712-Invalid-IKEv1-repeat-IKE-SA-delete-cau.patch +0009-CVE-2024-2357-Missing-PreSharedKey-for-connection-ca.patch
signature.asc
Description: PGP signature