mirror of
https://git.yoctoproject.org/poky
synced 2026-09-22 00:49:35 +02:00
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>
This commit is contained in:
committed by
Richard Purdie
parent
3ffe50e092
commit
abef4d0701
@@ -0,0 +1,72 @@
|
||||
From 22acbaae97c3698005e69555eb4ebccc168b2fff Mon Sep 17 00:00:00 2001
|
||||
From: metsw24-max <metsw24@gmail.com>
|
||||
Date: Mon, 11 May 2026 20:59:30 +0530
|
||||
Subject: [PATCH 3/3] Enforce early length limits in check_label
|
||||
|
||||
CVE: CVE-2026-45409
|
||||
Upstream-Status: Backport [https://github.com/kjd/idna/commit/e1cb465b6376f33306a26f467d197edbcd01c4b9]
|
||||
|
||||
(cherry picked from commit e1cb465b6376f33306a26f467d197edbcd01c4b9)
|
||||
Signed-off-by: Hetvi Thakar <hthakar@cisco.com>
|
||||
---
|
||||
idna/core.py | 11 +++++++++++
|
||||
tests/test_idna.py | 24 ++++++++++++++++++++++++
|
||||
2 files changed, 35 insertions(+)
|
||||
|
||||
diff --git a/idna/core.py b/idna/core.py
|
||||
index 4a9fc75..26bb9fa 100644
|
||||
--- a/idna/core.py
|
||||
+++ b/idna/core.py
|
||||
@@ -230,6 +230,17 @@ def check_label(label: Union[str, bytes, bytearray]) -> None:
|
||||
label = label.decode('utf-8')
|
||||
if len(label) == 0:
|
||||
raise IDNAError('Empty Label')
|
||||
+ # Reject oversized labels before per-codepoint validation runs.
|
||||
+ # CONTEXTJ/CONTEXTO checks scan the whole label per codepoint, so an
|
||||
+ # uncapped label drives validation into quadratic time
|
||||
+ # (GHSA-65pc-fj4g-8rjx / CVE-2024-3651). encode()/decode() cap the
|
||||
+ # whole-domain length; this cap protects direct callers of
|
||||
+ # alabel/ulabel/check_label and the idna2008 incremental codec.
|
||||
+ # Use the whole-domain bound rather than the per-label DNS bound so
|
||||
+ # that UTS #46 lenient decoding of labels longer than 63 chars is
|
||||
+ # preserved.
|
||||
+ if not valid_string_length(label, trailing_dot=True):
|
||||
+ raise IDNAError("Label too long")
|
||||
|
||||
check_nfc(label)
|
||||
check_hyphen_ok(label)
|
||||
diff --git a/tests/test_idna.py b/tests/test_idna.py
|
||||
index 5001b48..2dc0892 100755
|
||||
--- a/tests/test_idna.py
|
||||
+++ b/tests/test_idna.py
|
||||
@@ -91,6 +91,30 @@ class IDNATests(unittest.TestCase):
|
||||
self.assertRaises(idna.IDNAError, idna.decode, payload)
|
||||
self.assertLess(time.perf_counter() - start, 1.0)
|
||||
|
||||
+ def test_oversized_label_rejected_promptly(self):
|
||||
+ # The whole-domain cap in encode()/decode() does not cover direct
|
||||
+ # callers of alabel/ulabel/check_label, nor the idna2008
|
||||
+ # incremental codec which calls alabel/ulabel per label. Without a
|
||||
+ # per-label cap, a single oversized CONTEXTO-heavy label still
|
||||
+ # drives validation into quadratic time.
|
||||
+ import codecs
|
||||
+ import time
|
||||
+
|
||||
+ import idna.codec # noqa: F401 (register the idna2008 codec)
|
||||
+
|
||||
+ payload = "・" * 8000 + "漢"
|
||||
+ start = time.perf_counter()
|
||||
+ self.assertRaises(idna.IDNAError, idna.check_label, payload)
|
||||
+ self.assertRaises(idna.IDNAError, idna.alabel, payload)
|
||||
+ self.assertRaises(idna.IDNAError, idna.ulabel, payload)
|
||||
+ self.assertRaises(
|
||||
+ idna.IDNAError,
|
||||
+ codecs.getincrementalencoder("idna2008")().encode,
|
||||
+ payload,
|
||||
+ True,
|
||||
+ )
|
||||
+ self.assertLess(time.perf_counter() - start, 1.0)
|
||||
+
|
||||
def test_check_bidi(self):
|
||||
|
||||
l = '\u0061'
|
||||
Reference in New Issue
Block a user