Skip to content
Snippets Groups Projects
Commit b620a0b1 authored by Nick Kralevich's avatar Nick Kralevich
Browse files

Validate sender credentials on netlink msg receive

Verify that netlink messages are actually from the kernel,
and not from a userspace program.

Change-Id: I709c0efe9ba0258f6d79ebcde531d7f7bbe780b2
parent 336bc321
No related branches found
No related tags found
No related merge requests found
......@@ -17,6 +17,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/netlink.h>
#include <string.h>
#define LOG_TAG "NetlinkListener"
......@@ -32,10 +33,32 @@ NetlinkListener::NetlinkListener(int socket) :
bool NetlinkListener::onDataAvailable(SocketClient *cli)
{
int socket = cli->getSocket();
int count;
ssize_t count;
char cred_msg[CMSG_SPACE(sizeof(struct ucred))];
struct sockaddr_nl snl;
struct iovec iov = {mBuffer, sizeof(mBuffer)};
struct msghdr hdr = {&snl, sizeof(snl), &iov, 1, cred_msg, sizeof(cred_msg), 0};
if ((count = recv(socket, mBuffer, sizeof(mBuffer), 0)) < 0) {
SLOGE("recv failed (%s)", strerror(errno));
if ((count = recvmsg(socket, &hdr, 0)) < 0) {
SLOGE("recvmsg failed (%s)", strerror(errno));
return false;
}
if ((snl.nl_groups != 1) || (snl.nl_pid != 0)) {
SLOGE("ignoring non-kernel netlink multicast message");
return false;
}
struct cmsghdr * cmsg = CMSG_FIRSTHDR(&hdr);
if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) {
SLOGE("ignoring message with no sender credentials");
return false;
}
struct ucred * cred = (struct ucred *)CMSG_DATA(cmsg);
if (cred->uid != 0) {
SLOGE("ignoring message from non-root UID %d", cred->uid);
return false;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment