summaryrefslogtreecommitdiff
path: root/src/inet.c
diff options
context:
space:
mode:
authorJukka Rissanen <jukka.rissanen@linux.intel.com>2012-05-03 15:27:23 +0300
committerPatrik Flykt <patrik.flykt@linux.intel.com>2012-05-04 12:14:45 +0300
commitc1b968984212b46bea1330f5ae029507b9bfded9 (patch)
treee03481723bbbb0df2db06702c7255c13b3820023 /src/inet.c
parentb0ec6eb4466acc57a9ea8be52c17b674b6ea0618 (diff)
downloadconnman-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/inet.c')
-rw-r--r--src/inet.c30
1 files changed, 20 insertions, 10 deletions
diff --git a/src/inet.c b/src/inet.c
index a0f69713..e01bfb38 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;