Opened 10 years ago

Last modified 5 years ago

#380 closed defect (Fixed)

remote DoS in async DNS code

Reported by: jonojono Owned by:
Priority: High Milestone:
Component: Core Tor/Tor Version: 0.1.0.18
Severity: Keywords:
Cc: jonojono, arma Actual Points:
Parent ID: Points:
Reviewer: Sponsor:

Description

Greetings,

A bug exists in the label pointer handling of Tor's async DNS code that
results in denial of service. A pointer loop, resulting from a pointer
that points to itself or pointers that pointer to each other, will cause
the parsing code to enter an endless loop.

This bug is present in Adam Langley's implementation and also in the
version included in libevent.

Regards,
Jon Oberheide

[Automatically added by flyspray2trac: Operating System: All]

Child Tickets

Change History (5)

comment:1 Changed 10 years ago by arma

Great. We need a few more hints though. :)

What symptoms do you experience? Are there certain configurations or
queries that can trigger this? Any other hints?

You reported the bug is in 0.1.0.18, but that doesn't ship our eventdns
stuff. Did you mean 0.1.1.26 or 0.1.2.6-alpha, or something else?

comment:2 Changed 10 years ago by nickm

We don't actually need a few more hints. Bugfix incoming. :)

comment:3 Changed 10 years ago by jonojono

The issue is present in the current SVN, sorry about the version mismark.

If you take a look at src/or/eventdns.c around line 752 in the name_parse()
function, you can see the issue:

<snip>

for(;;) {

u8 label_len;
if (j >= length) return -1;
GET8(label_len);
if (!label_len) break;
if (label_len & 0xc0) {

u8 ptr_low;
GET8(ptr_low);
if (name_end < 0) name_end = j;
j = (((int)label_len & 0x3f) << 8) + ptr_low;

if (j < 0
j >= length) return -1;

continue;

}

</snip>

When decoding hostnames, DNS allows for a special mechanism called a pointer
which redirects the parser to another area of the packet. For example, if an
RR with google.com is specified in the question section of a DNS A query, the
RR in the answer section can have a pointer to point back to that hostname in
the question section. While these pointers can save a bit of space in the
packet but avoiding redundant information, it makes them a bit trickier to
parse.

A pointer is determined by looking at the two high bits of the first bytes of
the label (line 757). If the first two bits are 11, the rest of the bytes and
the next byte are used to determine the offset to jump to (line 761). In the
affected code, creating a pointer that has an offset to itself will cause the
above for loop to continue endlessly.

For example, if j is at offset 20 when entering the for loop, and the 20th and
21st bytes of our packet are 0x0c 0x14, the parser will detect a pointer and
then set j to (0x0c & 0x3f) << 8) + 0x14 == 20. The continue statements sends
execution back up to the for loop and repeats the same operations.

This code is also present in libevent which is where I first discovered the
problem. Here is a simple example using libevent that demonstrates the DoS:

http://jon.oberheide.org/dns-loop.py
http://jon.oberheide.org/evdns.c

Regards,
Jon Oberheide

comment:4 Changed 10 years ago by nickm

flyspray2trac: bug closed.
Fixed in r9378.

comment:5 Changed 5 years ago by nickm

  • Component changed from Tor Client to Tor
Note: See TracTickets for help on using tickets.