diff options
author | Jukka Rissanen <jukka.rissanen@linux.intel.com> | 2012-05-03 15:27:23 +0300 |
---|---|---|
committer | Patrik Flykt <patrik.flykt@linux.intel.com> | 2012-05-04 12:14:45 +0300 |
commit | c1b968984212b46bea1330f5ae029507b9bfded9 (patch) | |
tree | e03481723bbbb0df2db06702c7255c13b3820023 /src | |
parent | b0ec6eb4466acc57a9ea8be52c17b674b6ea0618 (diff) | |
download | connman-c1b968984212b46bea1330f5ae029507b9bfded9.tar.gz connman-c1b968984212b46bea1330f5ae029507b9bfded9.tar.bz2 connman-c1b968984212b46bea1330f5ae029507b9bfded9.zip |
inet: Make sure that we only accept netlink messages from kernel
Diffstat (limited to 'src')
-rw-r--r-- | src/inet.c | 30 |
1 files changed, 20 insertions, 10 deletions
@@ -1991,27 +1991,37 @@ static int inet_rtnl_recv(GIOChannel *chan, gpointer user_data) struct inet_rtnl_cb_data *rtnl_data = user_data; struct __connman_inet_rtnl_handle *rth = rtnl_data->rtnl; struct nlmsghdr *h = NULL; + struct sockaddr_nl nladdr; + socklen_t addr_len = sizeof(nladdr); unsigned char buf[4096]; void *ptr = buf; gsize len; - int status; + int status, fd; memset(buf, 0, sizeof(buf)); + memset(&nladdr, 0, sizeof(nladdr)); - status = g_io_channel_read_chars(chan, (gchar *) buf, - sizeof(buf), &len, NULL); + fd = g_io_channel_unix_get_fd(chan); - DBG("status %d", status); + status = recvfrom(fd, buf, sizeof(buf), 0, + (struct sockaddr *) &nladdr, &addr_len); + if (status < 0) { + if (errno == EINTR || errno == EAGAIN) + return 0; - switch (status) { - case G_IO_STATUS_NORMAL: - break; - case G_IO_STATUS_AGAIN: - return 0; - default: return -1; } + if (status == 0) + return -1; + + if (nladdr.nl_pid != 0) { /* not sent by kernel, ignore */ + DBG("Received msg from %u, ignoring it", nladdr.nl_pid); + return 0; + } + + len = status; + while (len > 0) { struct nlmsgerr *err; |