Skip to content

Commit

Permalink
Merge pull request mfontanini#444 from gaya-cohen/decompression-bug-fix
Browse files Browse the repository at this point in the history
Fix DNS decompression bug and add descriptive exceptions
  • Loading branch information
mfontanini authored Jun 9, 2021
2 parents 5858132 + 137b56d commit 14bb185
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 1 deletion.
18 changes: 18 additions & 0 deletions include/tins/exceptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,26 @@ class option_not_found : public exception_base {
class malformed_packet : public exception_base {
public:
malformed_packet() : exception_base("Malformed packet") { }
malformed_packet(const std::string& message) : exception_base(message) { }
};

/**
* \brief Exception thrown when a DNS decompression pointer is out of bounds.
*/
class dns_decompression_pointer_out_of_bounds : public malformed_packet {
public:
dns_decompression_pointer_out_of_bounds() : malformed_packet("DNS decompression: pointer out of bounds") { }
};

/**
* \brief Exception thrown when a DNS decompression pointer loops.
*/
class dns_decompression_pointer_loops : public malformed_packet {
public:
dns_decompression_pointer_loops() : malformed_packet("DNS decompression: pointer loops") { }
};


/**
* \brief Exception thrown when serializing a packet fails.
*/
Expand Down
6 changes: 5 additions & 1 deletion src/dns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,11 @@ uint32_t DNS::compose_name(const uint8_t* ptr, char* out_ptr) const {
const uint8_t* end = &records_data_[0] + records_data_.size();
const uint8_t* end_ptr = 0;
char* current_out_ptr = out_ptr;
uint8_t pointer_counter = 0;
while (*ptr) {
if (pointer_counter++ > 30){
throw dns_decompression_pointer_loops();
}
// It's an offset
if ((*ptr & 0xc0)) {
if (TINS_UNLIKELY(ptr + sizeof(uint16_t) > end)) {
Expand All @@ -347,7 +351,7 @@ uint32_t DNS::compose_name(const uint8_t* ptr, char* out_ptr) const {
index = Endian::be_to_host(index) & 0x3fff;
// Check that the offset is neither too low or too high
if (index < 0x0c || (&records_data_[0] + (index - 0x0c)) >= end) {
throw malformed_packet();
throw dns_decompression_pointer_out_of_bounds();
}
// We've probably found the end of the original domain name. Save it.
if (end_ptr == 0) {
Expand Down

0 comments on commit 14bb185

Please sign in to comment.