• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
19 #include <cerrno>
20 #include <cinttypes>
21 #include <cstdint>
22 #include <cstdio>
23 #include <cstdlib>
24 #include <set>
25 #include <vector>
26 
27 #include <fcntl.h>
28 #include <ifaddrs.h>
29 #include <netdb.h>
30 #include <sys/socket.h>
31 #include <sys/types.h>
32 #include <netinet/in.h>
33 #include <linux/if.h>
34 #include <linux/if_tun.h>
35 
36 #include <android-base/macros.h>
37 #include <android-base/stringprintf.h>
38 #include <android-base/strings.h>
39 #include <cutils/multiuser.h>
40 #include <gtest/gtest.h>
41 #include <logwrap/logwrap.h>
42 #include <netutils/ifc.h>
43 
44 #include "NetdConstants.h"
45 #include "Stopwatch.h"
46 #include "tun_interface.h"
47 #include "android/net/INetd.h"
48 #include "android/net/UidRange.h"
49 #include "binder/IServiceManager.h"
50 
51 #define TUN_DEV "/dev/tun"
52 
53 using namespace android;
54 using namespace android::base;
55 using namespace android::binder;
56 using android::net::INetd;
57 using android::net::TunInterface;
58 using android::net::UidRange;
59 
60 static const char* IP_RULE_V4 = "-4";
61 static const char* IP_RULE_V6 = "-6";
62 
63 class BinderTest : public ::testing::Test {
64 
65 public:
BinderTest()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 
SetUp()74     void SetUp() override {
75         ASSERT_NE(nullptr, mNetd.get());
76     }
77 
78     // Static because setting up the tun interface takes about 40ms.
SetUpTestCase()79     static void SetUpTestCase() {
80         ASSERT_EQ(0, sTun.init());
81         ASSERT_LE(sTun.name().size(), static_cast<size_t>(IFNAMSIZ));
82     }
83 
TearDownTestCase()84     static void TearDownTestCase() {
85         // Closing the socket removes the interface and IP addresses.
86         sTun.destroy();
87     }
88 
89     static void fakeRemoteSocketPair(int *clientSocket, int *serverSocket, int *acceptedSocket);
90 
91 protected:
92     sp<INetd> mNetd;
93     static TunInterface sTun;
94 };
95 
96 TunInterface BinderTest::sTun;
97 
98 class TimedOperation : public Stopwatch {
99 public:
TimedOperation(const std::string & name)100     explicit TimedOperation(const std::string &name): mName(name) {}
~TimedOperation()101     virtual ~TimedOperation() {
102         fprintf(stderr, "    %s: %6.1f ms\n", mName.c_str(), timeTaken());
103     }
104 
105 private:
106     std::string mName;
107 };
108 
TEST_F(BinderTest,TestIsAlive)109 TEST_F(BinderTest, TestIsAlive) {
110     TimedOperation t("isAlive RPC");
111     bool isAlive = false;
112     mNetd->isAlive(&isAlive);
113     ASSERT_TRUE(isAlive);
114 }
115 
randomUid()116 static int randomUid() {
117     return 100000 * arc4random_uniform(7) + 10000 + arc4random_uniform(5000);
118 }
119 
runCommand(const std::string & command)120 static std::vector<std::string> runCommand(const std::string& command) {
121     std::vector<std::string> lines;
122     FILE *f;
123 
124     if ((f = popen(command.c_str(), "r")) == nullptr) {
125         perror("popen");
126         return lines;
127     }
128 
129     char *line = nullptr;
130     size_t bufsize = 0;
131     ssize_t linelen = 0;
132     while ((linelen = getline(&line, &bufsize, f)) >= 0) {
133         lines.push_back(std::string(line, linelen));
134         free(line);
135         line = nullptr;
136     }
137 
138     pclose(f);
139     return lines;
140 }
141 
listIpRules(const char * ipVersion)142 static 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 
listIptablesRule(const char * binary,const char * chainName)147 static std::vector<std::string> listIptablesRule(const char *binary, const char *chainName) {
148     std::string command = StringPrintf("%s -w -n -L %s", binary, chainName);
149     return runCommand(command);
150 }
151 
iptablesRuleLineLength(const char * binary,const char * chainName)152 static int iptablesRuleLineLength(const char *binary, const char *chainName) {
153     return listIptablesRule(binary, chainName).size();
154 }
155 
TEST_F(BinderTest,TestFirewallReplaceUidChain)156 TEST_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);
171     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()));
173     {
174         TimedOperation op("Clearing whitelist chain");
175         mNetd->firewallReplaceUidChain(String16(chainName.c_str()), false, noUids, &ret);
176     }
177     EXPECT_EQ(true, ret);
178     EXPECT_EQ(5, iptablesRuleLineLength(IPTABLES_PATH, chainName.c_str()));
179     EXPECT_EQ(5, iptablesRuleLineLength(IP6TABLES_PATH, chainName.c_str()));
180 
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);
186     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()));
188 
189     {
190         TimedOperation op("Clearing blacklist chain");
191         mNetd->firewallReplaceUidChain(String16(chainName.c_str()), false, noUids, &ret);
192     }
193     EXPECT_EQ(true, ret);
194     EXPECT_EQ(5, iptablesRuleLineLength(IPTABLES_PATH, chainName.c_str()));
195     EXPECT_EQ(5, iptablesRuleLineLength(IP6TABLES_PATH, chainName.c_str()));
196 
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 }
202 
bandwidthDataSaverEnabled(const char * binary)203 static int bandwidthDataSaverEnabled(const char *binary) {
204     std::vector<std::string> lines = listIptablesRule(binary, "bw_data_saver");
205 
206     // Output looks like this:
207     //
208     // Chain bw_data_saver (1 references)
209     // target     prot opt source               destination
210     // RETURN     all  --  0.0.0.0/0            0.0.0.0/0
211     EXPECT_EQ(3U, lines.size());
212     if (lines.size() != 3) return -1;
213 
214     EXPECT_TRUE(android::base::StartsWith(lines[2], "RETURN ") ||
215                 android::base::StartsWith(lines[2], "REJECT "));
216 
217     return android::base::StartsWith(lines[2], "REJECT");
218 }
219 
enableDataSaver(sp<INetd> & netd,bool enable)220 bool 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 
getDataSaverState()227 int 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 
TEST_F(BinderTest,TestBandwidthEnableDataSaver)239 TEST_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 }
262 
ipRuleExistsForRange(const uint32_t priority,const UidRange & range,const std::string & action,const char * ipVersion)263 static bool ipRuleExistsForRange(const uint32_t priority, const UidRange& range,
264         const std::string& action, const char* ipVersion) {
265     // Output looks like this:
266     //   "12500:\tfrom all fwmark 0x0/0x20000 iif lo uidrange 1000-2000 prohibit"
267     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 
ipRuleExistsForRange(const uint32_t priority,const UidRange & range,const std::string & action)281 static 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 
TEST_F(BinderTest,TestNetworkRejectNonSecureVpn)289 TEST_F(BinderTest, TestNetworkRejectNonSecureVpn) {
290     constexpr uint32_t RULE_PRIORITY = 12500;
291 
292     constexpr int baseUid = AID_USER_OFFSET * 5;
293     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 }
326 
327 // Create a socket pair that isLoopbackSocket won't think is local.
fakeRemoteSocketPair(int * clientSocket,int * serverSocket,int * acceptedSocket)328 void BinderTest::fakeRemoteSocketPair(int *clientSocket, int *serverSocket, int *acceptedSocket) {
329     *serverSocket = socket(AF_INET6, SOCK_STREAM, 0);
330     struct sockaddr_in6 server6 = { .sin6_family = AF_INET6, .sin6_addr = sTun.dstAddr() };
331     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);
338     struct sockaddr_in6 client6 = { .sin6_family = AF_INET6, .sin6_addr = sTun.srcAddr() };
339     ASSERT_EQ(0, bind(*clientSocket, (struct sockaddr *) &client6, sizeof(client6)));
340     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 
checkSocketpairOpen(int clientSocket,int acceptedSocket)349 void 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 
checkSocketpairClosed(int clientSocket,int acceptedSocket)356 void 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 
TEST_F(BinderTest,TestSocketDestroy)370 TEST_F(BinderTest, TestSocketDestroy) {
371     int clientSocket, serverSocket, acceptedSocket;
372     ASSERT_NO_FATAL_FAILURE(fakeRemoteSocketPair(&clientSocket, &serverSocket, &acceptedSocket));
373 
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 }
416 
417 namespace {
418 
netmaskToPrefixLength(const uint8_t * buf,size_t buflen)419 int 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 
444 template<typename T>
netmaskToPrefixLength(const T * p)445 int netmaskToPrefixLength(const T *p) {
446     return netmaskToPrefixLength(reinterpret_cast<const uint8_t*>(p), sizeof(T));
447 }
448 
449 
interfaceHasAddress(const std::string & ifname,const char * addrString,int prefixLength)450 static 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 
TEST_F(BinderTest,TestInterfaceAddRemoveAddress)520 TEST_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(
543                 sTun.name(), td.addrString, td.prefixLength);
544         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) {
553             EXPECT_TRUE(interfaceHasAddress(sTun.name(), td.addrString, td.prefixLength));
554         } else {
555             EXPECT_FALSE(interfaceHasAddress(sTun.name(), td.addrString, -1));
556         }
557 
558         // [2.a] Try to remove the address.  If it was not previously added, removing it fails.
559         status = mNetd->interfaceDelAddress(sTun.name(), td.addrString, td.prefixLength);
560         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.
568         EXPECT_FALSE(interfaceHasAddress(sTun.name(), td.addrString, -1));
569     }
570 }
571 
TEST_F(BinderTest,TestSetProcSysNet)572 TEST_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[] = {
581         { 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 },
584         { INetd::IPV4, INetd::CONF, "..", "conf/lo/arp_ignore", "1", EINVAL },
585         { INetd::IPV4, INetd::CONF, ".", "lo/arp_ignore", "1", EINVAL },
586         { 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 },
588     };
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 }
608