Skip to content

Commit

Permalink
DNS compression loop detection
Browse files Browse the repository at this point in the history
- `dns_protocol`: Issue DNS-OARC#291: Implement proper loop detection during decompression
  • Loading branch information
jelu committed Jun 28, 2023
1 parent c18a3c7 commit bd13aa3
Showing 1 changed file with 12 additions and 6 deletions.
18 changes: 12 additions & 6 deletions src/dns_protocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,11 @@ static int rfc1035NameUnpack(const u_char* buf, size_t sz, off_t* off, char* nam
off_t no = 0;
unsigned char c;
size_t len;
static int loop_detect = 0;
if (loop_detect > 2)
return 4; /* compression loop */
/*
* loop_detect[] tracks which position in the DNS message it has
* jumped to so it can't jump to the same twice, aka loop
*/
static unsigned char loop_detect[0x3FFF] = { 0 };
if (ns <= 0)
return 4; /* probably compression loop */
do {
Expand All @@ -66,7 +68,7 @@ static int rfc1035NameUnpack(const u_char* buf, size_t sz, off_t* off, char* nam
/* blasted compression */
int rc;
unsigned short s;
off_t ptr;
off_t ptr, loop_ptr;
s = nptohs(buf + (*off));
(*off) += sizeof(s);
/* Sanity check */
Expand All @@ -78,9 +80,13 @@ static int rfc1035NameUnpack(const u_char* buf, size_t sz, off_t* off, char* nam
return 2; /* bad compression ptr */
if (ptr < DNS_MSG_HDR_SZ)
return 2; /* bad compression ptr */
loop_detect++;
if (loop_detect[ptr])
return 4; /* compression loop */
loop_detect[(loop_ptr = ptr)] = 1;

rc = rfc1035NameUnpack(buf, sz, &ptr, name + no, ns - no);
loop_detect--;

loop_detect[loop_ptr] = 0;
return rc;
} else if (c > RFC1035_MAXLABELSZ) {
/*
Expand Down

0 comments on commit bd13aa3

Please sign in to comment.