We copied too much data into addrinfo struct which corrupted
the protocol and channel fields.
Fixes BMC#25726
char *interface;
GList *domains;
char *server;
char *interface;
GList *domains;
char *server;
- struct sockaddr server_addr;
+ struct sockaddr *server_addr;
socklen_t server_addr_len;
int protocol;
GIOChannel *channel;
socklen_t server_addr_len;
int protocol;
GIOChannel *channel;
- 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;
for (list = server_list; list; list = list->next) {
struct server_data *data = list->data;
sk = g_io_channel_unix_get_fd(server->channel);
err = sendto(sk, request, req->request_len, MSG_NOSIGNAL,
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)",
if (err < 0) {
DBG("Cannot send message to server %s sock %d "
"protocol %d (%s/%d)",
g_free(domain);
}
g_free(server->interface);
g_free(domain);
}
g_free(server->interface);
+ g_free(server->server_addr);
/*
* We do not remove cache right away but delay it few seconds.
/*
* We do not remove cache right away but delay it few seconds.
struct server_data *data;
int sk, ret;
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));
memset(&hints, 0, sizeof(hints));
data->server = g_strdup(server);
data->protocol = protocol;
data->server_addr_len = rp->ai_addrlen;
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);
ret = connect(sk, rp->ai_addr, rp->ai_addrlen);
freeaddrinfo(rp);