summaryrefslogtreecommitdiff
path: root/src/rtnl.c
diff options
context:
space:
mode:
authorJukka Rissanen <jukka.rissanen@linux.intel.com>2012-05-03 15:27:22 +0300
committerPatrik Flykt <patrik.flykt@linux.intel.com>2012-05-04 12:14:34 +0300
commitb0ec6eb4466acc57a9ea8be52c17b674b6ea0618 (patch)
treedcb995946cd0fead301ea739a553f5570b3669d9 /src/rtnl.c
parentc863ccb24e75656d90b533f1505f9f8000d9e006 (diff)
downloadconnman-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.c37
1 files changed, 24 insertions, 13 deletions
diff --git a/src/rtnl.c b/src/rtnl.c
index 3cd6c4b6..e53f5e88 100644
--- a/src/rtnl.c
+++ b/src/rtnl.c
@@ -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;
}