Skip to content

Commit

Permalink
Dnspython 2.6.1 - Address DoS via the Tudoor mechanism (CVE-2023-29483)
Browse files Browse the repository at this point in the history
Fix for (CVE-2023-29483) and handling of truncated exceptions in greendns.py provided by Bob Halley from https://github.com/rthalley/eventlet/tree/tudoor

Do not eat legitimate Truncated exceptions.
---------
Co-authored-by: Bob Halley <halley@play-bow.org>
Co-authored-by: Hervé Beraud <hberaud@redhat.com>
  • Loading branch information
kelvin-j-li committed Feb 19, 2024
1 parent b6f6e7c commit 51e3c49
Showing 1 changed file with 38 additions and 18 deletions.
56 changes: 38 additions & 18 deletions eventlet/support/greendns.py
Original file line number Diff line number Diff line change
Expand Up @@ -713,7 +713,7 @@ def _net_write(sock, data, expiration):
def udp(q, where, timeout=DNS_QUERY_TIMEOUT, port=53,
af=None, source=None, source_port=0, ignore_unexpected=False,
one_rr_per_rrset=False, ignore_trailing=False,
raise_on_truncation=False, sock=None):
raise_on_truncation=False, sock=None, ignore_errors=False):
"""coro friendly replacement for dns.query.udp
Return the response obtained after sending a query via UDP.
Expand Down Expand Up @@ -752,7 +752,10 @@ def udp(q, where, timeout=DNS_QUERY_TIMEOUT, port=53,
query. If None, the default, a socket is created. Note that
if a socket is provided, it must be a nonblocking datagram socket,
and the source and source_port are ignored.
@type sock: socket.socket | None"""
@type sock: socket.socket | None
@param ignore_errors: if various format errors or response mismatches occur,
continue listening.
@type ignore_errors: bool"""

wire = q.to_wire()
if af is None:
Expand Down Expand Up @@ -816,26 +819,43 @@ def udp(q, where, timeout=DNS_QUERY_TIMEOUT, port=53,
addr = from_address[0]
addr = dns.ipv6.inet_ntoa(dns.ipv6.inet_aton(addr))
from_address = (addr, from_address[1], from_address[2], from_address[3])
if from_address == destination:
if from_address != destination:
if ignore_unexpected:
continue
else:
raise dns.query.UnexpectedSource(
'got a response from %s instead of %s'
% (from_address, destination))
try:
if _handle_raise_on_truncation:
r = dns.message.from_wire(wire,
keyring=q.keyring,
request_mac=q.mac,
one_rr_per_rrset=one_rr_per_rrset,
ignore_trailing=ignore_trailing,
raise_on_truncation=raise_on_truncation)
else:
r = dns.message.from_wire(wire,
keyring=q.keyring,
request_mac=q.mac,
one_rr_per_rrset=one_rr_per_rrset,
ignore_trailing=ignore_trailing)
if not q.is_response(r):
raise dns.query.BadResponse()
break
if not ignore_unexpected:
raise dns.query.UnexpectedSource(
'got a response from %s instead of %s'
% (from_address, destination))
except dns.message.Truncated as e:
if ignore_errors and not q.is_response(e.message()):
continue
else:
raise
except Exception:
if ignore_errors:
continue
else:
raise
finally:
s.close()

if _handle_raise_on_truncation:
r = dns.message.from_wire(wire, keyring=q.keyring, request_mac=q.mac,
one_rr_per_rrset=one_rr_per_rrset,
ignore_trailing=ignore_trailing,
raise_on_truncation=raise_on_truncation)
else:
r = dns.message.from_wire(wire, keyring=q.keyring, request_mac=q.mac,
one_rr_per_rrset=one_rr_per_rrset,
ignore_trailing=ignore_trailing)
if not q.is_response(r):
raise dns.query.BadResponse()
return r


Expand Down

0 comments on commit 51e3c49

Please sign in to comment.