diff options
author | Jukka Rissanen <jukka.rissanen@linux.intel.com> | 2012-10-03 13:55:56 +0300 |
---|---|---|
committer | Patrik Flykt <patrik.flykt@linux.intel.com> | 2012-10-03 14:12:54 +0300 |
commit | 297a1d9c92957c7cfb7a0275056cde5acd9924f8 (patch) | |
tree | 7d326639a3e1fbeb810e01297af132447644afd1 /src/dnsproxy.c | |
parent | befa87b573879fd0935994c96af744a99252bffa (diff) | |
download | connman-297a1d9c92957c7cfb7a0275056cde5acd9924f8.tar.gz connman-297a1d9c92957c7cfb7a0275056cde5acd9924f8.tar.bz2 connman-297a1d9c92957c7cfb7a0275056cde5acd9924f8.zip |
dnsproxy: Do not overwrite protocol and channel in server struct
We copied too much data into addrinfo struct which corrupted
the protocol and channel fields.
Fixes BMC#25726
Diffstat (limited to 'src/dnsproxy.c')
-rw-r--r-- | src/dnsproxy.c | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/src/dnsproxy.c b/src/dnsproxy.c index 719c1706..2a2e52c3 100644 --- a/src/dnsproxy.c +++ b/src/dnsproxy.c @@ -86,7 +86,7 @@ struct server_data { char *interface; GList *domains; char *server; - struct sockaddr server_addr; + struct sockaddr *server_addr; socklen_t server_addr_len; int protocol; GIOChannel *channel; @@ -249,7 +249,7 @@ static struct server_data *find_server(const char *interface, { GSList *list; - DBG("interface %s server %s", interface, server); + DBG("interface %s server %s proto %d", interface, server, protocol); for (list = server_list; list; list = list->next) { struct server_data *data = list->data; @@ -1508,7 +1508,7 @@ static int ns_resolv(struct server_data *server, struct request_data *req, sk = g_io_channel_unix_get_fd(server->channel); err = sendto(sk, request, req->request_len, MSG_NOSIGNAL, - &server->server_addr, server->server_addr_len); + server->server_addr, server->server_addr_len); if (err < 0) { DBG("Cannot send message to server %s sock %d " "protocol %d (%s/%d)", @@ -1767,6 +1767,7 @@ static void destroy_server(struct server_data *server) g_free(domain); } g_free(server->interface); + g_free(server->server_addr); /* * We do not remove cache right away but delay it few seconds. @@ -2023,7 +2024,7 @@ static struct server_data *create_server(const char *interface, struct server_data *data; int sk, ret; - DBG("interface %s server %s", interface, server); + DBG("interface %s server %s proto %d", interface, server, protocol); memset(&hints, 0, sizeof(hints)); @@ -2110,7 +2111,27 @@ static struct server_data *create_server(const char *interface, data->server = g_strdup(server); data->protocol = protocol; data->server_addr_len = rp->ai_addrlen; - memcpy(&data->server_addr, rp->ai_addr, rp->ai_addrlen); + + switch (rp->ai_family) { + case AF_INET: + data->server_addr = (struct sockaddr *) + g_try_new0(struct sockaddr_in, 1); + break; + case AF_INET6: + data->server_addr = (struct sockaddr *) + g_try_new0(struct sockaddr_in6, 1); + break; + default: + connman_error("Wrong address family %d", rp->ai_family); + break; + } + if (data->server_addr == NULL) { + freeaddrinfo(rp); + close(sk); + g_free(data); + return NULL; + } + memcpy(data->server_addr, rp->ai_addr, rp->ai_addrlen); ret = connect(sk, rp->ai_addr, rp->ai_addrlen); freeaddrinfo(rp); |