X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fdnsproxy.c;fp=src%2Fdnsproxy.c;h=18dc6480bac7e81dbb58e82d78af980548a8ea13;hb=bf0e619ef451bde3568c1af509ccb12cbda2ff93;hp=7956e7fb17bdf335e665bcf441c39f5ffcc80ea0;hpb=2985b9822ac3f5acfef2933cbda98c1285e11af4;p=platform%2Fupstream%2Fconnman.git diff --git a/src/dnsproxy.c b/src/dnsproxy.c index 7956e7f..18dc648 100755 --- a/src/dnsproxy.c +++ b/src/dnsproxy.c @@ -1819,6 +1819,7 @@ static char *uncompress(int16_t field_count, char *start, char *end, char **uncompressed_ptr) { char *uptr = *uncompressed_ptr; /* position in result buffer */ + char * const uncomp_end = uncompressed + uncomp_len - 1; debug("count %d ptr %p end %p uptr %p", field_count, ptr, end, uptr); @@ -1839,14 +1840,15 @@ static char *uncompress(int16_t field_count, char *start, char *end, * tmp buffer. */ - ulen = strlen(name); - strncpy(uptr, name, uncomp_len - (uptr - uncompressed)); + ulen = strlen(name) + 1; + if ((uptr + ulen) > uncomp_end) + goto out; + strncpy(uptr, name, ulen); debug("pos %d ulen %d left %d name %s", pos, ulen, - (int)(uncomp_len - (uptr - uncompressed)), uptr); + (int)(uncomp_end - (uptr + ulen)), uptr); uptr += ulen; - *uptr++ = '\0'; ptr += pos; @@ -1854,6 +1856,10 @@ static char *uncompress(int16_t field_count, char *start, char *end, * We copy also the fixed portion of the result (type, class, * ttl, address length and the address) */ + if ((uptr + NS_RRFIXEDSZ) > uncomp_end) { + debug("uncompressed data too large for buffer"); + goto out; + } memcpy(uptr, ptr, NS_RRFIXEDSZ); dns_type = uptr[0] << 8 | uptr[1]; @@ -1885,7 +1891,7 @@ static char *uncompress(int16_t field_count, char *start, char *end, } else if (dns_type == ns_t_a || dns_type == ns_t_aaaa) { dlen = uptr[-2] << 8 | uptr[-1]; - if (ptr + dlen > end) { + if ((ptr + dlen) > end || (uptr + dlen) > uncomp_end) { debug("data len %d too long", dlen); goto out; } @@ -1924,6 +1930,10 @@ static char *uncompress(int16_t field_count, char *start, char *end, * refresh interval, retry interval, expiration * limit and minimum ttl). They are 20 bytes long. */ + if ((uptr + 20) > uncomp_end || (ptr + 20) > end) { + debug("soa record too long"); + goto out; + } memcpy(uptr, ptr, 20); uptr += 20; ptr += 20; @@ -3124,6 +3134,7 @@ static void dnsproxy_default_changed(struct connman_service *service) bool server_enabled = false; GSList *list; int index; + int vpn_index; DBG("service %p", service); @@ -3140,6 +3151,13 @@ static void dnsproxy_default_changed(struct connman_service *service) if (index < 0) return; + /* + * In case non-split-routed VPN is set as split routed the DNS servers + * the VPN must be enabled as well, when the transport becomes the + * default service. + */ + vpn_index = __connman_connection_get_vpn_index(index); + for (list = server_list; list; list = list->next) { struct server_data *data = list->data; @@ -3147,6 +3165,9 @@ static void dnsproxy_default_changed(struct connman_service *service) DBG("Enabling DNS server %s", data->server); data->enabled = true; server_enabled = true; + } else if (data->index == vpn_index) { + DBG("Enabling DNS server of VPN %s", data->server); + data->enabled = true; } else { DBG("Disabling DNS server %s", data->server); data->enabled = false;