已开启
fix(cve): 修复 CVE-2026-114605 在 python-dns 中的漏洞 #72
fix(cve): 修复 CVE-2026-114605 在 python-dns 中的漏洞 #72
已开启
infra_team创建于 12 天前
共 2 个文件变更+108-1
@@ -0,0 +1,102 @@
1+From 2398b7043edd894cd22bd5870c72121e245464a8 Mon Sep 17 00:00:00 2001
E
Eeaglegai10 天前

@infra_team commit id建议跟社区保持一致

likedislike
2+From: Bob Halley <halley@dnspython.org>
3+Date: Sat, 26 Sep 2026 13:38:07 -0700
4+Subject: [PATCH] Limit decompression to a chain length of at most 16 pointers.
5+ 
6+A maliciously crafted DNS message may cause dns.name.from_wire_parser()
7+to use excessive CPU for DNS name decompression. Applications which
8+process untrusted DNS wire form messages with dnspython may be degraded
9+or DoS'd by the extra CPU use required.
10+ 
11+Credit:
12+ 
13+Evgenios Gkritsis, Department of Informatics, University of Piraeus & Athena Research Center, Greece
14+Constantinos Patsakis, Department of Informatics, University of Piraeus & Athena Research Center, Greece
15+George Stergiopoulos, Department of Informatics, Athens University of Economics and Business, Greece
16+ 
17+Upstream-commit: https://github.com/rthalley/dnspython/commit/b485e460c266540a1a09ca6d8d1d7b685b1d3023
18+Signed-off-by: infra_team <zhaiwenjie1@huawei.com>
19+---
20+ dns/name.py | 11 +++++++++++
21+ tests/test_name.py | 22 ++++++++++++++++++++++
22+ 2 files changed, 33 insertions(+)
23+ 
24+diff --git a/dns/name.py b/dns/name.py
25+index 8905d70..1ff195d 100644
26+--- a/dns/name.py
27++++ b/dns/name.py
28+@@ -58,6 +58,10 @@ class BadPointer(dns.exception.FormError):
29+ """A DNS compression pointer points forward instead of backward."""
30+
31+
32++class PointerChainTooLong(dns.exception.FormError):
33++ """A DNS compression pointer chain was too long."""
34++
35++
36+ class BadLabelType(dns.exception.FormError):
37+ """The label type in DNS name wire format is unknown."""
38+
39+@@ -959,6 +963,9 @@ def from_text(text, origin=root, idna_codec=None):
40+ return Name(labels)
41+
42+
43++MAX_COMPRESSION_POINTER_CHAIN = 16
44++
45++
46+ def from_wire_parser(parser):
47+ """Convert possibly compressed wire format into a Name.
48+
49+@@ -974,6 +981,7 @@ def from_wire_parser(parser):
50+
51+ labels = []
52+ biggest_pointer = parser.current
53++ hops = 0
54+ with parser.restore_furthest():
55+ count = parser.get_uint8()
56+ while count != 0:
57+@@ -984,6 +992,9 @@ def from_wire_parser(parser):
58+ if current >= biggest_pointer:
59+ raise BadPointer
60+ biggest_pointer = current
61++ hops += 1
62++ if hops > MAX_COMPRESSION_POINTER_CHAIN:
63++ raise PointerChainTooLong
64+ parser.seek(current)
65+ else:
66+ raise BadLabelType
67+diff --git a/tests/test_name.py b/tests/test_name.py
68+index f91d7e6..0fde0dd 100644
69+--- a/tests/test_name.py
70++++ b/tests/test_name.py
71+@@ -676,6 +676,28 @@ class NameTestCase(unittest.TestCase):
72+ dns.name.from_wire(w, 0)
73+ self.assertRaises(dns.name.BadLabelType, bad)
74+
75++ def testCompressionChainLength(self):
76++ # We're going to decode some wire starting two bytes from the end. At this
77++ # position is a pointer which points to four bytes from the end, and it points
78++ # to one 6 bytes from the end, etc., until finally the 16th pointer points at
79++ # offset zero, which is the root label followed by a byte of padding. After
80++ # all of this useless pointer hopping, we should get the root name.
81++ w = b"\x00\x00\xc0\x00\xc0\x02\xc0\x04\xc0\x06\xc0\x08\xc0\x0a\xc0\x0c\xc0\x0e\xc0\x10\xc0\x12\xc0\x14\xc0\x16\xc0\x18\xc0\x1a\xc0\x1c\xc0\x1e"
82++ self.assertEqual(len(w), 34)
83++ starts = [c for c in w if c == 0xC0]
84++ self.assertEqual(len(starts), dns.name.MAX_COMPRESSION_POINTER_CHAIN)
85++
86++ def bad():
87++ # Now we make the wire one pointer longer, which is too long!
88++ w1 = w + b"\xc0\x20"
89++ self.assertEqual(len(w1), 36)
90++ starts = [c for c in w1 if c == 0xC0]
91++ self.assertEqual(len(starts), dns.name.MAX_COMPRESSION_POINTER_CHAIN + 1)
92++ dns.name.from_wire(w1, 34)
93++
94++ self.assertEqual(dns.name.from_wire(w, 32)[0], dns.name.from_text("."))
95++ self.assertRaises(dns.name.PointerChainTooLong, bad)
96++
97+ def testParent1(self):
98+ n = dns.name.from_text('foo.bar.')
99+ self.assertEqual(n.parent(), dns.name.from_text('bar.'))
100+--
101+2.39.5
102+ 
@@ -14,7 +14,7 @@ messages, names, and records.
14Name: python-dns14Name: python-dns
15Summary: %{sum}15Summary: %{sum}
16Version: 2.2.116Version: 2.2.1
17-Release: 317+Release: 4
18License: ISC and MIT18License: ISC and MIT
19URL: http://www.dnspython.org/19URL: http://www.dnspython.org/
20Source0: https://github.com/rthalley/dnspython/archive/v%{version}/dnspython-%{version}.tar.gz20Source0: https://github.com/rthalley/dnspython/archive/v%{version}/dnspython-%{version}.tar.gz
@@ -25,6 +25,7 @@ Patch2: 0001-update-README-w-codecov-and-lgtm.patch
25Patch3: backport-001-CVE-2023-29483.patch25Patch3: backport-001-CVE-2023-29483.patch
26Patch4: backport-002-CVE-2023-29483.patch26Patch4: backport-002-CVE-2023-29483.patch
27Patch5: backport-003-CVE-2023-29483.patch27Patch5: backport-003-CVE-2023-29483.patch
28+Patch6: backport-CVE-2026-114605-limit-pointer-chain.patch
28 29 
29BuildArch: noarch30BuildArch: noarch
30 31 
@@ -67,6 +68,10 @@ pytest
67%doc examples68%doc examples
68 69 
69%changelog70%changelog
71+* Sat Oct 24 2026 infra_team <zhaiwenjie1@huawei.com> - 2.2.1-4
72+- fix CVE-2026-114605
73+- limit DNS name decompression to a chain length of at most 16 pointers
74+ 
70* Wed Jul 24 2024 gaihuiying <eaglegai@163.com> - 2.2.1-375* Wed Jul 24 2024 gaihuiying <eaglegai@163.com> - 2.2.1-3
71- fix CVE-2023-2948376- fix CVE-2023-29483
72 77