diff options
author | Jukka Rissanen <jukka.rissanen@linux.intel.com> | 2012-05-03 15:27:22 +0300 |
---|---|---|
committer | Patrik Flykt <patrik.flykt@linux.intel.com> | 2012-05-04 12:14:34 +0300 |
commit | b0ec6eb4466acc57a9ea8be52c17b674b6ea0618 (patch) | |
tree | dcb995946cd0fead301ea739a553f5570b3669d9 /src/rtnl.c | |
parent | c863ccb24e75656d90b533f1505f9f8000d9e006 (diff) | |
download | connman-b0ec6eb4466acc57a9ea8be52c17b674b6ea0618.tar.gz connman-b0ec6eb4466acc57a9ea8be52c17b674b6ea0618.tar.bz2 connman-b0ec6eb4466acc57a9ea8be52c17b674b6ea0618.zip |
rtnl: Make sure that we only accept netlink messages from kernel
Diffstat (limited to 'src/rtnl.c')
-rw-r--r-- | src/rtnl.c | 37 |
1 files changed, 24 insertions, 13 deletions
@@ -1368,10 +1368,11 @@ static void rtnl_message(void *buf, size_t len) if (!NLMSG_OK(hdr, len)) break; - DBG("%s len %d type %d flags 0x%04x seq %d", + DBG("%s len %d type %d flags 0x%04x seq %d pid %d", type2string(hdr->nlmsg_type), hdr->nlmsg_len, hdr->nlmsg_type, - hdr->nlmsg_flags, hdr->nlmsg_seq); + hdr->nlmsg_flags, hdr->nlmsg_seq, + hdr->nlmsg_pid); switch (hdr->nlmsg_type) { case NLMSG_NOOP: @@ -1417,27 +1418,37 @@ static gboolean netlink_event(GIOChannel *chan, GIOCondition cond, gpointer data) { unsigned char buf[4096]; - gsize len; - GIOStatus status; + struct sockaddr_nl nladdr; + socklen_t addr_len = sizeof(nladdr); + ssize_t status; + int fd; if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) return FALSE; 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); + + status = recvfrom(fd, buf, sizeof(buf), 0, + (struct sockaddr *) &nladdr, &addr_len); + if (status < 0) { + if (errno == EINTR || errno == EAGAIN) + return TRUE; - switch (status) { - case G_IO_STATUS_NORMAL: - break; - case G_IO_STATUS_AGAIN: - return TRUE; - default: return FALSE; } - rtnl_message(buf, len); + if (status == 0) + return FALSE; + + if (nladdr.nl_pid != 0) { /* not sent by kernel, ignore */ + DBG("Received msg from %u, ignoring it", nladdr.nl_pid); + return TRUE; + } + + rtnl_message(buf, status); return TRUE; } |