1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "netlink.h"
18 
19 #include "log.h"
20 #include "netlinkmessage.h"
21 
22 #include <errno.h>
23 #include <poll.h>
24 #include <string.h>
25 #include <linux/netlink.h>
26 #include <sys/socket.h>
27 #include <sys/types.h>
28 #include <unistd.h>
29 
30 static const size_t kControlRead = 0;
31 static const size_t kControlWrite = 1;
32 
closeIfOpen(int * fd)33 static void closeIfOpen(int* fd) {
34     if (*fd != -1) {
35         ::close(*fd);
36         *fd = -1;
37     }
38 }
39 
Netlink()40 Netlink::Netlink()
41     : mNextSequenceNumber(1)
42     , mSocket(-1) {
43     mControlPipe[kControlRead] = -1;
44     mControlPipe[kControlWrite] = -1;
45 }
46 
~Netlink()47 Netlink::~Netlink() {
48     closeIfOpen(&mSocket);
49     closeIfOpen(&mControlPipe[kControlRead]);
50     closeIfOpen(&mControlPipe[kControlWrite]);
51 }
52 
init()53 bool Netlink::init() {
54     if (mSocket != -1) {
55         ALOGE("Netlink already initialized");
56         return false;
57     }
58 
59     int status = ::pipe2(mControlPipe, O_CLOEXEC);
60     if (status != 0) {
61         ALOGE("Failed to create control pipe: %s", strerror(errno));
62         return false;
63     }
64 
65     mSocket = ::socket(AF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_ROUTE);
66     if (mSocket == -1) {
67         ALOGE("Failed to create netlink socket: %s", strerror(errno));
68         return false;
69     }
70 
71     struct sockaddr_nl addr;
72     memset(&addr, 0, sizeof(addr));
73     addr.nl_family = AF_NETLINK;
74     status = ::bind(mSocket,
75                     reinterpret_cast<struct sockaddr*>(&addr),
76                     sizeof(addr));
77     if (status != 0) {
78         ALOGE("Failed to bind netlink socket: %s", strerror(errno));
79         return false;
80     }
81 
82     return true;
83 }
84 
stop(StopHandler handler)85 void Netlink::stop(StopHandler handler) {
86     char stop = 1;
87     // Set the handler before writing so that it's guaranteed to be available
88     // when the event loop reads from the control pipe.
89     {
90         // No need to keep the lock while writing so make it scoped
91         std::unique_lock<std::mutex> lock(mStopHandlerMutex);
92         mStopHandler = handler;
93     }
94     ::write(mControlPipe[kControlWrite], &stop, sizeof(stop));
95 }
96 
eventLoop()97 bool Netlink::eventLoop() {
98     struct pollfd fds[2];
99     memset(fds, 0, sizeof(fds));
100     fds[0].fd = mSocket;
101     fds[0].events = POLLIN;
102     fds[1].fd = mControlPipe[kControlRead];
103     fds[1].events = POLLIN;
104 
105     for (;;) {
106         int status = ::poll(fds, 2, -1);
107         if (status == 0) {
108             // Timeout, not really supposed to happen
109             ALOGW("poll encountered a timeout despite infinite timeout");
110             continue;
111         } else if (status < 0) {
112             if (errno == EINTR) {
113                 continue;
114             }
115             ALOGE("poll encountered an error: %s", strerror(errno));
116             return false;
117         }
118         for (auto& fd : fds) {
119             if ((fd.revents & POLLIN) == 0) {
120                 continue;
121             }
122             if (fd.fd == mSocket) {
123                 readNetlinkMessage(fd.fd);
124             } else if (fd.fd == mControlPipe[kControlRead]) {
125                 if (readControlMessage()) {
126                     // Make a copy of the stop handler while holding the lock
127                     // and then call it after releasing the lock. This prevents
128                     // the potential deadlock of someone calling stop from the
129                     // stop callback. The drawback of this is that if someone
130                     // calls stop again with a new stop handler that new stop
131                     // handler might not be called if the timing is wrong.
132                     // Both of these scenarios indicate highly questionable
133                     // behavior on the callers part but at least this way the
134                     // event loop will terminate which seems better than a
135                     // total deadlock.
136                     StopHandler handler;
137                     {
138                         std::unique_lock<std::mutex> lock(mStopHandlerMutex);
139                         handler = mStopHandler;
140                     }
141                     if (handler) {
142                         handler();
143                     }
144                     return true;
145                 }
146             }
147         }
148     }
149 }
150 
getSequenceNumber()151 uint32_t Netlink::getSequenceNumber() {
152     return mNextSequenceNumber++;
153 }
154 
sendMessage(const NetlinkMessage & message,ReplyHandler handler)155 bool Netlink::sendMessage(const NetlinkMessage& message,
156                           ReplyHandler handler) {
157     // Keep lock the entire time so that we can safely erase the handler
158     // without worrying about another call to sendAsync adding a handler that
159     // shouldn't be deleted.
160     std::unique_lock<std::mutex> lock(mHandlersMutex);
161     // Register handler before sending in case the read thread picks up the
162     // response between the send thread sending and registering the handler.
163     mHandlers[message.sequence()] = handler;
164     for (;;) {
165         int bytesSent = ::send(mSocket, message.data(), message.size(), 0);
166         if (bytesSent > 0 && static_cast<size_t>(bytesSent) == message.size()) {
167             return true;
168         }
169         if (bytesSent < 0 && errno == EINTR) {
170             // We need to try again, keep the mutex locked
171             continue;
172         }
173         // It's a failure, remove the handler and unlock the mutex
174         mHandlers.erase(message.sequence());
175         lock.unlock();
176 
177         if (bytesSent < 0) {
178             ALOGE("Failed to send netlink message: %s", strerror(errno));
179         }
180         return false;
181     }
182 }
183 
readNetlinkMessage(int fd)184 bool Netlink::readNetlinkMessage(int fd) {
185     char buffer[8 * 1024];
186     for (;;) {
187         int bytesReceived = ::recv(fd, buffer, sizeof(buffer), 0);
188         if (bytesReceived < 0) {
189             if (errno == EINTR) {
190                 continue;
191             }
192             ALOGE("recv failed to receive on netlink socket: %s",
193                   strerror(errno));
194             return false;
195         }
196         char* data = buffer;
197         char* end = data + bytesReceived;
198         while (data < end) {
199             if (data + sizeof(nlmsghdr) > end) {
200                 ALOGE("received invalid netlink message, too small for header");
201                 return false;
202             }
203             auto header = reinterpret_cast<nlmsghdr*>(data);
204             if (data + header->nlmsg_len > end) {
205                 ALOGE("received invalid netlink message, too small for data");
206                 return false;
207             }
208 
209             if (header->nlmsg_type == NLMSG_ERROR) {
210                 if (data + NLMSG_HDRLEN + sizeof(nlmsgerr) <= end) {
211                     auto err = reinterpret_cast<nlmsgerr*>(NLMSG_DATA(header));
212                     ALOGE("Receive netlink error message: %s, sequence %u",
213                           strerror(-err->error), header->nlmsg_seq);
214                 } else {
215                     ALOGE("Received netlink error code but no error message");
216                 }
217                 return false;
218             }
219 
220             notifyHandler(data, header->nlmsg_len);
221 
222             data += header->nlmsg_len;
223         }
224         return true;
225     }
226 }
227 
readControlMessage()228 bool Netlink::readControlMessage() {
229     char buffer[32];
230 
231     for (;;) {
232         int bytesReceived = ::recv(mControlPipe[kControlRead],
233                                    buffer,
234                                    sizeof(buffer),
235                                    0);
236         if (bytesReceived < 0) {
237             if (errno == EINTR) {
238                 continue;
239             }
240         } else if (bytesReceived == 0) {
241             return false;
242         }
243         return true;
244     }
245 }
246 
247 
notifyHandler(const char * data,size_t size)248 void Netlink::notifyHandler(const char* data, size_t size) {
249     NetlinkMessage message(data, size);
250 
251     ReplyHandler replyHandler;
252     {
253         std::unique_lock<std::mutex> lock(mHandlersMutex);
254         auto handler = mHandlers.find(message.sequence());
255         if (handler == mHandlers.end()) {
256             // No handler found, ignore message
257             return;
258         }
259         replyHandler = handler->second;
260         mHandlers.erase(handler);
261     }
262 
263     replyHandler(message);
264 }
265 
266