From 2fa18b47db9ef17f1d1b3742c06bb25c0384bb54 Mon Sep 17 00:00:00 2001 From: Deomid Ryabkov Date: Wed, 6 Sep 2017 20:54:38 +0300 Subject: [PATCH] Fix DNS name uncompression PUBLISHED_FROM=07e820f539fa5feca2ad1cf81faca8404b773a65 --- mongoose.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/mongoose.c b/mongoose.c index c573e7aa..b3959e1a 100644 --- a/mongoose.c +++ b/mongoose.c @@ -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, char *dst, int dst_len) { - int chunk_len; + int chunk_len, num_ptrs = 0; char *old_dst = dst; const unsigned char *data = (unsigned char *) name->p; 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, return 0; } - if (chunk_len & 0xc0) { + if ((chunk_len & 0xc0) == 0xc0) { uint16_t off = (data[-1] & (~0xc0)) << 8 | data[0]; if (off >= msg->pkt.len) { 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; continue; } + if (chunk_len > 63) { + return 0; + } if (chunk_len > leeway) { chunk_len = leeway; }