Files
poky/meta/recipes-devtools/python/python3-idna/CVE-2026-45409_p1.patch
Hetvi Thakar abef4d0701 python3-idna: Fix CVE-2026-45409
This patch applies the complete upstream fix chain for
CVE-2026-45409. Commit [1] introduces early domain-length rejection
required by [2]. Commit [2] is the v3.14 fix identified by [5], and
commit [3] extends the protection to per-label conversions and codec
support to complete the v3.15 fix described in [4].

[1] https://github.com/kjd/idna/commit/c0dda4501df5
[2] https://github.com/kjd/idna/commit/628fef84d3ed
[3] https://github.com/kjd/idna/commit/e1cb465b6376
[4] https://github.com/kjd/idna/security/advisories/GHSA-65pc-fj4g-8rjx
[5] https://security-tracker.debian.org/tracker/CVE-2026-45409

(From OE-Core rev: 09773d9d1b44dfe868913b6bb142a728529f62cb)

Signed-off-by: Hetvi Thakar <hthakar@cisco.com>
Signed-off-by: Yoann Congal <yoann.congal@smile.fr>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2026-09-11 14:32:08 +01:00

76 lines
3.1 KiB
Diff
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

From b34cd8399981324b361ae4f2b8e0eb77444ae0e3 Mon Sep 17 00:00:00 2001
From: Kim Davies <kim@cynosure.com.au>
Date: Sun, 10 May 2026 08:47:22 -0700
Subject: [PATCH 1/3] Merge commit from fork
CVE: CVE-2026-45409
Upstream-Status: Backport [https://github.com/kjd/idna/commit/c0dda4501df5d91c3181ce6f962dc5de74e82cc1]
Backport Changes:
- Omit the HISTORY.rst hunk because it documents the upstream 3.14
release and is not applicable to the Scarthgap 3.7 source.
(cherry picked from commit c0dda4501df5d91c3181ce6f962dc5de74e82cc1)
Signed-off-by: Hetvi Thakar <hthakar@cisco.com>
---
idna/core.py | 14 ++++++++++++++
tests/test_idna.py | 13 +++++++++++++
2 files changed, 27 insertions(+)
diff --git a/idna/core.py b/idna/core.py
index 0dae61a..a549326 100644
--- a/idna/core.py
+++ b/idna/core.py
@@ -340,6 +340,15 @@ def encode(s: Union[str, bytes, bytearray], strict: bool = False, uts46: bool =
raise IDNAError('should pass a unicode string to the function rather than a byte string.')
if uts46:
s = uts46_remap(s, std3_rules, transitional)
+
+ # Reject inputs that exceed the maximum DNS domain length up-front.
+ # Each codepoint in a U-label contributes at least one octet to its
+ # A-label form, so any input longer than the domain limit cannot
+ # produce a valid A-domain. Short-circuiting here prevents per-label
+ # validation from being driven into quadratic time
+ if len(s) > 254:
+ raise IDNAError("Domain too long")
+
trailing_dot = False
result = []
if strict:
@@ -373,6 +382,11 @@ def decode(s: Union[str, bytes, bytearray], strict: bool = False, uts46: bool =
raise IDNAError('Invalid ASCII in A-label')
if uts46:
s = uts46_remap(s, std3_rules, False)
+ # See encode() for rationale; the same bound applies because every
+ # legal A-domain is at most 254 octets and every codepoint of a
+ # legal U-domain contributes at least one octet to its A-form.
+ if len(s) > 254:
+ raise IDNAError("Domain too long")
trailing_dot = False
result = []
if not strict:
diff --git a/tests/test_idna.py b/tests/test_idna.py
index 81afb32..5001b48 100755
--- a/tests/test_idna.py
+++ b/tests/test_idna.py
@@ -78,6 +78,19 @@ class IDNATests(unittest.TestCase):
self.assertFalse(idna.valid_label_length('a' * 64))
self.assertRaises(idna.IDNAError, idna.encode, 'a' * 64)
+ def test_oversized_input_rejected_promptly(self):
+ # GHSA-65pc-fj4g-8rjx: encode/decode must reject inputs that
+ # exceed the maximum DNS domain length before per-codepoint
+ # validation runs, so labels dominated by CONTEXTO codepoints
+ # cannot drive validation into quadratic time.
+ import time
+
+ for payload in ("٠" * 8000, "・" * 8000 + "漢"):
+ start = time.perf_counter()
+ self.assertRaises(idna.IDNAError, idna.encode, payload)
+ self.assertRaises(idna.IDNAError, idna.decode, payload)
+ self.assertLess(time.perf_counter() - start, 1.0)
+
def test_check_bidi(self):
l = '\u0061'