blob: 65de0c3cbc10c42e5d48d421a483661f0b3ba86b [file] [log] [blame]
Lorenzo Colitti89faa342016-02-26 11:38:47 +09001/*
2 * Copyright 2016 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 * binder_test.cpp - unit tests for netd binder RPCs.
17 */
18
Robin Leeb8087362016-03-30 18:43:08 +010019#include <cerrno>
20#include <cinttypes>
Lorenzo Colitti89faa342016-02-26 11:38:47 +090021#include <cstdint>
Lorenzo Colittidedd2712016-03-22 12:36:29 +090022#include <cstdio>
23#include <cstdlib>
Lorenzo Colitti563d98b2016-04-24 13:13:14 +090024#include <set>
Lorenzo Colitti89faa342016-02-26 11:38:47 +090025#include <vector>
26
Lorenzo Colitti755faa92016-07-27 22:10:49 +090027#include <fcntl.h>
Erik Klinecc4f2732016-08-03 11:24:27 +090028#include <ifaddrs.h>
Lorenzo Colitti755faa92016-07-27 22:10:49 +090029#include <netdb.h>
Lorenzo Colitti563d98b2016-04-24 13:13:14 +090030#include <sys/socket.h>
Lorenzo Colitti755faa92016-07-27 22:10:49 +090031#include <sys/types.h>
Lorenzo Colitti563d98b2016-04-24 13:13:14 +090032#include <netinet/in.h>
Lorenzo Colitti755faa92016-07-27 22:10:49 +090033#include <linux/if.h>
34#include <linux/if_tun.h>
Lorenzo Colitti563d98b2016-04-24 13:13:14 +090035
Erik Klinecc4f2732016-08-03 11:24:27 +090036#include <android-base/macros.h>
Lorenzo Colitti89faa342016-02-26 11:38:47 +090037#include <android-base/stringprintf.h>
Lorenzo Colittidedd2712016-03-22 12:36:29 +090038#include <android-base/strings.h>
Robin Leeb8087362016-03-30 18:43:08 +010039#include <cutils/multiuser.h>
Lorenzo Colitti89faa342016-02-26 11:38:47 +090040#include <gtest/gtest.h>
41#include <logwrap/logwrap.h>
Lorenzo Colitti755faa92016-07-27 22:10:49 +090042#include <netutils/ifc.h>
Lorenzo Colitti89faa342016-02-26 11:38:47 +090043
44#include "NetdConstants.h"
Robin Lee7e05cc92016-09-21 16:31:33 +090045#include "Stopwatch.h"
Lorenzo Colitti1e299c62017-02-27 17:16:10 +090046#include "tun_interface.h"
Lorenzo Colitti89faa342016-02-26 11:38:47 +090047#include "android/net/INetd.h"
Robin Leeb8087362016-03-30 18:43:08 +010048#include "android/net/UidRange.h"
Lorenzo Colitti89faa342016-02-26 11:38:47 +090049#include "binder/IServiceManager.h"
50
Lorenzo Colitti755faa92016-07-27 22:10:49 +090051#define TUN_DEV "/dev/tun"
52
Lorenzo Colitti89faa342016-02-26 11:38:47 +090053using namespace android;
54using namespace android::base;
55using namespace android::binder;
56using android::net::INetd;
Lorenzo Colitti1e299c62017-02-27 17:16:10 +090057using android::net::TunInterface;
Robin Leeb8087362016-03-30 18:43:08 +010058using android::net::UidRange;
59
60static const char* IP_RULE_V4 = "-4";
61static const char* IP_RULE_V6 = "-6";
Lorenzo Colitti89faa342016-02-26 11:38:47 +090062
63class BinderTest : public ::testing::Test {
64
65public:
66 BinderTest() {
67 sp<IServiceManager> sm = defaultServiceManager();
68 sp<IBinder> binder = sm->getService(String16("netd"));
69 if (binder != nullptr) {
70 mNetd = interface_cast<INetd>(binder);
71 }
72 }
73
Lorenzo Colitti755faa92016-07-27 22:10:49 +090074 void SetUp() override {
Lorenzo Colitti89faa342016-02-26 11:38:47 +090075 ASSERT_NE(nullptr, mNetd.get());
76 }
77
Lorenzo Colitti755faa92016-07-27 22:10:49 +090078 // Static because setting up the tun interface takes about 40ms.
79 static void SetUpTestCase() {
Lorenzo Colitti1e299c62017-02-27 17:16:10 +090080 ASSERT_EQ(0, sTun.init());
81 ASSERT_LE(sTun.name().size(), static_cast<size_t>(IFNAMSIZ));
Lorenzo Colitti755faa92016-07-27 22:10:49 +090082 }
83
84 static void TearDownTestCase() {
85 // Closing the socket removes the interface and IP addresses.
Lorenzo Colitti1e299c62017-02-27 17:16:10 +090086 sTun.destroy();
Lorenzo Colitti755faa92016-07-27 22:10:49 +090087 }
88
89 static void fakeRemoteSocketPair(int *clientSocket, int *serverSocket, int *acceptedSocket);
Lorenzo Colitti755faa92016-07-27 22:10:49 +090090
Lorenzo Colitti89faa342016-02-26 11:38:47 +090091protected:
92 sp<INetd> mNetd;
Lorenzo Colitti1e299c62017-02-27 17:16:10 +090093 static TunInterface sTun;
Lorenzo Colitti89faa342016-02-26 11:38:47 +090094};
95
Lorenzo Colitti1e299c62017-02-27 17:16:10 +090096TunInterface BinderTest::sTun;
Lorenzo Colitti89faa342016-02-26 11:38:47 +090097
Lorenzo Colitti699aa992016-04-15 10:22:37 +090098class TimedOperation : public Stopwatch {
Lorenzo Colitti89faa342016-02-26 11:38:47 +090099public:
Chih-Hung Hsieh18051052016-05-06 10:36:13 -0700100 explicit TimedOperation(const std::string &name): mName(name) {}
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900101 virtual ~TimedOperation() {
Lorenzo Colitti699aa992016-04-15 10:22:37 +0900102 fprintf(stderr, " %s: %6.1f ms\n", mName.c_str(), timeTaken());
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900103 }
104
105private:
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900106 std::string mName;
107};
108
109TEST_F(BinderTest, TestIsAlive) {
110 TimedOperation t("isAlive RPC");
111 bool isAlive = false;
112 mNetd->isAlive(&isAlive);
113 ASSERT_TRUE(isAlive);
114}
115
116static int randomUid() {
117 return 100000 * arc4random_uniform(7) + 10000 + arc4random_uniform(5000);
118}
119
Robin Leeb8087362016-03-30 18:43:08 +0100120static std::vector<std::string> runCommand(const std::string& command) {
Lorenzo Colittidedd2712016-03-22 12:36:29 +0900121 std::vector<std::string> lines;
122 FILE *f;
123
Lorenzo Colittidedd2712016-03-22 12:36:29 +0900124 if ((f = popen(command.c_str(), "r")) == nullptr) {
125 perror("popen");
126 return lines;
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900127 }
Lorenzo Colittidedd2712016-03-22 12:36:29 +0900128
129 char *line = nullptr;
Robin Leeb8087362016-03-30 18:43:08 +0100130 size_t bufsize = 0;
131 ssize_t linelen = 0;
132 while ((linelen = getline(&line, &bufsize, f)) >= 0) {
Lorenzo Colittidedd2712016-03-22 12:36:29 +0900133 lines.push_back(std::string(line, linelen));
134 free(line);
135 line = nullptr;
136 }
137
138 pclose(f);
139 return lines;
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900140}
141
Robin Leeb8087362016-03-30 18:43:08 +0100142static std::vector<std::string> listIpRules(const char *ipVersion) {
143 std::string command = StringPrintf("%s %s rule list", IP_PATH, ipVersion);
144 return runCommand(command);
145}
146
147static std::vector<std::string> listIptablesRule(const char *binary, const char *chainName) {
Lorenzo Colitti80545772016-06-09 14:20:08 +0900148 std::string command = StringPrintf("%s -w -n -L %s", binary, chainName);
Robin Leeb8087362016-03-30 18:43:08 +0100149 return runCommand(command);
150}
151
Lorenzo Colittidedd2712016-03-22 12:36:29 +0900152static int iptablesRuleLineLength(const char *binary, const char *chainName) {
153 return listIptablesRule(binary, chainName).size();
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900154}
155
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900156TEST_F(BinderTest, TestFirewallReplaceUidChain) {
157 std::string chainName = StringPrintf("netd_binder_test_%u", arc4random_uniform(10000));
158 const int kNumUids = 500;
159 std::vector<int32_t> noUids(0);
160 std::vector<int32_t> uids(kNumUids);
161 for (int i = 0; i < kNumUids; i++) {
162 uids[i] = randomUid();
163 }
164
165 bool ret;
166 {
167 TimedOperation op(StringPrintf("Programming %d-UID whitelist chain", kNumUids));
168 mNetd->firewallReplaceUidChain(String16(chainName.c_str()), true, uids, &ret);
169 }
170 EXPECT_EQ(true, ret);
Lorenzo Colitti50b198a2017-03-30 02:50:09 +0900171 EXPECT_EQ((int) uids.size() + 7, iptablesRuleLineLength(IPTABLES_PATH, chainName.c_str()));
172 EXPECT_EQ((int) uids.size() + 13, iptablesRuleLineLength(IP6TABLES_PATH, chainName.c_str()));
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900173 {
174 TimedOperation op("Clearing whitelist chain");
175 mNetd->firewallReplaceUidChain(String16(chainName.c_str()), false, noUids, &ret);
176 }
177 EXPECT_EQ(true, ret);
Lorenzo Colitti50b198a2017-03-30 02:50:09 +0900178 EXPECT_EQ(5, iptablesRuleLineLength(IPTABLES_PATH, chainName.c_str()));
179 EXPECT_EQ(5, iptablesRuleLineLength(IP6TABLES_PATH, chainName.c_str()));
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900180
181 {
182 TimedOperation op(StringPrintf("Programming %d-UID blacklist chain", kNumUids));
183 mNetd->firewallReplaceUidChain(String16(chainName.c_str()), false, uids, &ret);
184 }
185 EXPECT_EQ(true, ret);
Lorenzo Colitti50b198a2017-03-30 02:50:09 +0900186 EXPECT_EQ((int) uids.size() + 5, iptablesRuleLineLength(IPTABLES_PATH, chainName.c_str()));
187 EXPECT_EQ((int) uids.size() + 5, iptablesRuleLineLength(IP6TABLES_PATH, chainName.c_str()));
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900188
189 {
190 TimedOperation op("Clearing blacklist chain");
191 mNetd->firewallReplaceUidChain(String16(chainName.c_str()), false, noUids, &ret);
192 }
193 EXPECT_EQ(true, ret);
Lorenzo Colitti50b198a2017-03-30 02:50:09 +0900194 EXPECT_EQ(5, iptablesRuleLineLength(IPTABLES_PATH, chainName.c_str()));
195 EXPECT_EQ(5, iptablesRuleLineLength(IP6TABLES_PATH, chainName.c_str()));
Lorenzo Colitti89faa342016-02-26 11:38:47 +0900196
197 // Check that the call fails if iptables returns an error.
198 std::string veryLongStringName = "netd_binder_test_UnacceptablyLongIptablesChainName";
199 mNetd->firewallReplaceUidChain(String16(veryLongStringName.c_str()), true, noUids, &ret);
200 EXPECT_EQ(false, ret);
201}
Lorenzo Colittidedd2712016-03-22 12:36:29 +0900202
203static int bandwidthDataSaverEnabled(const char *binary) {
Lorenzo Colitti464eabe2016-03-25 13:38:19 +0900204 std::vector<std::string> lines = listIptablesRule(binary, "bw_data_saver");
Lorenzo Colittidedd2712016-03-22 12:36:29 +0900205
206 // Output looks like this:
207 //
Lorenzo Colitti464eabe2016-03-25 13:38:19 +0900208 // Chain bw_data_saver (1 references)
Lorenzo Colittidedd2712016-03-22 12:36:29 +0900209 // target prot opt source destination
Lorenzo Colittidedd2712016-03-22 12:36:29 +0900210 // RETURN all -- 0.0.0.0/0 0.0.0.0/0
Lorenzo Colitti464eabe2016-03-25 13:38:19 +0900211 EXPECT_EQ(3U, lines.size());
212 if (lines.size() != 3) return -1;
Lorenzo Colittidedd2712016-03-22 12:36:29 +0900213
Lorenzo Colitti464eabe2016-03-25 13:38:19 +0900214 EXPECT_TRUE(android::base::StartsWith(lines[2], "RETURN ") ||
215 android::base::StartsWith(lines[2], "REJECT "));
Lorenzo Colittidedd2712016-03-22 12:36:29 +0900216
Lorenzo Colitti464eabe2016-03-25 13:38:19 +0900217 return android::base::StartsWith(lines[2], "REJECT");
Lorenzo Colittidedd2712016-03-22 12:36:29 +0900218}
219
220bool enableDataSaver(sp<INetd>& netd, bool enable) {
221 TimedOperation op(enable ? " Enabling data saver" : "Disabling data saver");
222 bool ret;
223 netd->bandwidthEnableDataSaver(enable, &ret);
224 return ret;
225}
226
227int getDataSaverState() {
228 const int enabled4 = bandwidthDataSaverEnabled(IPTABLES_PATH);
229 const int enabled6 = bandwidthDataSaverEnabled(IP6TABLES_PATH);
230 EXPECT_EQ(enabled4, enabled6);
231 EXPECT_NE(-1, enabled4);
232 EXPECT_NE(-1, enabled6);
233 if (enabled4 != enabled6 || (enabled6 != 0 && enabled6 != 1)) {
234 return -1;
235 }
236 return enabled6;
237}
238
239TEST_F(BinderTest, TestBandwidthEnableDataSaver) {
240 const int wasEnabled = getDataSaverState();
241 ASSERT_NE(-1, wasEnabled);
242
243 if (wasEnabled) {
244 ASSERT_TRUE(enableDataSaver(mNetd, false));
245 EXPECT_EQ(0, getDataSaverState());
246 }
247
248 ASSERT_TRUE(enableDataSaver(mNetd, false));
249 EXPECT_EQ(0, getDataSaverState());
250
251 ASSERT_TRUE(enableDataSaver(mNetd, true));
252 EXPECT_EQ(1, getDataSaverState());
253
254 ASSERT_TRUE(enableDataSaver(mNetd, true));
255 EXPECT_EQ(1, getDataSaverState());
256
257 if (!wasEnabled) {
258 ASSERT_TRUE(enableDataSaver(mNetd, false));
259 EXPECT_EQ(0, getDataSaverState());
260 }
261}
Robin Leeb8087362016-03-30 18:43:08 +0100262
263static bool ipRuleExistsForRange(const uint32_t priority, const UidRange& range,
264 const std::string& action, const char* ipVersion) {
265 // Output looks like this:
Robin Lee6c84ef62016-05-03 13:17:58 +0100266 // "12500:\tfrom all fwmark 0x0/0x20000 iif lo uidrange 1000-2000 prohibit"
Robin Leeb8087362016-03-30 18:43:08 +0100267 std::vector<std::string> rules = listIpRules(ipVersion);
268
269 std::string prefix = StringPrintf("%" PRIu32 ":", priority);
270 std::string suffix = StringPrintf(" iif lo uidrange %d-%d %s\n",
271 range.getStart(), range.getStop(), action.c_str());
272 for (std::string line : rules) {
273 if (android::base::StartsWith(line, prefix.c_str())
274 && android::base::EndsWith(line, suffix.c_str())) {
275 return true;
276 }
277 }
278 return false;
279}
280
281static bool ipRuleExistsForRange(const uint32_t priority, const UidRange& range,
282 const std::string& action) {
283 bool existsIp4 = ipRuleExistsForRange(priority, range, action, IP_RULE_V4);
284 bool existsIp6 = ipRuleExistsForRange(priority, range, action, IP_RULE_V6);
285 EXPECT_EQ(existsIp4, existsIp6);
286 return existsIp4;
287}
288
289TEST_F(BinderTest, TestNetworkRejectNonSecureVpn) {
Robin Lee6c84ef62016-05-03 13:17:58 +0100290 constexpr uint32_t RULE_PRIORITY = 12500;
Robin Leeb8087362016-03-30 18:43:08 +0100291
Jeff Sharkeyfe3cbd62016-12-13 13:26:47 -0700292 constexpr int baseUid = AID_USER_OFFSET * 5;
Robin Leeb8087362016-03-30 18:43:08 +0100293 std::vector<UidRange> uidRanges = {
294 {baseUid + 150, baseUid + 224},
295 {baseUid + 226, baseUid + 300}
296 };
297
298 const std::vector<std::string> initialRulesV4 = listIpRules(IP_RULE_V4);
299 const std::vector<std::string> initialRulesV6 = listIpRules(IP_RULE_V6);
300
301 // Create two valid rules.
302 ASSERT_TRUE(mNetd->networkRejectNonSecureVpn(true, uidRanges).isOk());
303 EXPECT_EQ(initialRulesV4.size() + 2, listIpRules(IP_RULE_V4).size());
304 EXPECT_EQ(initialRulesV6.size() + 2, listIpRules(IP_RULE_V6).size());
305 for (auto const& range : uidRanges) {
306 EXPECT_TRUE(ipRuleExistsForRange(RULE_PRIORITY, range, "prohibit"));
307 }
308
309 // Remove the rules.
310 ASSERT_TRUE(mNetd->networkRejectNonSecureVpn(false, uidRanges).isOk());
311 EXPECT_EQ(initialRulesV4.size(), listIpRules(IP_RULE_V4).size());
312 EXPECT_EQ(initialRulesV6.size(), listIpRules(IP_RULE_V6).size());
313 for (auto const& range : uidRanges) {
314 EXPECT_FALSE(ipRuleExistsForRange(RULE_PRIORITY, range, "prohibit"));
315 }
316
317 // Fail to remove the rules a second time after they are already deleted.
318 binder::Status status = mNetd->networkRejectNonSecureVpn(false, uidRanges);
319 ASSERT_EQ(binder::Status::EX_SERVICE_SPECIFIC, status.exceptionCode());
320 EXPECT_EQ(ENOENT, status.serviceSpecificErrorCode());
321
322 // All rules should be the same as before.
323 EXPECT_EQ(initialRulesV4, listIpRules(IP_RULE_V4));
324 EXPECT_EQ(initialRulesV6, listIpRules(IP_RULE_V6));
325}
Lorenzo Colitti563d98b2016-04-24 13:13:14 +0900326
Lorenzo Colitti755faa92016-07-27 22:10:49 +0900327// Create a socket pair that isLoopbackSocket won't think is local.
328void BinderTest::fakeRemoteSocketPair(int *clientSocket, int *serverSocket, int *acceptedSocket) {
Lorenzo Colitti563d98b2016-04-24 13:13:14 +0900329 *serverSocket = socket(AF_INET6, SOCK_STREAM, 0);
Lorenzo Colitti1e299c62017-02-27 17:16:10 +0900330 struct sockaddr_in6 server6 = { .sin6_family = AF_INET6, .sin6_addr = sTun.dstAddr() };
Lorenzo Colitti563d98b2016-04-24 13:13:14 +0900331 ASSERT_EQ(0, bind(*serverSocket, (struct sockaddr *) &server6, sizeof(server6)));
332
333 socklen_t addrlen = sizeof(server6);
334 ASSERT_EQ(0, getsockname(*serverSocket, (struct sockaddr *) &server6, &addrlen));
335 ASSERT_EQ(0, listen(*serverSocket, 10));
336
337 *clientSocket = socket(AF_INET6, SOCK_STREAM, 0);
Lorenzo Colitti1e299c62017-02-27 17:16:10 +0900338 struct sockaddr_in6 client6 = { .sin6_family = AF_INET6, .sin6_addr = sTun.srcAddr() };
Lorenzo Colitti755faa92016-07-27 22:10:49 +0900339 ASSERT_EQ(0, bind(*clientSocket, (struct sockaddr *) &client6, sizeof(client6)));
Lorenzo Colitti563d98b2016-04-24 13:13:14 +0900340 ASSERT_EQ(0, connect(*clientSocket, (struct sockaddr *) &server6, sizeof(server6)));
341 ASSERT_EQ(0, getsockname(*clientSocket, (struct sockaddr *) &client6, &addrlen));
342
343 *acceptedSocket = accept(*serverSocket, (struct sockaddr *) &server6, &addrlen);
344 ASSERT_NE(-1, *acceptedSocket);
345
346 ASSERT_EQ(0, memcmp(&client6, &server6, sizeof(client6)));
347}
348
349void checkSocketpairOpen(int clientSocket, int acceptedSocket) {
350 char buf[4096];
351 EXPECT_EQ(4, write(clientSocket, "foo", sizeof("foo")));
352 EXPECT_EQ(4, read(acceptedSocket, buf, sizeof(buf)));
353 EXPECT_EQ(0, memcmp(buf, "foo", sizeof("foo")));
354}
355
356void checkSocketpairClosed(int clientSocket, int acceptedSocket) {
357 // Check that the client socket was closed with ECONNABORTED.
358 int ret = write(clientSocket, "foo", sizeof("foo"));
359 int err = errno;
360 EXPECT_EQ(-1, ret);
361 EXPECT_EQ(ECONNABORTED, err);
362
363 // Check that it sent a RST to the server.
364 ret = write(acceptedSocket, "foo", sizeof("foo"));
365 err = errno;
366 EXPECT_EQ(-1, ret);
367 EXPECT_EQ(ECONNRESET, err);
368}
369
370TEST_F(BinderTest, TestSocketDestroy) {
371 int clientSocket, serverSocket, acceptedSocket;
Lorenzo Colitti755faa92016-07-27 22:10:49 +0900372 ASSERT_NO_FATAL_FAILURE(fakeRemoteSocketPair(&clientSocket, &serverSocket, &acceptedSocket));
Lorenzo Colitti563d98b2016-04-24 13:13:14 +0900373
374 // Pick a random UID in the system UID range.
375 constexpr int baseUid = AID_APP - 2000;
376 static_assert(baseUid > 0, "Not enough UIDs? Please fix this test.");
377 int uid = baseUid + 500 + arc4random_uniform(1000);
378 EXPECT_EQ(0, fchown(clientSocket, uid, -1));
379
380 // UID ranges that don't contain uid.
381 std::vector<UidRange> uidRanges = {
382 {baseUid + 42, baseUid + 449},
383 {baseUid + 1536, AID_APP - 4},
384 {baseUid + 498, uid - 1},
385 {uid + 1, baseUid + 1520},
386 };
387 // A skip list that doesn't contain UID.
388 std::vector<int32_t> skipUids { baseUid + 123, baseUid + 1600 };
389
390 // Close sockets. Our test socket should be intact.
391 EXPECT_TRUE(mNetd->socketDestroy(uidRanges, skipUids).isOk());
392 checkSocketpairOpen(clientSocket, acceptedSocket);
393
394 // UID ranges that do contain uid.
395 uidRanges = {
396 {baseUid + 42, baseUid + 449},
397 {baseUid + 1536, AID_APP - 4},
398 {baseUid + 498, baseUid + 1520},
399 };
400 // Add uid to the skip list.
401 skipUids.push_back(uid);
402
403 // Close sockets. Our test socket should still be intact because it's in the skip list.
404 EXPECT_TRUE(mNetd->socketDestroy(uidRanges, skipUids).isOk());
405 checkSocketpairOpen(clientSocket, acceptedSocket);
406
407 // Now remove uid from skipUids, and close sockets. Our test socket should have been closed.
408 skipUids.resize(skipUids.size() - 1);
409 EXPECT_TRUE(mNetd->socketDestroy(uidRanges, skipUids).isOk());
410 checkSocketpairClosed(clientSocket, acceptedSocket);
411
412 close(clientSocket);
413 close(serverSocket);
414 close(acceptedSocket);
415}
Erik Klinecc4f2732016-08-03 11:24:27 +0900416
417namespace {
418
419int netmaskToPrefixLength(const uint8_t *buf, size_t buflen) {
420 if (buf == nullptr) return -1;
421
422 int prefixLength = 0;
423 bool endOfContiguousBits = false;
424 for (unsigned int i = 0; i < buflen; i++) {
425 const uint8_t value = buf[i];
426
427 // Bad bit sequence: check for a contiguous set of bits from the high
428 // end by verifying that the inverted value + 1 is a power of 2
429 // (power of 2 iff. (v & (v - 1)) == 0).
430 const uint8_t inverse = ~value + 1;
431 if ((inverse & (inverse - 1)) != 0) return -1;
432
433 prefixLength += (value == 0) ? 0 : CHAR_BIT - ffs(value) + 1;
434
435 // Bogus netmask.
436 if (endOfContiguousBits && value != 0) return -1;
437
438 if (value != 0xff) endOfContiguousBits = true;
439 }
440
441 return prefixLength;
442}
443
444template<typename T>
445int netmaskToPrefixLength(const T *p) {
446 return netmaskToPrefixLength(reinterpret_cast<const uint8_t*>(p), sizeof(T));
447}
448
449
450static bool interfaceHasAddress(
451 const std::string &ifname, const char *addrString, int prefixLength) {
452 struct addrinfo *addrinfoList = nullptr;
453 ScopedAddrinfo addrinfoCleanup(addrinfoList);
454
455 const struct addrinfo hints = {
456 .ai_flags = AI_NUMERICHOST,
457 .ai_family = AF_UNSPEC,
458 .ai_socktype = SOCK_DGRAM,
459 };
460 if (getaddrinfo(addrString, nullptr, &hints, &addrinfoList) != 0 ||
461 addrinfoList == nullptr || addrinfoList->ai_addr == nullptr) {
462 return false;
463 }
464
465 struct ifaddrs *ifaddrsList = nullptr;
466 ScopedIfaddrs ifaddrsCleanup(ifaddrsList);
467
468 if (getifaddrs(&ifaddrsList) != 0) {
469 return false;
470 }
471
472 for (struct ifaddrs *addr = ifaddrsList; addr != nullptr; addr = addr->ifa_next) {
473 if (std::string(addr->ifa_name) != ifname ||
474 addr->ifa_addr == nullptr ||
475 addr->ifa_addr->sa_family != addrinfoList->ai_addr->sa_family) {
476 continue;
477 }
478
479 switch (addr->ifa_addr->sa_family) {
480 case AF_INET: {
481 auto *addr4 = reinterpret_cast<const struct sockaddr_in*>(addr->ifa_addr);
482 auto *want = reinterpret_cast<const struct sockaddr_in*>(addrinfoList->ai_addr);
483 if (memcmp(&addr4->sin_addr, &want->sin_addr, sizeof(want->sin_addr)) != 0) {
484 continue;
485 }
486
487 if (prefixLength < 0) return true; // not checking prefix lengths
488
489 if (addr->ifa_netmask == nullptr) return false;
490 auto *nm = reinterpret_cast<const struct sockaddr_in*>(addr->ifa_netmask);
491 EXPECT_EQ(prefixLength, netmaskToPrefixLength(&nm->sin_addr));
492 return (prefixLength == netmaskToPrefixLength(&nm->sin_addr));
493 }
494 case AF_INET6: {
495 auto *addr6 = reinterpret_cast<const struct sockaddr_in6*>(addr->ifa_addr);
496 auto *want = reinterpret_cast<const struct sockaddr_in6*>(addrinfoList->ai_addr);
497 if (memcmp(&addr6->sin6_addr, &want->sin6_addr, sizeof(want->sin6_addr)) != 0) {
498 continue;
499 }
500
501 if (prefixLength < 0) return true; // not checking prefix lengths
502
503 if (addr->ifa_netmask == nullptr) return false;
504 auto *nm = reinterpret_cast<const struct sockaddr_in6*>(addr->ifa_netmask);
505 EXPECT_EQ(prefixLength, netmaskToPrefixLength(&nm->sin6_addr));
506 return (prefixLength == netmaskToPrefixLength(&nm->sin6_addr));
507 }
508 default:
509 // Cannot happen because we have already screened for matching
510 // address families at the top of each iteration.
511 continue;
512 }
513 }
514
515 return false;
516}
517
518} // namespace
519
520TEST_F(BinderTest, TestInterfaceAddRemoveAddress) {
521 static const struct TestData {
522 const char *addrString;
523 const int prefixLength;
524 const bool expectSuccess;
525 } kTestData[] = {
526 { "192.0.2.1", 24, true },
527 { "192.0.2.2", 25, true },
528 { "192.0.2.3", 32, true },
529 { "192.0.2.4", 33, false },
530 { "192.not.an.ip", 24, false },
531 { "2001:db8::1", 64, true },
532 { "2001:db8::2", 65, true },
533 { "2001:db8::3", 128, true },
534 { "2001:db8::4", 129, false },
535 { "foo:bar::bad", 64, false },
536 };
537
538 for (unsigned int i = 0; i < arraysize(kTestData); i++) {
539 const auto &td = kTestData[i];
540
541 // [1.a] Add the address.
542 binder::Status status = mNetd->interfaceAddAddress(
Lorenzo Colitti1e299c62017-02-27 17:16:10 +0900543 sTun.name(), td.addrString, td.prefixLength);
Erik Klinecc4f2732016-08-03 11:24:27 +0900544 if (td.expectSuccess) {
545 EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
546 } else {
547 ASSERT_EQ(binder::Status::EX_SERVICE_SPECIFIC, status.exceptionCode());
548 ASSERT_NE(0, status.serviceSpecificErrorCode());
549 }
550
551 // [1.b] Verify the addition meets the expectation.
552 if (td.expectSuccess) {
Lorenzo Colitti1e299c62017-02-27 17:16:10 +0900553 EXPECT_TRUE(interfaceHasAddress(sTun.name(), td.addrString, td.prefixLength));
Erik Klinecc4f2732016-08-03 11:24:27 +0900554 } else {
Lorenzo Colitti1e299c62017-02-27 17:16:10 +0900555 EXPECT_FALSE(interfaceHasAddress(sTun.name(), td.addrString, -1));
Erik Klinecc4f2732016-08-03 11:24:27 +0900556 }
557
558 // [2.a] Try to remove the address. If it was not previously added, removing it fails.
Lorenzo Colitti1e299c62017-02-27 17:16:10 +0900559 status = mNetd->interfaceDelAddress(sTun.name(), td.addrString, td.prefixLength);
Erik Klinecc4f2732016-08-03 11:24:27 +0900560 if (td.expectSuccess) {
561 EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
562 } else {
563 ASSERT_EQ(binder::Status::EX_SERVICE_SPECIFIC, status.exceptionCode());
564 ASSERT_NE(0, status.serviceSpecificErrorCode());
565 }
566
567 // [2.b] No matter what, the address should not be present.
Lorenzo Colitti1e299c62017-02-27 17:16:10 +0900568 EXPECT_FALSE(interfaceHasAddress(sTun.name(), td.addrString, -1));
Erik Klinecc4f2732016-08-03 11:24:27 +0900569 }
570}
Erik Kline55b06f82016-07-04 09:57:18 +0900571
572TEST_F(BinderTest, TestSetProcSysNet) {
573 static const struct TestData {
574 const int family;
575 const int which;
576 const char *ifname;
577 const char *parameter;
578 const char *value;
579 const int expectedReturnCode;
580 } kTestData[] = {
Lorenzo Colitti1e299c62017-02-27 17:16:10 +0900581 { INetd::IPV4, INetd::CONF, sTun.name().c_str(), "arp_ignore", "1", 0 },
582 { -1, INetd::CONF, sTun.name().c_str(), "arp_ignore", "1", EAFNOSUPPORT },
583 { INetd::IPV4, -1, sTun.name().c_str(), "arp_ignore", "1", EINVAL },
Erik Kline55b06f82016-07-04 09:57:18 +0900584 { INetd::IPV4, INetd::CONF, "..", "conf/lo/arp_ignore", "1", EINVAL },
585 { INetd::IPV4, INetd::CONF, ".", "lo/arp_ignore", "1", EINVAL },
Lorenzo Colitti1e299c62017-02-27 17:16:10 +0900586 { INetd::IPV4, INetd::CONF, sTun.name().c_str(), "../all/arp_ignore", "1", EINVAL },
587 { INetd::IPV6, INetd::NEIGH, sTun.name().c_str(), "ucast_solicit", "7", 0 },
Erik Kline55b06f82016-07-04 09:57:18 +0900588 };
589
590 for (unsigned int i = 0; i < arraysize(kTestData); i++) {
591 const auto &td = kTestData[i];
592
593 const binder::Status status = mNetd->setProcSysNet(
594 td.family, td.which, td.ifname, td.parameter,
595 td.value);
596
597 if (td.expectedReturnCode == 0) {
598 SCOPED_TRACE(String8::format("test case %d should have passed", i));
599 EXPECT_EQ(0, status.exceptionCode());
600 EXPECT_EQ(0, status.serviceSpecificErrorCode());
601 } else {
602 SCOPED_TRACE(String8::format("test case %d should have failed", i));
603 EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, status.exceptionCode());
604 EXPECT_EQ(td.expectedReturnCode, status.serviceSpecificErrorCode());
605 }
606 }
607}