From 08efe8080a1ba9982dc40446ebacc68bfb668041 Mon Sep 17 00:00:00 2001 From: Patrik Flykt Date: Thu, 25 Oct 2012 13:52:22 +0300 Subject: dnsproxy: Add reply host part length checking Check that the first part of the name is not of zero length before attempting to calculate the length of the domain part. Also ensure the domain lenght checking does not run outside of the receive buffer. Also add debug messages for ids and lengths in order to pinpoint any possible problems. --- src/dnsproxy.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/dnsproxy.c b/src/dnsproxy.c index 2a2e52c3..17d9a20c 100644 --- a/src/dnsproxy.c +++ b/src/dnsproxy.c @@ -1570,6 +1570,9 @@ static int ns_resolv(struct server_data *server, struct request_data *req, alt[1] = req_len & 0xff; } + DBG("req %p dstid 0x%04x altid 0x%04x", req, req->dstid, + req->altid); + err = send(sk, alt, req->request_len + domlen, MSG_NOSIGNAL); if (err < 0) return -EIO; @@ -1611,7 +1614,8 @@ static int forward_dns_reply(unsigned char *reply, int reply_len, int protocol, if (req == NULL) return -EINVAL; - DBG("id 0x%04x rcode %d", hdr->id, hdr->rcode); + DBG("req %p dstid 0x%04x altid 0x%04x rcode %d", + req, req->dstid, req->altid, hdr->rcode); ifdata = req->ifdata; @@ -1627,17 +1631,25 @@ static int forward_dns_reply(unsigned char *reply, int reply_len, int protocol, * remove it before forwarding the reply. */ if (req->append_domain == TRUE) { + unsigned int domain_len = 0; unsigned char *ptr; uint8_t host_len; - unsigned int domain_len; + unsigned int header_len; /* * ptr points to the first char of the hostname. * ->hostname.domain.net */ - ptr = reply + offset + sizeof(struct domain_hdr); + header_len = offset + sizeof(struct domain_hdr); + ptr = reply + header_len; host_len = *ptr; - domain_len = strlen((const char *)ptr + host_len + 1); + if (host_len > 0) + domain_len = strnlen((const char *)ptr + 1 + + host_len, + reply_len - header_len); + + + DBG("host len %d domain len %d", host_len, domain_len); /* * Remove the domain name and replace it by the end @@ -1657,7 +1669,7 @@ static int forward_dns_reply(unsigned char *reply, int reply_len, int protocol, */ memmove(ptr + host_len + 1, ptr + host_len + domain_len + 1, - reply_len - (ptr - reply + domain_len)); + reply_len - header_len - domain_len); reply_len = reply_len - domain_len; } -- cgit v1.2.3