Commit 2fa18b47 authored by Deomid Ryabkov's avatar Deomid Ryabkov Committed by Cesanta Bot

Fix DNS name uncompression

PUBLISHED_FROM=07e820f539fa5feca2ad1cf81faca8404b773a65
parent c8af7cdd
...@@ -10835,7 +10835,7 @@ int mg_parse_dns(const char *buf, int len, struct mg_dns_message *msg) { ...@@ -10835,7 +10835,7 @@ int mg_parse_dns(const char *buf, int len, struct mg_dns_message *msg) {
size_t mg_dns_uncompress_name(struct mg_dns_message *msg, struct mg_str *name, size_t mg_dns_uncompress_name(struct mg_dns_message *msg, struct mg_str *name,
char *dst, int dst_len) { char *dst, int dst_len) {
int chunk_len; int chunk_len, num_ptrs = 0;
char *old_dst = dst; char *old_dst = dst;
const unsigned char *data = (unsigned char *) name->p; const unsigned char *data = (unsigned char *) name->p;
const unsigned char *end = (unsigned char *) msg->pkt.p + msg->pkt.len; const unsigned char *end = (unsigned char *) msg->pkt.p + msg->pkt.len;
...@@ -10850,14 +10850,21 @@ size_t mg_dns_uncompress_name(struct mg_dns_message *msg, struct mg_str *name, ...@@ -10850,14 +10850,21 @@ size_t mg_dns_uncompress_name(struct mg_dns_message *msg, struct mg_str *name,
return 0; return 0;
} }
if (chunk_len & 0xc0) { if ((chunk_len & 0xc0) == 0xc0) {
uint16_t off = (data[-1] & (~0xc0)) << 8 | data[0]; uint16_t off = (data[-1] & (~0xc0)) << 8 | data[0];
if (off >= msg->pkt.len) { if (off >= msg->pkt.len) {
return 0; return 0;
} }
/* Basic circular loop avoidance: allow up to 16 pointer hops. */
if (++num_ptrs > 15) {
return 0;
}
data = (unsigned char *) msg->pkt.p + off; data = (unsigned char *) msg->pkt.p + off;
continue; continue;
} }
if (chunk_len > 63) {
return 0;
}
if (chunk_len > leeway) { if (chunk_len > leeway) {
chunk_len = leeway; chunk_len = leeway;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment