diff options
author | Jukka Rissanen <jukka.rissanen@linux.intel.com> | 2012-06-01 15:02:06 +0300 |
---|---|---|
committer | Patrik Flykt <patrik.flykt@linux.intel.com> | 2012-06-07 10:39:46 +0300 |
commit | 4884c249bf7f098bbffd1a704a0a5ade573bee54 (patch) | |
tree | 0f6725d54308e737327d6e9e215887a8c031f47b /src | |
parent | ffcaa03b166c6eaaf57e7edbd633a4fd30d9fd93 (diff) | |
download | connman-4884c249bf7f098bbffd1a704a0a5ade573bee54.tar.gz connman-4884c249bf7f098bbffd1a704a0a5ade573bee54.tar.bz2 connman-4884c249bf7f098bbffd1a704a0a5ade573bee54.zip |
dnsproxy: Check overlapping memcpy
The problem was seen with valgrind. We tried to get hostname
without domain part and if server returns an error, we could
end up in situation where domain_len == 0 even if append_domain
is set to TRUE. So check that if domain_len is 0, then do not
try to memcpy.
Diffstat (limited to 'src')
-rw-r--r-- | src/dnsproxy.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/src/dnsproxy.c b/src/dnsproxy.c index efbc195f..f56c30cb 100644 --- a/src/dnsproxy.c +++ b/src/dnsproxy.c @@ -1554,14 +1554,23 @@ static int forward_dns_reply(unsigned char *reply, int reply_len, int protocol, domain_len = strlen((const char *)ptr + host_len + 1); /* - * remove the domain name and replace it by the end - * of reply. + * Remove the domain name and replace it by the end + * of reply. Check if the domain is really there + * before trying to copy the data. The domain_len can + * be 0 because if the original query did not contain + * a domain name, then we are sending two packets, + * first without the domain name and the second packet + * with domain name. The append_domain is set to true + * even if we sent the first packet without domain + * name. In this case we end up in this branch. */ - memcpy(ptr + host_len + 1, - ptr + host_len + domain_len + 1, - reply_len - (ptr - reply + domain_len)); + if (domain_len > 0) { + memcpy(ptr + host_len + 1, + ptr + host_len + domain_len + 1, + reply_len - (ptr - reply + domain_len)); - reply_len = reply_len - domain_len; + reply_len = reply_len - domain_len; + } } g_free(req->resp); |