summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libsysutils/src/NetlinkListener.cpp29
1 files changed, 26 insertions, 3 deletions
diff --git a/libsysutils/src/NetlinkListener.cpp b/libsysutils/src/NetlinkListener.cpp
index e2a354e4f..fb088e1c3 100644
--- a/libsysutils/src/NetlinkListener.cpp
+++ b/libsysutils/src/NetlinkListener.cpp
@@ -17,6 +17,7 @@
17 17
18#include <sys/types.h> 18#include <sys/types.h>
19#include <sys/socket.h> 19#include <sys/socket.h>
20#include <linux/netlink.h>
20#include <string.h> 21#include <string.h>
21 22
22#define LOG_TAG "NetlinkListener" 23#define LOG_TAG "NetlinkListener"
@@ -32,10 +33,32 @@ NetlinkListener::NetlinkListener(int socket) :
32bool NetlinkListener::onDataAvailable(SocketClient *cli) 33bool NetlinkListener::onDataAvailable(SocketClient *cli)
33{ 34{
34 int socket = cli->getSocket(); 35 int socket = cli->getSocket();
35 int count; 36 ssize_t count;
37 char cred_msg[CMSG_SPACE(sizeof(struct ucred))];
38 struct sockaddr_nl snl;
39 struct iovec iov = {mBuffer, sizeof(mBuffer)};
40 struct msghdr hdr = {&snl, sizeof(snl), &iov, 1, cred_msg, sizeof(cred_msg), 0};
36 41
37 if ((count = recv(socket, mBuffer, sizeof(mBuffer), 0)) < 0) { 42 if ((count = recvmsg(socket, &hdr, 0)) < 0) {
38 SLOGE("recv failed (%s)", strerror(errno)); 43 SLOGE("recvmsg failed (%s)", strerror(errno));
44 return false;
45 }
46
47 if ((snl.nl_groups != 1) || (snl.nl_pid != 0)) {
48 SLOGE("ignoring non-kernel netlink multicast message");
49 return false;
50 }
51
52 struct cmsghdr * cmsg = CMSG_FIRSTHDR(&hdr);
53
54 if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) {
55 SLOGE("ignoring message with no sender credentials");
56 return false;
57 }
58
59 struct ucred * cred = (struct ucred *)CMSG_DATA(cmsg);
60 if (cred->uid != 0) {
61 SLOGE("ignoring message from non-root UID %d", cred->uid);
39 return false; 62 return false;
40 } 63 }
41 64