Skip to content

DNS RR encodes 8-bit rname incorrectly #1967

@arnout

Description

@arnout

Brief description

DNS should support 8-bit characters in names. However, DNSRR does not convert a correctly UTF-8 encoded rname correctly into a DNS path.

Environment

  • Scapy version: 5c9a7789

How to reproduce

Create a DNSRR with an 8-bit character in the rrname (e.g. a valid non-ASCII UTF-8 character).

bytes(DNSRR(rrname='a\u0080b.'))

Actual result

b'a\xc2\x80b.\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00'
  ^ Not correctly path/length encoded

Expected result

b'\x04a\xc2\x80b\x00\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00'
       ^^^^^^^^ UTF-8 encoding of U+0080
  ^^^^ 4 bytes in path component

Proposed fix

I believe the following patch solves the issue.

diff --git a/scapy/layers/dns.py b/scapy/layers/dns.py
index 48453867..31b897b4 100755
--- a/scapy/layers/dns.py
+++ b/scapy/layers/dns.py
@@ -194,7 +194,7 @@ class DNSStrField(StrField):
         return x
 
     def i2m(self, pkt, x):
-        if any((orb(y) >= 0xc0) for y in x):
+        if b'.' not in x and x[-1] == b"\x00":
             # The value has already been processed. Do not process it again
             return x

The check was introduced by fdae9df "DNS improvements & compression". Compression is indeed indicated by a length byte with a value >= 0xc0. However, such characters may actually occur in the name so it's not a good check. Since the conversion removes all dots (path splitting), it is a much more reliable marker.

However, I think the check might even be removed entirely. AFAIU, the result of i2m is not saved.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions