libtins icon indicating copy to clipboard operation
libtins copied to clipboard

Parsing ip6.arpa DNS PTR replies throws an exception

Open pyksy opened this issue 3 months ago • 1 comments

Platform: GNU/Linux

After constructing a TINS::DNS object with a valid DNS reply packet that contains an ip6.arpa PTR record, DNS::answers() throws a "DNS decompression: pointer loops" exception.

In my testing I used the DNS reply packet created by this dig command: dig @8.8.8.8 2.2.2.0.4.0.0.0.0.0.0.0.0.0.0.0.5.0.0.0.0.0.0.0.8.0.7.0.1.0.0.2.ip6.arpa ptr ip6_arpa_dns_reply.pcap.gz

I think the exception gets thrown due to faulty tracking of pointer chains during DNS name decompression. In DNS::compose_name() there is this check

if (pointer_counter++ > 30){
    throw dns_decompression_pointer_loops();
}

which throws the exception on my perfectly valid ip6.arpa PTR reply.

~~Instead of counting pointers, I think it could be replaced by tracking the visited offsets for duplicates~~ EDIT: I thought wrong. The pointers cannot be tracked just locally. This is not a working fix.

#include <set>
 
[ ... ]
std::set<const uint8_t*> visited_ptrs;
[ ... ]
if (!visited_ptrs.insert(ptr).second) {
    throw dns_decompression_pointer_loops();
}
[ ... ]

pyksy avatar Oct 03 '25 20:10 pyksy

I think the pointer counting and checking should be performed only after following compression pointers instead of for every label, by moving the pointer loop check under the pointer offset check.

pyksy avatar Oct 04 '25 11:10 pyksy