diff --git a/SPECS/libreswan/CVE-2026-12413.patch b/SPECS/libreswan/CVE-2026-12413.patch new file mode 100644 index 00000000000..d0edd87718f --- /dev/null +++ b/SPECS/libreswan/CVE-2026-12413.patch @@ -0,0 +1,28 @@ +From cb5fd3d27d8d260f96bbe0e0d6de6e12980bd536 Mon Sep 17 00:00:00 2001 +From: Azure Linux Security Servicing Account + +Date: Fri, 3 Jul 2026 09:49:24 +0000 +Subject: [PATCH] Patch CVE-2026-12413 for libreswan (applied via patch -p1) + +Signed-off-by: Azure Linux Security Servicing Account +Upstream-reference: https://libreswan.org/security/CVE-2026-12413/libreswan-4.15-CVE-2026-12413.patch +--- + programs/pluto/ikev2_message.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/programs/pluto/ikev2_message.c b/programs/pluto/ikev2_message.c +index 84b289c..a691346 100644 +--- a/programs/pluto/ikev2_message.c ++++ b/programs/pluto/ikev2_message.c +@@ -1000,7 +1000,7 @@ struct msg_digest *reassemble_v2_incoming_fragments(struct v2_incoming_fragments + passert(md->chain[ISAKMP_NEXT_v2SK] == NULL); + passert(md->chain[ISAKMP_NEXT_v2SKF] != NULL); + pexpect(md->chain[ISAKMP_NEXT_v2SKF]->payload.v2skf.isaskf_number == 1); +- passert(md->digest_roof < elemsof(md->digest)); ++ passert(md->digest_roof <= elemsof(md->digest)); + + /* + * Pass 1: Compute the total payload size. +-- +2.45.4 + diff --git a/SPECS/libreswan/CVE-2026-50721.patch b/SPECS/libreswan/CVE-2026-50721.patch new file mode 100644 index 00000000000..a2c048c588e --- /dev/null +++ b/SPECS/libreswan/CVE-2026-50721.patch @@ -0,0 +1,296 @@ +From 318b43e80938748062213a760a1158887f386f74 Mon Sep 17 00:00:00 2001 +From: Azure Linux Security Servicing Account + +Date: Fri, 3 Jul 2026 09:48:08 +0000 +Subject: [PATCH] Patch CVE-2026-50721 for libreswan (applied via patch -p1) + +Signed-off-by: Azure Linux Security Servicing Account +Upstream-reference: https://libreswan.org/security/CVE-2026-50721/libreswan-4.15-CVE-2026-50721.patch +--- + lib/libswan/pubkey_rsa.c | 52 ++---------- + .../patches/0002-debian-pam.d-pluto.patch | 43 ---------- + .../patches/0002-debian-pam.d-pluto.patch | 43 ---------- + .../libreswan-3.23-del-notify.patch | 14 ---- + .../libreswan-3.23-impair-del-notify.patch | 79 ------------------- + 5 files changed, 7 insertions(+), 224 deletions(-) + delete mode 100644 packaging/debian/patches/0002-debian-pam.d-pluto.patch + delete mode 100644 packaging/devuan/patches/0002-debian-pam.d-pluto.patch + delete mode 100644 testing/pluto/delete-sa-02/libreswan-3.23-del-notify.patch + delete mode 100644 testing/pluto/delete-sa-02/libreswan-3.23-impair-del-notify.patch + +diff --git a/lib/libswan/pubkey_rsa.c b/lib/libswan/pubkey_rsa.c +index 38b44ab..d2f36cb 100644 +--- a/lib/libswan/pubkey_rsa.c ++++ b/lib/libswan/pubkey_rsa.c +@@ -402,58 +402,20 @@ static bool RSA_authenticate_signature_raw_rsa(const struct crypt_mac *expected_ + *expected_hash); + } + +- /* +- * Use the same space used by the out going hash. +- */ +- +- SECItem decrypted_signature = { +- .type = siBuffer, +- }; +- +- if (SECITEM_AllocItem(NULL, &decrypted_signature, signature.len) == NULL) { +- llog_nss_error(RC_LOG, logger, "allocating space for decrypted RSA signature"); +- return false; +- } +- + /* NSS doesn't do const */ +- const SECItem encrypted_signature = { +- .type = siBuffer, +- .data = DISCARD_CONST(unsigned char *, signature.ptr), +- .len = signature.len, +- }; +- +- if (PK11_VerifyRecover(seckey_public, &encrypted_signature, &decrypted_signature, +- lsw_nss_get_password_context(logger)) != SECSuccess) { +- SECITEM_FreeItem(&decrypted_signature, PR_FALSE/*not-pointer*/); +- dbg("NSS RSA verify: decrypting signature is failed"); +- *fatal_diag = NULL; +- return false; +- } + +- if (DBGP(DBG_CRYPT)) { +- LLOG_JAMBUF(DEBUG_STREAM, logger, buf) { +- jam_string(buf, "NSS RSA verify: decrypted sig: "); +- jam_nss_secitem(buf, &decrypted_signature); +- } +- } ++ const SECItem signature_secitem = ++ same_shunk_as_secitem(signature, siBuffer); ++ const SECItem expected_hash_secitem = ++ same_shunk_as_secitem(HUNK_AS_SHUNK(*expected_hash), siBuffer); + +- /* +- * Expect the matching hash to appear at the end. See above +- * for length check. It may, or may not, be prefixed by a +- * PKCS#1 1.5 RSA ASN.1 blob. +- */ +- passert(decrypted_signature.len >= expected_hash->len); +- uint8_t *start = (decrypted_signature.data +- + decrypted_signature.len +- - expected_hash->len); +- if (!memeq(start, expected_hash->ptr, expected_hash->len)) { +- dbg("RSA Signature NOT verified"); +- SECITEM_FreeItem(&decrypted_signature, PR_FALSE/*not-pointer*/); ++ if (PK11_Verify(seckey_public, &signature_secitem, &expected_hash_secitem, ++ lsw_nss_get_password_context(logger)) != SECSuccess) { ++ dbg("NSS RSA verify: decrypting signature is failed"); + *fatal_diag = NULL; + return false; + } + +- SECITEM_FreeItem(&decrypted_signature, PR_FALSE/*not-pointer*/); + *fatal_diag = NULL; + return true; + } +diff --git a/packaging/debian/patches/0002-debian-pam.d-pluto.patch b/packaging/debian/patches/0002-debian-pam.d-pluto.patch +deleted file mode 100644 +index 431a496..0000000 +--- a/packaging/debian/patches/0002-debian-pam.d-pluto.patch ++++ /dev/null +@@ -1,43 +0,0 @@ +-From: Marc-Christian Petersen +-Date: Wed, 9 Mar 2016 19:22:41 +0200 +-Subject: debian-pam.d-pluto +- +-debian: fix /etc/pam.d/pluto to work with debian +- +-Signed-off-by: Tuomo Soini +---- +- configs/pam.d/pluto | 27 +++++++++++---------------- +- 1 file changed, 11 insertions(+), 16 deletions(-) +- +-diff --git a/configs/pam.d/pluto b/configs/pam.d/pluto +-index 3855385..bb9b22c 100644 +---- a/configs/pam.d/pluto +-+++ b/configs/pam.d/pluto +-@@ -1,16 +1,11 @@ +--#%PAM-1.0 +--# Regular System auth +--auth include system-auth +--# +--# Google Authenticator with Regular System auth in combined prompt mode +--# (OTP is added to the password at the password prompt without separator) +--# auth required pam_google_authenticator.so forward_pass +--# auth include system-auth use_first_pass +--# +--# Common +--account required pam_nologin.so +--account include system-auth +--password include system-auth +--session optional pam_keyinit.so force revoke +--session include system-auth +--session required pam_loginuid.so +-+@include common-auth +-+ +-+account required pam_nologin.so +-+account required pam_access.so +-+@include common-account +-+ +-+session optional pam_keyinit.so force revoke +-+session required pam_loginuid.so +-+@include common-session +-+ +-+@include common-password +diff --git a/packaging/devuan/patches/0002-debian-pam.d-pluto.patch b/packaging/devuan/patches/0002-debian-pam.d-pluto.patch +deleted file mode 100644 +index b215138..0000000 +--- a/packaging/devuan/patches/0002-debian-pam.d-pluto.patch ++++ /dev/null +@@ -1,43 +0,0 @@ +-From: Marc-Christian Petersen +-Date: Wed, 9 Mar 2016 19:22:41 +0200 +-Subject: debian-pam.d-pluto +- +-debian: fix /etc/pam.d/pluto to work with debian +- +-Signed-off-by: Tuomo Soini +---- +- pam.d/pluto | 27 +++++++++++---------------- +- 1 file changed, 11 insertions(+), 16 deletions(-) +- +-diff --git a/pam.d/pluto b/pam.d/pluto +-index 3855385..bb9b22c 100644 +---- a/pam.d/pluto +-+++ b/pam.d/pluto +-@@ -1,16 +1,11 @@ +--#%PAM-1.0 +--# Regular System auth +--auth include system-auth +--# +--# Google Authenticator with Regular System auth in combined prompt mode +--# (OTP is added to the password at the password prompt without separator) +--# auth required pam_google_authenticator.so forward_pass +--# auth include system-auth use_first_pass +--# +--# Common +--account required pam_nologin.so +--account include system-auth +--password include system-auth +--session optional pam_keyinit.so force revoke +--session include system-auth +--session required pam_loginuid.so +-+@include common-auth +-+ +-+account required pam_nologin.so +-+account required pam_access.so +-+@include common-account +-+ +-+session optional pam_keyinit.so force revoke +-+session required pam_loginuid.so +-+@include common-session +-+ +-+@include common-password +diff --git a/testing/pluto/delete-sa-02/libreswan-3.23-del-notify.patch b/testing/pluto/delete-sa-02/libreswan-3.23-del-notify.patch +deleted file mode 100644 +index 5ccebad..0000000 +--- a/testing/pluto/delete-sa-02/libreswan-3.23-del-notify.patch ++++ /dev/null +@@ -1,14 +0,0 @@ +-diff --git a/programs/pluto/ikev1_main.c b/programs/pluto/ikev1_main.c +-index 30a1ea78d..c992f662d 100644 +---- a/programs/pluto/ikev1_main.c +-+++ b/programs/pluto/ikev1_main.c +-@@ -2684,7 +2708,9 @@ bool accept_delete(struct msg_digest *md, +- rc->policy &= ~POLICY_UP; +- if (!shared_phase1_connection(rc)) { +- flush_pending_by_connection(rc); +-+ /* why loop? there can be only one IKE SA, just delete_state(st) ? */ +- delete_states_by_connection(rc, FALSE); +-+ md->st = NULL; +- } +- reset_cur_connection(); +- } +diff --git a/testing/pluto/delete-sa-02/libreswan-3.23-impair-del-notify.patch b/testing/pluto/delete-sa-02/libreswan-3.23-impair-del-notify.patch +deleted file mode 100644 +index 69f5bf4..0000000 +--- a/testing/pluto/delete-sa-02/libreswan-3.23-impair-del-notify.patch ++++ /dev/null +@@ -1,79 +0,0 @@ +-diff --git a/include/pluto_constants.h b/include/pluto_constants.h +-index 5e3d67e64..fd0c14d47 100644 +---- a/include/pluto_constants.h +-+++ b/include/pluto_constants.h +-@@ -411,6 +411,7 @@ enum { +- IMPAIR_REPLAY_DUPLICATES_IX, /* replay duplicates of each incoming packet */ +- IMPAIR_REPLAY_FORWARD_IX, /* replay all earlier packets old-to-new */ +- IMPAIR_REPLAY_BACKWARD_IX, /* replay all earlier packets new-to-old */ +-+ IMPAIR_IKEv1_DEL_WITH_NOTIFY_IX, /* causes pluto send send IKE Delete with additional bogus Notify */ +- +- IMPAIR_roof_IX /* first unassigned IMPAIR */ +- }; +-@@ -452,6 +453,7 @@ enum { +- #define IMPAIR_REPLAY_DUPLICATES LELEM(IMPAIR_REPLAY_DUPLICATES_IX) +- #define IMPAIR_REPLAY_FORWARD LELEM(IMPAIR_REPLAY_FORWARD_IX) +- #define IMPAIR_REPLAY_BACKWARD LELEM(IMPAIR_REPLAY_BACKWARD_IX) +-+#define IMPAIR_IKEv1_DEL_WITH_NOTIFY LELEM(IMPAIR_IKEv1_DEL_WITH_NOTIFY_IX) +- +- /* State of exchanges +- * +-diff --git a/lib/libswan/debug_enum_names.c b/lib/libswan/debug_enum_names.c +-index 44d6e9866..59d6bd50c 100644 +---- a/lib/libswan/debug_enum_names.c +-+++ b/lib/libswan/debug_enum_names.c +-@@ -103,6 +103,7 @@ static const char *impair_strings[] = { +- I(IMPAIR_REPLAY_DUPLICATES, "impair-replay-duplicates"), +- I(IMPAIR_REPLAY_FORWARD, "impair-replay-forward"), +- I(IMPAIR_REPLAY_BACKWARD, "impair-replay-backward"), +-+ I(IMPAIR_IKEv1_DEL_WITH_NOTIFY, "impair-ikev1-del-with-notify"), +- }; +- +- const struct enum_names impair_names = { +-diff --git a/programs/pluto/ikev1_main.c b/programs/pluto/ikev1_main.c +-index 30a1ea78d..c992f662d 100644 +---- a/programs/pluto/ikev1_main.c +-+++ b/programs/pluto/ikev1_main.c +-@@ -2424,18 +2427,39 @@ bool ikev1_delete_out(struct state *st) +- +- ns--; +- isad.isad_doi = ISAKMP_DOI_IPSEC; +-- isad.isad_np = ns == +-- said ? ISAKMP_NEXT_NONE : ISAKMP_NEXT_D; +-+ isad.isad_np = ns == said ? ISAKMP_NEXT_NONE : ISAKMP_NEXT_D; +- isad.isad_spisize = sizeof(ipsec_spi_t); +- isad.isad_protoid = ns->proto; +-- +- isad.isad_nospi = 1; +-+ +-+ if (DBGP(IMPAIR_IKEv1_DEL_WITH_NOTIFY)) +-+ isad.isad_np = ISAKMP_NEXT_N; /* Notify */ +-+ +- passert(out_struct(&isad, &isakmp_delete_desc, &r_hdr_pbs, +- &del_pbs)); +- passert(out_raw(&ns->spi, sizeof(ipsec_spi_t), +- &del_pbs, +- "delete payload")); +- close_output_pbs(&del_pbs); +-+ +-+ if (DBGP(IMPAIR_IKEv1_DEL_WITH_NOTIFY)) { +-+ pb_stream cruft_pbs; +-+ +-+ libreswan_log("IMPAIR: adding bogus Notify payload after IKE Delete payload"); +-+ struct isakmp_notification isan = { +-+ .isan_np = ISAKMP_NEXT_NONE, +-+ .isan_doi = ISAKMP_DOI_IPSEC, +-+ .isan_protoid = PROTO_ISAKMP, +-+ .isan_spisize = COOKIE_SIZE * 2, +-+ .isan_type = INVALID_PAYLOAD_TYPE, +-+ }; +-+ +-+ passert(out_struct(&isan, &isakmp_notification_desc, &r_hdr_pbs, +-+ &cruft_pbs)); +-+ passert(out_raw(&ns->spi, sizeof(ipsec_spi_t), &cruft_pbs, +-+ "delete payload")); +-+ close_output_pbs(&cruft_pbs); +-+ } +- } +- } +- +-- +2.45.4 + diff --git a/SPECS/libreswan/CVE-2026-50722.patch b/SPECS/libreswan/CVE-2026-50722.patch new file mode 100644 index 00000000000..9852450b850 --- /dev/null +++ b/SPECS/libreswan/CVE-2026-50722.patch @@ -0,0 +1,98 @@ +From bbc3bf81083be3e1c45e78e48c1b16f9250c9f5e Mon Sep 17 00:00:00 2001 +From: Azure Linux Security Servicing Account + +Date: Fri, 3 Jul 2026 09:48:46 +0000 +Subject: [PATCH] Patch CVE-2026-50722 for libreswan (applied via patch -p1) + +Signed-off-by: Azure Linux Security Servicing Account +Upstream-reference: https://libreswan.org/security/CVE-2026-50722/libreswan-4.15-CVE-2026-50722.patch +--- + lib/libswan/pubkey_rsa.c | 58 +++++++++------------------------------- + 1 file changed, 12 insertions(+), 46 deletions(-) + +diff --git a/lib/libswan/pubkey_rsa.c b/lib/libswan/pubkey_rsa.c +index d2f36cb..0c5a1c9 100644 +--- a/lib/libswan/pubkey_rsa.c ++++ b/lib/libswan/pubkey_rsa.c +@@ -491,7 +491,7 @@ static struct hash_signature RSA_sign_hash_pkcs1_1_5_rsa(const struct secret_stu + static bool RSA_authenticate_signature_pkcs1_1_5_rsa(const struct crypt_mac *expected_hash, + shunk_t signature, + struct pubkey *pubkey, +- const struct hash_desc *unused_hash_algo UNUSED, ++ const struct hash_desc *hash_alg, + diag_t *fatal_diag, + struct logger *logger) + { +@@ -509,58 +509,24 @@ static bool RSA_authenticate_signature_pkcs1_1_5_rsa(const struct crypt_mac *exp + *expected_hash); + } + +- /* +- * Use the same space used by the out going hash. +- */ +- +- SECItem decrypted_signature = { +- .type = siBuffer, +- }; +- +- if (SECITEM_AllocItem(NULL, &decrypted_signature, signature.len) == NULL) { +- llog_nss_error(RC_LOG, logger, "allocating space for decrypted RSA signature"); +- return false; +- } ++ SECItem hash_item = ++ same_shunk_as_secitem(HUNK_AS_SHUNK(*expected_hash), siBuffer); + + /* NSS doesn't do const */ +- const SECItem encrypted_signature = { +- .type = siBuffer, +- .data = DISCARD_CONST(unsigned char *, signature.ptr), +- .len = signature.len, +- }; +- +- if (PK11_VerifyRecover(seckey_public, &encrypted_signature, &decrypted_signature, +- lsw_nss_get_password_context(logger)) != SECSuccess) { +- SECITEM_FreeItem(&decrypted_signature, PR_FALSE/*not-pointer*/); +- dbg("NSS RSA verify: decrypting signature is failed"); +- *fatal_diag = NULL; +- return false; +- } +- +- if (DBGP(DBG_CRYPT)) { +- LLOG_JAMBUF(DEBUG_STREAM, logger, buf) { +- jam_string(buf, "NSS RSA verify: decrypted sig: "); +- jam_nss_secitem(buf, &decrypted_signature); +- } +- } ++ SECItem signature_item = ++ same_shunk_as_secitem(signature, siBuffer); + +- /* +- * Expect the matching hash to appear at the end. See above +- * for length check. It may, or may not, be prefixed by a +- * PKCS#1 1.5 RSA ASN.1 blob. +- */ +- passert(decrypted_signature.len >= expected_hash->len); +- uint8_t *start = (decrypted_signature.data +- + decrypted_signature.len +- - expected_hash->len); +- if (!memeq(start, expected_hash->ptr, expected_hash->len)) { +- dbg("RSA Signature NOT verified"); +- SECITEM_FreeItem(&decrypted_signature, PR_FALSE/*not-pointer*/); ++ if (VFY_VerifyDigestDirect(&hash_item, ++ seckey_public, ++ &signature_item, ++ /*pubkey algorithm*/SEC_OID_PKCS1_RSA_ENCRYPTION, ++ /*hash algorithm*/hash_alg->nss.oid_tag, ++ lsw_nss_get_password_context(logger)) != SECSuccess) { ++ ldbg_nss_error(logger, "NSS VFY_VerifyDigest() failed"); + *fatal_diag = NULL; + return false; + } + +- SECITEM_FreeItem(&decrypted_signature, PR_FALSE/*not-pointer*/); + *fatal_diag = NULL; + return true; + } +-- +2.45.4 + diff --git a/SPECS/libreswan/libreswan.spec b/SPECS/libreswan/libreswan.spec index 8d9c2c966dd..24d51d1859f 100644 --- a/SPECS/libreswan/libreswan.spec +++ b/SPECS/libreswan/libreswan.spec @@ -27,7 +27,7 @@ Summary: Internet Key Exchange (IKEv1 and IKEv2) implementation for IPsec Name: libreswan Version: 4.15 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv2+ Vendor: Microsoft Corporation Distribution: Azure Linux @@ -37,6 +37,9 @@ Source0: https://github.com/libreswan/libreswan/archive/refs/tags/v%{vers Source3: https://download.libreswan.org/cavs/ikev1_dsa.fax.bz2 Source4: https://download.libreswan.org/cavs/ikev1_psk.fax.bz2 Source5: https://download.libreswan.org/cavs/ikev2.fax.bz2 +Patch0: CVE-2026-12413.patch +Patch1: CVE-2026-50721.patch +Patch2: CVE-2026-50722.patch BuildRequires: audit-libs-devel BuildRequires: bison @@ -194,6 +197,9 @@ certutil -N -d sql:$tmpdir --empty-password %doc %{_mandir}/*/* %changelog +* Fri Jul 03 2026 Azure Linux Security Servicing Account - 4.15-2 +- Patch for CVE-2026-50722, CVE-2026-50721, CVE-2026-12413 + * Sat Mar 29 2025 Kanishk Bansal - 4.15-1 - Upgrade to 4.15 to fix CVE-2024-3652, CVE-2024-2357, CVE-2023-30570 - Remove previously applied patches