new file mode 100644
@@ -0,0 +1,43 @@
+From 1dead2faec6320aaba321eb56f20d442df192b83 Mon Sep 17 00:00:00 2001
+From: Alexander Sosedkin <asosedkin@redhat.com>
+Date: Tue, 14 Apr 2026 17:41:30 +0200
+Subject: [PATCH 1/2] x509/name_constraints: fix intersecting empty constraints
+
+Permitted name constraints were wrongfully ignored
+when prior CAs only had excluded name constraints,
+resulting in a name constraint bypass.
+
+With this change, they are taken into account and propagate.
+
+CVE: CVE-2026-42011
+Upstream-Status: Backport [https://gitlab.com/gnutls/gnutls/-/commit/1dead2faec6320aaba321eb56f20d442df192b83]
+
+Reported-by: Haruto Kimura (Stella)
+Fixes: #1824
+Fixes: CVE-2026-42011
+Fixes: GNUTLS-SA-2026-04-29-6
+CVSS: 4.8 Medium CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N
+
+Signed-off-by: Alexander Sosedkin <asosedkin@redhat.com>
+Signed-off-by: Jakub Szczudlo <jakub.szczudlo@nokia.com>
+---
+ lib/x509/name_constraints.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/lib/x509/name_constraints.c b/lib/x509/name_constraints.c
+index 04722bdf4..232d466c4 100644
+--- a/lib/x509/name_constraints.c
++++ b/lib/x509/name_constraints.c
+@@ -723,9 +723,6 @@ static int name_constraints_node_list_intersect(
+ type_bitmask_t types_in_p1 = 0, types_in_p2 = 0;
+ static const unsigned char universal_ip[32] = { 0 };
+
+- if (permitted->size == 0 || permitted2->size == 0)
+- return GNUTLS_E_SUCCESS;
+-
+ /* make sorted views of the arrays */
+ ret = ensure_sorted(permitted);
+ if (ret < 0) {
+--
+2.53.0
+
new file mode 100644
@@ -0,0 +1,141 @@
+From 24713b8c63137ce0665b495d22ccce4f5ce05c84 Mon Sep 17 00:00:00 2001
+From: Alexander Sosedkin <asosedkin@redhat.com>
+Date: Tue, 14 Apr 2026 17:49:50 +0200
+Subject: [PATCH 2/2] tests/name-constraints-merge: extend to cover #1824
+
+CVE: CVE-2026-42011
+Upstream-Status: Backport [https://gitlab.com/gnutls/gnutls/-/commit/24713b8c63137ce0665b495d22ccce4f5ce05c84]
+
+Signed-off-by: Alexander Sosedkin <asosedkin@redhat.com>
+Signed-off-by: Jakub Szczudlo <jakub.szczudlo@nokia.com>
+---
+ tests/name-constraints-merge.c | 113 +++++++++++++++++++++++++++++++++
+ 1 file changed, 113 insertions(+)
+
+diff --git a/tests/name-constraints-merge.c b/tests/name-constraints-merge.c
+index 70376aaa7..3ff8d6c60 100644
+--- a/tests/name-constraints-merge.c
++++ b/tests/name-constraints-merge.c
+@@ -473,6 +473,119 @@ void doit(void)
+ gnutls_x509_name_constraints_deinit(nc1);
+ gnutls_x509_name_constraints_deinit(nc2);
+
++ /* 6: test intersecting empty permitted with non-empty permitted
++ * NC1: excluded DNS excluded.example.org (empty permitted)
++ * NC2: permitted DNS permitted.example.org
++ * Expected result:
++ * permitted=[permitted.example.org], excluded=[excluded.example.org]
++ * unrelated.example.com is rejected
++ */
++ suite = 6;
++
++ ret = gnutls_x509_name_constraints_init(&nc1);
++ check_for_error(ret);
++
++ ret = gnutls_x509_name_constraints_init(&nc2);
++ check_for_error(ret);
++
++ set_name("excluded.example.org", &name);
++ ret = gnutls_x509_name_constraints_add_excluded(nc1, GNUTLS_SAN_DNSNAME,
++ &name);
++ check_for_error(ret);
++
++ set_name("permitted.example.org", &name);
++ ret = gnutls_x509_name_constraints_add_permitted(
++ nc2, GNUTLS_SAN_DNSNAME, &name);
++ check_for_error(ret);
++
++ ret = _gnutls_x509_name_constraints_merge(nc1, nc2);
++ check_for_error(ret);
++
++ set_name("unrelated.example.com", &name); /* entirely unrelated */
++ ret = gnutls_x509_name_constraints_check(nc1, GNUTLS_SAN_DNSNAME,
++ &name);
++ check_test_result(suite, ret, NAME_REJECTED, &name); /* #1814 */
++
++ set_name("permitted.example.org", &name); /* permitted, direct */
++ ret = gnutls_x509_name_constraints_check(nc1, GNUTLS_SAN_DNSNAME,
++ &name);
++ check_test_result(suite, ret, NAME_ACCEPTED, &name); /* sanity */
++
++ set_name("sub.permitted.example.org", &name); /* permitted, subdomain */
++ ret = gnutls_x509_name_constraints_check(nc1, GNUTLS_SAN_DNSNAME,
++ &name);
++ check_test_result(suite, ret, NAME_ACCEPTED, &name); /* sanity */
++
++ set_name("excluded.example.org", &name); /* excluded, direct */
++ ret = gnutls_x509_name_constraints_check(nc1, GNUTLS_SAN_DNSNAME,
++ &name);
++ check_test_result(suite, ret, NAME_REJECTED, &name); /* sanity */
++
++ set_name("sub.excluded.example.org", &name); /* excluded, subdomain */
++ ret = gnutls_x509_name_constraints_check(nc1, GNUTLS_SAN_DNSNAME,
++ &name);
++ check_test_result(suite, ret, NAME_REJECTED, &name); /* sanity */
++
++ gnutls_x509_name_constraints_deinit(nc1);
++ gnutls_x509_name_constraints_deinit(nc2);
++
++ /* 7: test intersecting non-empty permitted with empty permitted
++ * (same as 6, but swapped to ensure order doesn't matter)
++ * NC1: permitted DNS permitted.example.org
++ * NC2: excluded DNS excluded.example.org (empty permitted)
++ * Expected result:
++ * permitted=[permitted.example.org], excluded=[excluded.example.org]
++ * unrelated.example.com is rejected
++ */
++ suite = 7;
++
++ ret = gnutls_x509_name_constraints_init(&nc1);
++ check_for_error(ret);
++
++ ret = gnutls_x509_name_constraints_init(&nc2);
++ check_for_error(ret);
++
++ set_name("permitted.example.org", &name);
++ ret = gnutls_x509_name_constraints_add_permitted(
++ nc1, GNUTLS_SAN_DNSNAME, &name);
++ check_for_error(ret);
++
++ set_name("excluded.example.org", &name);
++ ret = gnutls_x509_name_constraints_add_excluded(nc2, GNUTLS_SAN_DNSNAME,
++ &name);
++ check_for_error(ret);
++
++ ret = _gnutls_x509_name_constraints_merge(nc1, nc2);
++ check_for_error(ret);
++
++ set_name("unrelated.example.com", &name); /* entirely unrelated */
++ ret = gnutls_x509_name_constraints_check(nc1, GNUTLS_SAN_DNSNAME,
++ &name);
++ check_test_result(suite, ret, NAME_REJECTED, &name); /* #1814 */
++
++ set_name("permitted.example.org", &name); /* permitted, direct */
++ ret = gnutls_x509_name_constraints_check(nc1, GNUTLS_SAN_DNSNAME,
++ &name);
++ check_test_result(suite, ret, NAME_ACCEPTED, &name); /* sanity */
++
++ set_name("sub.permitted.example.org", &name); /* permitted, subdomain */
++ ret = gnutls_x509_name_constraints_check(nc1, GNUTLS_SAN_DNSNAME,
++ &name);
++ check_test_result(suite, ret, NAME_ACCEPTED, &name); /* sanity */
++
++ set_name("excluded.example.org", &name); /* excluded, direct */
++ ret = gnutls_x509_name_constraints_check(nc1, GNUTLS_SAN_DNSNAME,
++ &name);
++ check_test_result(suite, ret, NAME_REJECTED, &name); /* sanity */
++
++ set_name("sub.excluded.example.org", &name); /* excluded, subdomain */
++ ret = gnutls_x509_name_constraints_check(nc1, GNUTLS_SAN_DNSNAME,
++ &name);
++ check_test_result(suite, ret, NAME_REJECTED, &name); /* sanity */
++
++ gnutls_x509_name_constraints_deinit(nc1);
++ gnutls_x509_name_constraints_deinit(nc2);
++
+ /* Test footer */
+
+ if (debug)
+--
+2.53.0
+
@@ -37,6 +37,8 @@ SRC_URI = "https://www.gnupg.org/ftp/gcrypt/gnutls/v${SHRT_VER}/gnutls-${PV}.tar
file://CVE-2026-42009_p1.patch \
file://CVE-2026-42009_p2.patch \
file://CVE-2026-3833.patch \
+ file://CVE-2026-42011_p1.patch \
+ file://CVE-2026-42011_p2.patch \
"
SRC_URI[sha256sum] = "a7b341421bfd459acf7a374ca4af3b9e06608dcd7bd792b2bf470bea012b8e51"
Backport patches to fix CVE-2026-42011 and extend test for it References: https://nvd.nist.gov/vuln/detail/CVE-2026-42011 Upstream fix: https://gitlab.com/gnutls/gnutls/-/commit/1dead2faec6320aaba321eb56f20d442df192b83 https://gitlab.com/gnutls/gnutls/-/commit/24713b8c63137ce0665b495d22ccce4f5ce05c84 Tested with ptest Signed-off-by: Jakub Szczudlo <jakub.szczudlo@nokia.com> --- .../gnutls/gnutls/CVE-2026-42011_p1.patch | 43 ++++++ .../gnutls/gnutls/CVE-2026-42011_p2.patch | 141 ++++++++++++++++++ meta/recipes-support/gnutls/gnutls_3.8.12.bb | 2 + 3 files changed, 186 insertions(+) create mode 100644 meta/recipes-support/gnutls/gnutls/CVE-2026-42011_p1.patch create mode 100644 meta/recipes-support/gnutls/gnutls/CVE-2026-42011_p2.patch