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 | |
| parent | b0ec6eb4466acc57a9ea8be52c17b674b6ea0618 (diff) | |
| download | connman-c1b968984212b46bea1330f5ae029507b9bfded9.tar.gz | |
inet: Make sure that we only accept netlink messages from kernel
| -rw-r--r-- | src/inet.c | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/src/inet.c b/src/inet.c index a0f69713a..e01bfb384 100644 --- a/src/inet.c +++ b/src/inet.c @@ -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; |
