Skip to content

Commit 14bb185

Browse files
authored
Merge pull request #444 from gaya-cohen/decompression-bug-fix
Fix DNS decompression bug and add descriptive exceptions
2 parents 5858132 + 137b56d commit 14bb185

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed

include/tins/exceptions.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,26 @@ class option_not_found : public exception_base {
6464
class malformed_packet : public exception_base {
6565
public:
6666
malformed_packet() : exception_base("Malformed packet") { }
67+
malformed_packet(const std::string& message) : exception_base(message) { }
6768
};
6869

70+
/**
71+
* \brief Exception thrown when a DNS decompression pointer is out of bounds.
72+
*/
73+
class dns_decompression_pointer_out_of_bounds : public malformed_packet {
74+
public:
75+
dns_decompression_pointer_out_of_bounds() : malformed_packet("DNS decompression: pointer out of bounds") { }
76+
};
77+
78+
/**
79+
* \brief Exception thrown when a DNS decompression pointer loops.
80+
*/
81+
class dns_decompression_pointer_loops : public malformed_packet {
82+
public:
83+
dns_decompression_pointer_loops() : malformed_packet("DNS decompression: pointer loops") { }
84+
};
85+
86+
6987
/**
7088
* \brief Exception thrown when serializing a packet fails.
7189
*/

src/dns.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,11 @@ uint32_t DNS::compose_name(const uint8_t* ptr, char* out_ptr) const {
336336
const uint8_t* end = &records_data_[0] + records_data_.size();
337337
const uint8_t* end_ptr = 0;
338338
char* current_out_ptr = out_ptr;
339+
uint8_t pointer_counter = 0;
339340
while (*ptr) {
341+
if (pointer_counter++ > 30){
342+
throw dns_decompression_pointer_loops();
343+
}
340344
// It's an offset
341345
if ((*ptr & 0xc0)) {
342346
if (TINS_UNLIKELY(ptr + sizeof(uint16_t) > end)) {
@@ -347,7 +351,7 @@ uint32_t DNS::compose_name(const uint8_t* ptr, char* out_ptr) const {
347351
index = Endian::be_to_host(index) & 0x3fff;
348352
// Check that the offset is neither too low or too high
349353
if (index < 0x0c || (&records_data_[0] + (index - 0x0c)) >= end) {
350-
throw malformed_packet();
354+
throw dns_decompression_pointer_out_of_bounds();
351355
}
352356
// We've probably found the end of the original domain name. Save it.
353357
if (end_ptr == 0) {

0 commit comments

Comments
 (0)