summaryrefslogtreecommitdiff
path: root/src/dnsproxy.c
diff options
context:
space:
mode:
authorJukka Rissanen <jukka.rissanen@linux.intel.com>2012-10-03 13:55:56 +0300
committerPatrik Flykt <patrik.flykt@linux.intel.com>2012-10-03 14:12:54 +0300
commit297a1d9c92957c7cfb7a0275056cde5acd9924f8 (patch)
tree7d326639a3e1fbeb810e01297af132447644afd1 /src/dnsproxy.c
parentbefa87b573879fd0935994c96af744a99252bffa (diff)
downloadconnman-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.c31
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);