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);
* 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;
* 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];
} 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;
}
* 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;
bool server_enabled = false;
GSList *list;
int index;
+ int vpn_index;
DBG("service %p", 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;
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;