new file mode 100644
@@ -0,0 +1,167 @@
+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.
+
+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>
+
+CVE: CVE-2026-42011
+Upstream-Status: Backport [https://gitlab.com/gnutls/gnutls/-/commit/1dead2faec6320aaba321eb56f20d442df192b83 & https://gitlab.com/gnutls/gnutls/-/commit/24713b8c63137ce0665b495d22ccce4f5ce05c84]
+Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
+---
+ lib/x509/name_constraints.c | 3 -
+ tests/name-constraints-merge.c | 113 +++++++++++++++++++++++++++++++++
+ 2 files changed, 113 insertions(+), 3 deletions(-)
+
+diff --git a/lib/x509/name_constraints.c b/lib/x509/name_constraints.c
+index 04722bd..232d466 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) {
+diff --git a/tests/name-constraints-merge.c b/tests/name-constraints-merge.c
+index 03b3243..1eac6de 100644
+--- a/tests/name-constraints-merge.c
++++ b/tests/name-constraints-merge.c
+@@ -418,6 +418,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.50.1
+
@@ -43,6 +43,7 @@ SRC_URI = "https://www.gnupg.org/ftp/gcrypt/gnutls/v${SHRT_VER}/gnutls-${PV}.tar
file://CVE-2025-14831-7.patch \
file://CVE-2025-14831-8.patch \
file://CVE-2025-14831-9.patch \
+ file://CVE-2026-42011.patch \
"
SRC_URI[sha256sum] = "2bea4e154794f3f00180fa2a5c51fe8b005ac7a31cd58bd44cdfa7f36ebc3a9b"
Pick patch from [1] & [2] also mentioned at Debian report in [3] [1] https://gitlab.com/gnutls/gnutls/-/commit/1dead2faec6320aaba321eb56f20d442df192b83 [2] https://gitlab.com/gnutls/gnutls/-/commit/24713b8c63137ce0665b495d22ccce4f5ce05c84 [3] https://security-tracker.debian.org/tracker/CVE-2026-42011 [4] https://gitlab.com/gnutls/gnutls/-/work_items/1824 Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com> --- .../gnutls/gnutls/CVE-2026-42011.patch | 167 ++++++++++++++++++ meta/recipes-support/gnutls/gnutls_3.8.4.bb | 1 + 2 files changed, 168 insertions(+) create mode 100644 meta/recipes-support/gnutls/gnutls/CVE-2026-42011.patch