Compare commits
3 Commits
imports/c8
...
c8
Author | SHA1 | Date | |
---|---|---|---|
b051ffef9f | |||
|
c7bf39cfdb | ||
|
19b13ceed2 |
99
SOURCES/CVE-2023-29483.patch
Normal file
99
SOURCES/CVE-2023-29483.patch
Normal file
@ -0,0 +1,99 @@
|
||||
From a77e0c662c6d5b8224ac1e283aee8353bcd1536e Mon Sep 17 00:00:00 2001
|
||||
From: Lumir Balhar <lbalhar@redhat.com>
|
||||
Date: Mon, 22 Apr 2024 16:49:15 +0200
|
||||
Subject: [PATCH] CVE-2023-29483
|
||||
|
||||
---
|
||||
dns/query.py | 60 +++++++++++++++++++++++++++++++++++-----------------
|
||||
1 file changed, 41 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/dns/query.py b/dns/query.py
|
||||
index 19b9fbb..2dba3cc 100644
|
||||
--- a/dns/query.py
|
||||
+++ b/dns/query.py
|
||||
@@ -170,6 +170,22 @@ def _addresses_equal(af, a1, a2):
|
||||
return n1 == n2 and a1[1:] == a2[1:]
|
||||
|
||||
|
||||
+def _matches_destination(af, from_address, destination, ignore_unexpected):
|
||||
+ # Check that from_address is appropriate for a response to a query
|
||||
+ # sent to destination.
|
||||
+ if not destination:
|
||||
+ return True
|
||||
+ if _addresses_equal(af, from_address, destination) or (
|
||||
+ dns.inet.is_multicast(destination[0]) and from_address[1:] == destination[1:]
|
||||
+ ):
|
||||
+ return True
|
||||
+ elif ignore_unexpected:
|
||||
+ return False
|
||||
+ raise UnexpectedSource(
|
||||
+ f"got a response from {from_address} instead of " f"{destination}"
|
||||
+ )
|
||||
+
|
||||
+
|
||||
def _destination_and_source(af, where, port, source, source_port):
|
||||
# Apply defaults and compute destination and source tuples
|
||||
# suitable for use in connect(), sendto(), or bind().
|
||||
@@ -194,7 +210,7 @@ def _destination_and_source(af, where, port, source, source_port):
|
||||
|
||||
|
||||
def udp(q, where, timeout=None, port=53, af=None, source=None, source_port=0,
|
||||
- ignore_unexpected=False, one_rr_per_rrset=False):
|
||||
+ ignore_unexpected=False, one_rr_per_rrset=False, ignore_errors=False):
|
||||
"""Return the response obtained after sending a query via UDP.
|
||||
|
||||
@param q: the query
|
||||
@@ -239,26 +255,32 @@ def udp(q, where, timeout=None, port=53, af=None, source=None, source_port=0,
|
||||
while 1:
|
||||
_wait_for_readable(s, expiration)
|
||||
(wire, from_address) = s.recvfrom(65535)
|
||||
- if _addresses_equal(af, from_address, destination) or \
|
||||
- (dns.inet.is_multicast(where) and
|
||||
- from_address[1:] == destination[1:]):
|
||||
- break
|
||||
- if not ignore_unexpected:
|
||||
- raise UnexpectedSource('got a response from '
|
||||
- '%s instead of %s' % (from_address,
|
||||
- destination))
|
||||
- finally:
|
||||
- if begin_time is None:
|
||||
- response_time = 0
|
||||
- else:
|
||||
+ if not _matches_destination(
|
||||
+ s.family, from_address, destination, ignore_unexpected
|
||||
+ ):
|
||||
+ continue
|
||||
+
|
||||
response_time = time.time() - begin_time
|
||||
+
|
||||
+ try:
|
||||
+ r = dns.message.from_wire(wire, keyring=q.keyring, request_mac=q.mac,
|
||||
+ one_rr_per_rrset=one_rr_per_rrset)
|
||||
+ r.time = response_time
|
||||
+ except Exception:
|
||||
+ if ignore_errors:
|
||||
+ continue
|
||||
+ else:
|
||||
+ raise
|
||||
+
|
||||
+ if q.is_response(r):
|
||||
+ return r
|
||||
+ else:
|
||||
+ if ignore_errors:
|
||||
+ continue
|
||||
+ else:
|
||||
+ raise BadResponse
|
||||
+ finally:
|
||||
s.close()
|
||||
- r = dns.message.from_wire(wire, keyring=q.keyring, request_mac=q.mac,
|
||||
- one_rr_per_rrset=one_rr_per_rrset)
|
||||
- r.time = response_time
|
||||
- if not q.is_response(r):
|
||||
- raise BadResponse
|
||||
- return r
|
||||
|
||||
|
||||
def _net_read(sock, count, expiration):
|
||||
--
|
||||
2.44.0
|
||||
|
161
SOURCES/fix_unicode_label_escaping.patch
Normal file
161
SOURCES/fix_unicode_label_escaping.patch
Normal file
@ -0,0 +1,161 @@
|
||||
From c28f0584ba37cd6b0e9919dcbec652a34a420843 Mon Sep 17 00:00:00 2001
|
||||
From: Lumir Balhar <lbalhar@redhat.com>
|
||||
Date: Wed, 28 Aug 2019 14:10:36 +0200
|
||||
Subject: [PATCH] Backported original patch from:
|
||||
https://github.com/rthalley/dnspython/commit/c76aa6ac9969447220c8e807aa1e5640a6c12924
|
||||
|
||||
Unicode label escapify was not escapifying special characters. [Issue #339]
|
||||
---
|
||||
dns/name.py | 57 +++++++++++++++++++++++-----------------------
|
||||
tests/test_name.py | 5 ++++
|
||||
2 files changed, 34 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/dns/name.py b/dns/name.py
|
||||
index 97e216c..4a064d6 100644
|
||||
--- a/dns/name.py
|
||||
+++ b/dns/name.py
|
||||
@@ -116,20 +116,28 @@ class IDNACodec(object):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
+ def is_idna(self, label):
|
||||
+ return label.lower().startswith(b'xn--')
|
||||
+
|
||||
+ def is_all_ascii(self, label):
|
||||
+ for c in label:
|
||||
+ if ord(c) > 0x7f:
|
||||
+ return False
|
||||
+ return True
|
||||
+
|
||||
def encode(self, label):
|
||||
raise NotImplementedError
|
||||
|
||||
def decode(self, label):
|
||||
- # We do not apply any IDNA policy on decode; we just
|
||||
- downcased = label.lower()
|
||||
- if downcased.startswith(b'xn--'):
|
||||
+ # We do not apply any IDNA policy on decode.
|
||||
+ if self.is_idna(label):
|
||||
try:
|
||||
- label = downcased[4:].decode('punycode')
|
||||
+ label = label[4:].decode('punycode')
|
||||
except Exception as e:
|
||||
raise IDNAException(idna_exception=e)
|
||||
else:
|
||||
label = maybe_decode(label)
|
||||
- return _escapify(label, True)
|
||||
+ return _escapify(label)
|
||||
|
||||
class IDNA2003Codec(IDNACodec):
|
||||
|
||||
@@ -159,7 +167,7 @@ class IDNA2003Codec(IDNACodec):
|
||||
if label == b'':
|
||||
return u''
|
||||
try:
|
||||
- return _escapify(encodings.idna.ToUnicode(label), True)
|
||||
+ return _escapify(encodings.idna.ToUnicode(label))
|
||||
except Exception as e:
|
||||
raise IDNAException(idna_exception=e)
|
||||
|
||||
@@ -197,12 +205,6 @@ class IDNA2008Codec(IDNACodec):
|
||||
self.allow_pure_ascii = allow_pure_ascii
|
||||
self.strict_decode = strict_decode
|
||||
|
||||
- def is_all_ascii(self, label):
|
||||
- for c in label:
|
||||
- if ord(c) > 0x7f:
|
||||
- return False
|
||||
- return True
|
||||
-
|
||||
def encode(self, label):
|
||||
if label == '':
|
||||
return b''
|
||||
@@ -227,11 +229,12 @@ class IDNA2008Codec(IDNACodec):
|
||||
try:
|
||||
if self.uts_46:
|
||||
label = idna.uts46_remap(label, False, False)
|
||||
- return _escapify(idna.ulabel(label), True)
|
||||
+ return _escapify(idna.ulabel(label))
|
||||
except idna.IDNAError as e:
|
||||
raise IDNAException(idna_exception=e)
|
||||
|
||||
_escaped = bytearray(b'"().;\\@$')
|
||||
+_escaped_text = '"().;\\@$'
|
||||
|
||||
IDNA_2003_Practical = IDNA2003Codec(False)
|
||||
IDNA_2003_Strict = IDNA2003Codec(True)
|
||||
@@ -242,13 +245,13 @@ IDNA_2008_Strict = IDNA2008Codec(False, False, False, True)
|
||||
IDNA_2008_Transitional = IDNA2008Codec(True, True, False, False)
|
||||
IDNA_2008 = IDNA_2008_Practical
|
||||
|
||||
-def _escapify(label, unicode_mode=False):
|
||||
+def _escapify(label):
|
||||
"""Escape the characters in label which need it.
|
||||
- @param unicode_mode: escapify only special and whitespace (<= 0x20)
|
||||
- characters
|
||||
@returns: the escaped string
|
||||
@rtype: string"""
|
||||
- if not unicode_mode:
|
||||
+ if isinstance(label, bytes):
|
||||
+ # Ordinary DNS label mode. Escape special characters and values
|
||||
+ # < 0x20 or > 0x7f.
|
||||
text = ''
|
||||
if isinstance(label, text_type):
|
||||
label = label.encode()
|
||||
@@ -259,19 +262,17 @@ def _escapify(label, unicode_mode=False):
|
||||
text += chr(c)
|
||||
else:
|
||||
text += '\\%03d' % c
|
||||
- return text.encode()
|
||||
+ return text
|
||||
|
||||
+ # Unicode label mode. Escape only special characters and values < 0x20
|
||||
text = u''
|
||||
- if isinstance(label, binary_type):
|
||||
- label = label.decode()
|
||||
for c in label:
|
||||
- if c > u'\x20' and c < u'\x7f':
|
||||
- text += c
|
||||
+ if c in _escaped_text:
|
||||
+ text += '\\' + c
|
||||
+ elif c <= '\x20':
|
||||
+ text += '\\%03d' % ord(c)
|
||||
else:
|
||||
- if c >= u'\x7f':
|
||||
- text += c
|
||||
- else:
|
||||
- text += u'\\%03d' % ord(c)
|
||||
+ text += c
|
||||
return text
|
||||
|
||||
def _validate_labels(labels):
|
||||
@@ -519,8 +520,8 @@ class Name(object):
|
||||
l = self.labels[:-1]
|
||||
else:
|
||||
l = self.labels
|
||||
- s = b'.'.join(map(_escapify, l))
|
||||
- return maybe_decode(s)
|
||||
+ s = '.'.join(map(_escapify, l))
|
||||
+ return s
|
||||
|
||||
def to_unicode(self, omit_final_dot=False, idna_codec=None):
|
||||
"""Convert name to Unicode text format.
|
||||
diff --git a/tests/test_name.py b/tests/test_name.py
|
||||
index f2a8773..fa1d3eb 100644
|
||||
--- a/tests/test_name.py
|
||||
+++ b/tests/test_name.py
|
||||
@@ -255,6 +255,11 @@ class NameTestCase(unittest.TestCase):
|
||||
t = dns.name.root.to_unicode()
|
||||
self.assertEqual(t, '.')
|
||||
|
||||
+ def testToText12(self):
|
||||
+ n = dns.name.from_text(r'a\.b.c')
|
||||
+ t = n.to_unicode()
|
||||
+ self.assertEqual(t, r'a\.b.c.')
|
||||
+
|
||||
def testSlice1(self):
|
||||
n = dns.name.from_text(r'a.b.c.', origin=None)
|
||||
s = n[:]
|
||||
--
|
||||
2.21.0
|
||||
|
14
SOURCES/float_none_comparison_fix.patch
Normal file
14
SOURCES/float_none_comparison_fix.patch
Normal file
@ -0,0 +1,14 @@
|
||||
diff --git a/dns/query.py b/dns/query.py
|
||||
index bfecd43..19b9fbb 100644
|
||||
--- a/dns/query.py
|
||||
+++ b/dns/query.py
|
||||
@@ -467,7 +467,8 @@ def xfr(where, zone, rdtype=dns.rdatatype.AXFR, rdclass=dns.rdataclass.IN,
|
||||
first = True
|
||||
while not done:
|
||||
mexpiration = _compute_expiration(timeout)
|
||||
- if mexpiration is None or mexpiration > expiration:
|
||||
+ if mexpiration is None or \
|
||||
+ (expiration is not None and mexpiration > expiration):
|
||||
mexpiration = expiration
|
||||
if use_udp:
|
||||
_wait_for_readable(s, expiration)
|
@ -1,6 +1,6 @@
|
||||
Name: python-dns
|
||||
Version: 1.15.0
|
||||
Release: 8%{?dist}
|
||||
Release: 12%{?dist}
|
||||
Summary: DNS toolkit for Python
|
||||
|
||||
License: MIT
|
||||
@ -10,6 +10,19 @@ Source0: http://www.dnspython.org/kits/%{version}/dnspython-%{version}.tar.gz
|
||||
|
||||
BuildArch: noarch
|
||||
Patch0: test_fails_on_missing_file.patch
|
||||
# Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1731081
|
||||
# Upstream issue: https://github.com/rthalley/dnspython/issues/339
|
||||
Patch1: fix_unicode_label_escaping.patch
|
||||
|
||||
# Fixes https://bugzilla.redhat.com/show_bug.cgi?id=2075187
|
||||
# Backported from upstream: https://github.com/rthalley/dnspython/commit/9fbf9b223dc26262b1cf23f623f89283ee9c8375
|
||||
Patch2: float_none_comparison_fix.patch
|
||||
|
||||
# Fix for CVE-2023-29483
|
||||
# Upstream fix:
|
||||
# https://github.com/rthalley/dnspython/commit/f66e25b5f549acf66d1fb6ead13eb3cff7d09af3
|
||||
# Backported to completely different codebase hence not very similar to upstream fix.
|
||||
Patch3: CVE-2023-29483.patch
|
||||
|
||||
BuildRequires: python3-devel
|
||||
BuildRequires: python3-setuptools
|
||||
@ -68,7 +81,23 @@ find examples -type f | xargs chmod a-x
|
||||
|
||||
|
||||
%changelog
|
||||
* Mon Aug 27 2018 Miro Hrončok <mhroncok@redhat.com>
|
||||
* Mon Apr 22 2024 Lumír Balhar <lbalhar@redhat.com> - 1.15.0-12
|
||||
- Security fix for CVE-2023-29483
|
||||
Resolves: RHEL-32630
|
||||
|
||||
* Thu Apr 21 2022 Charalampos Stratakis <cstratak@redhat.com> - 1.15.0-11
|
||||
- Fix comparison between float and None types
|
||||
Resolves: rhbz#2075187
|
||||
|
||||
* Thu Oct 24 2019 Lumír Balhar <lbalhar@redhat.com> - 1.15.0-10
|
||||
- Release bump for gating
|
||||
Related: rhbz#1731081
|
||||
|
||||
* Wed Aug 28 2019 Lumír Balhar <lbalhar@redhat.com> - 1.15.0-9
|
||||
- Fix unicode label escaping
|
||||
Resolves: rhbz#1731081
|
||||
|
||||
* Mon Aug 27 2018 Miro Hrončok <mhroncok@redhat.com> - 1.15.0-8
|
||||
- Drop python2 subpackage (#1567168)
|
||||
|
||||
* Mon Jun 25 2018 Petr Viktorin <pviktori@redhat.com> - 1.15.0-7
|
||||
|
Loading…
Reference in New Issue
Block a user