blob: 6cb094034a9700e1f21cdd5162d547dc01799a2d [file] [log] [blame]
Wayne Ma4d692332022-01-19 16:04:04 +08001/*
Wayne Ma7be6bce2022-01-12 16:29:49 +08002 * Copyright 2022 The Android Open Source Project
Wayne Ma4d692332022-01-19 16:04:04 +08003 *
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 * TrafficControllerTest.cpp - unit tests for TrafficController.cpp
17 */
18
19#include <cstdint>
20#include <string>
21#include <vector>
22
23#include <fcntl.h>
24#include <inttypes.h>
25#include <linux/inet_diag.h>
26#include <linux/sock_diag.h>
27#include <sys/socket.h>
28#include <sys/types.h>
29#include <unistd.h>
30
31#include <gtest/gtest.h>
32
Ken Chen2fb86362022-06-05 11:39:38 +080033#include <android-base/file.h>
Ken Chen0dd74952022-06-06 18:25:18 +080034#include <android-base/logging.h>
Wayne Ma4d692332022-01-19 16:04:04 +080035#include <android-base/stringprintf.h>
36#include <android-base/strings.h>
Wayne Ma7be6bce2022-01-12 16:29:49 +080037#include <binder/Status.h>
Wayne Ma4d692332022-01-19 16:04:04 +080038
39#include <netdutils/MockSyscalls.h>
40
Maciej Żenczykowski01319d92022-06-13 18:25:34 -070041#define BPF_MAP_MAKE_VISIBLE_FOR_TESTING
Wayne Ma4d692332022-01-19 16:04:04 +080042#include "TrafficController.h"
43#include "bpf/BpfUtils.h"
Patrick Rohr61e94672022-02-01 21:06:40 +010044#include "NetdUpdatablePublic.h"
Wayne Ma4d692332022-01-19 16:04:04 +080045
46using namespace android::bpf; // NOLINT(google-build-using-namespace): grandfathered
47
48namespace android {
49namespace net {
50
Wayne Ma7be6bce2022-01-12 16:29:49 +080051using android::netdutils::Status;
Wayne Ma4d692332022-01-19 16:04:04 +080052using base::Result;
53using netdutils::isOk;
Ken Chen2fb86362022-06-05 11:39:38 +080054using netdutils::statusFromErrno;
Wayne Ma4d692332022-01-19 16:04:04 +080055
56constexpr int TEST_MAP_SIZE = 10;
Wayne Ma4d692332022-01-19 16:04:04 +080057constexpr uid_t TEST_UID = 10086;
58constexpr uid_t TEST_UID2 = 54321;
59constexpr uid_t TEST_UID3 = 98765;
60constexpr uint32_t TEST_TAG = 42;
61constexpr uint32_t TEST_COUNTERSET = 1;
Ken Chen0dd74952022-06-06 18:25:18 +080062constexpr int TEST_COOKIE = 1;
Ken Chen0dd74952022-06-06 18:25:18 +080063constexpr int TEST_IFINDEX = 999;
64constexpr int RXPACKETS = 1;
65constexpr int RXBYTES = 100;
66constexpr int TXPACKETS = 0;
67constexpr int TXBYTES = 0;
Wayne Ma4d692332022-01-19 16:04:04 +080068
69#define ASSERT_VALID(x) ASSERT_TRUE((x).isValid())
Hungming Chen410bb122022-06-09 01:32:00 +080070#define ASSERT_INVALID(x) ASSERT_FALSE((x).isValid())
Wayne Ma4d692332022-01-19 16:04:04 +080071
72class TrafficControllerTest : public ::testing::Test {
73 protected:
Wayne Ma92d80792022-01-20 13:20:34 +080074 TrafficControllerTest() {}
Wayne Ma4d692332022-01-19 16:04:04 +080075 TrafficController mTc;
76 BpfMap<uint64_t, UidTagValue> mFakeCookieTagMap;
Wayne Ma4d692332022-01-19 16:04:04 +080077 BpfMap<uint32_t, StatsValue> mFakeAppUidStatsMap;
78 BpfMap<StatsKey, StatsValue> mFakeStatsMapA;
Hungming Chen410bb122022-06-09 01:32:00 +080079 BpfMap<StatsKey, StatsValue> mFakeStatsMapB; // makeTrafficControllerMapsInvalid only
80 BpfMap<uint32_t, StatsValue> mFakeIfaceStatsMap; ; // makeTrafficControllerMapsInvalid only
Lorenzo Colitti60cbed32022-03-03 17:49:01 +090081 BpfMap<uint32_t, uint32_t> mFakeConfigurationMap;
Wayne Ma4d692332022-01-19 16:04:04 +080082 BpfMap<uint32_t, UidOwnerValue> mFakeUidOwnerMap;
83 BpfMap<uint32_t, uint8_t> mFakeUidPermissionMap;
Ken Chen0dd74952022-06-06 18:25:18 +080084 BpfMap<uint32_t, uint8_t> mFakeUidCounterSetMap;
85 BpfMap<uint32_t, IfaceValue> mFakeIfaceIndexNameMap;
Wayne Ma4d692332022-01-19 16:04:04 +080086
87 void SetUp() {
88 std::lock_guard guard(mTc.mMutex);
89 ASSERT_EQ(0, setrlimitForTest());
90
Maciej Żenczykowski439bac22022-05-31 03:22:32 -070091 mFakeCookieTagMap.resetMap(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE);
Wayne Ma4d692332022-01-19 16:04:04 +080092 ASSERT_VALID(mFakeCookieTagMap);
93
Maciej Żenczykowski439bac22022-05-31 03:22:32 -070094 mFakeAppUidStatsMap.resetMap(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE);
Wayne Ma4d692332022-01-19 16:04:04 +080095 ASSERT_VALID(mFakeAppUidStatsMap);
96
Maciej Żenczykowski439bac22022-05-31 03:22:32 -070097 mFakeStatsMapA.resetMap(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE);
Wayne Ma4d692332022-01-19 16:04:04 +080098 ASSERT_VALID(mFakeStatsMapA);
99
Maciej Żenczykowskib10e0552022-06-16 14:49:27 -0700100 mFakeConfigurationMap.resetMap(BPF_MAP_TYPE_ARRAY, CONFIGURATION_MAP_SIZE);
Wayne Ma4d692332022-01-19 16:04:04 +0800101 ASSERT_VALID(mFakeConfigurationMap);
102
Maciej Żenczykowski439bac22022-05-31 03:22:32 -0700103 mFakeUidOwnerMap.resetMap(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE);
Wayne Ma4d692332022-01-19 16:04:04 +0800104 ASSERT_VALID(mFakeUidOwnerMap);
Maciej Żenczykowski439bac22022-05-31 03:22:32 -0700105 mFakeUidPermissionMap.resetMap(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE);
Wayne Ma4d692332022-01-19 16:04:04 +0800106 ASSERT_VALID(mFakeUidPermissionMap);
107
Ken Chen0dd74952022-06-06 18:25:18 +0800108 mFakeUidCounterSetMap.resetMap(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE);
109 ASSERT_VALID(mFakeUidCounterSetMap);
110
111 mFakeIfaceIndexNameMap.resetMap(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE);
112 ASSERT_VALID(mFakeIfaceIndexNameMap);
113
Maciej Żenczykowski55ab87a2022-05-31 03:15:12 -0700114 mTc.mCookieTagMap = mFakeCookieTagMap;
Wayne Ma4d692332022-01-19 16:04:04 +0800115 ASSERT_VALID(mTc.mCookieTagMap);
Maciej Żenczykowski55ab87a2022-05-31 03:15:12 -0700116 mTc.mAppUidStatsMap = mFakeAppUidStatsMap;
Wayne Ma4d692332022-01-19 16:04:04 +0800117 ASSERT_VALID(mTc.mAppUidStatsMap);
Maciej Żenczykowski55ab87a2022-05-31 03:15:12 -0700118 mTc.mStatsMapA = mFakeStatsMapA;
Wayne Ma4d692332022-01-19 16:04:04 +0800119 ASSERT_VALID(mTc.mStatsMapA);
Maciej Żenczykowski55ab87a2022-05-31 03:15:12 -0700120 mTc.mConfigurationMap = mFakeConfigurationMap;
Wayne Ma4d692332022-01-19 16:04:04 +0800121 ASSERT_VALID(mTc.mConfigurationMap);
122
123 // Always write to stats map A by default.
Maciej Żenczykowskib10e0552022-06-16 14:49:27 -0700124 static_assert(SELECT_MAP_A == 0);
125
Maciej Żenczykowski55ab87a2022-05-31 03:15:12 -0700126 mTc.mUidOwnerMap = mFakeUidOwnerMap;
Wayne Ma4d692332022-01-19 16:04:04 +0800127 ASSERT_VALID(mTc.mUidOwnerMap);
Maciej Żenczykowski55ab87a2022-05-31 03:15:12 -0700128 mTc.mUidPermissionMap = mFakeUidPermissionMap;
Wayne Ma4d692332022-01-19 16:04:04 +0800129 ASSERT_VALID(mTc.mUidPermissionMap);
130 mTc.mPrivilegedUser.clear();
Ken Chen0dd74952022-06-06 18:25:18 +0800131
132 mTc.mUidCounterSetMap = mFakeUidCounterSetMap;
133 ASSERT_VALID(mTc.mUidCounterSetMap);
134
135 mTc.mIfaceIndexNameMap = mFakeIfaceIndexNameMap;
136 ASSERT_VALID(mTc.mIfaceIndexNameMap);
Wayne Ma4d692332022-01-19 16:04:04 +0800137 }
138
Wayne Ma4d692332022-01-19 16:04:04 +0800139 void populateFakeStats(uint64_t cookie, uint32_t uid, uint32_t tag, StatsKey* key) {
140 UidTagValue cookieMapkey = {.uid = (uint32_t)uid, .tag = tag};
141 EXPECT_RESULT_OK(mFakeCookieTagMap.writeValue(cookie, cookieMapkey, BPF_ANY));
Ken Chen0dd74952022-06-06 18:25:18 +0800142 *key = {.uid = uid, .tag = tag, .counterSet = TEST_COUNTERSET, .ifaceIndex = TEST_IFINDEX};
143 StatsValue statsMapValue = {.rxPackets = RXPACKETS, .rxBytes = RXBYTES,
144 .txPackets = TXPACKETS, .txBytes = TXBYTES};
Wayne Ma4d692332022-01-19 16:04:04 +0800145 EXPECT_RESULT_OK(mFakeStatsMapA.writeValue(*key, statsMapValue, BPF_ANY));
146 EXPECT_RESULT_OK(mFakeAppUidStatsMap.writeValue(uid, statsMapValue, BPF_ANY));
147 // put tag information back to statsKey
148 key->tag = tag;
149 }
150
Ken Chen0dd74952022-06-06 18:25:18 +0800151 void populateFakeCounterSet(uint32_t uid, uint32_t counterSet) {
152 EXPECT_RESULT_OK(mFakeUidCounterSetMap.writeValue(uid, counterSet, BPF_ANY));
153 }
154
155 void populateFakeIfaceIndexName(const char* name, uint32_t ifaceIndex) {
156 if (name == nullptr || ifaceIndex <= 0) return;
157
158 IfaceValue iface;
159 strlcpy(iface.name, name, sizeof(IfaceValue));
160 EXPECT_RESULT_OK(mFakeIfaceIndexNameMap.writeValue(ifaceIndex, iface, BPF_ANY));
161 }
162
Wayne Ma4d692332022-01-19 16:04:04 +0800163 void checkUidOwnerRuleForChain(ChildChain chain, UidOwnerMatchType match) {
164 uint32_t uid = TEST_UID;
165 EXPECT_EQ(0, mTc.changeUidOwnerRule(chain, uid, DENY, DENYLIST));
166 Result<UidOwnerValue> value = mFakeUidOwnerMap.readValue(uid);
167 EXPECT_RESULT_OK(value);
168 EXPECT_TRUE(value.value().rule & match);
169
170 uid = TEST_UID2;
171 EXPECT_EQ(0, mTc.changeUidOwnerRule(chain, uid, ALLOW, ALLOWLIST));
172 value = mFakeUidOwnerMap.readValue(uid);
173 EXPECT_RESULT_OK(value);
174 EXPECT_TRUE(value.value().rule & match);
175
176 EXPECT_EQ(0, mTc.changeUidOwnerRule(chain, uid, DENY, ALLOWLIST));
177 value = mFakeUidOwnerMap.readValue(uid);
178 EXPECT_FALSE(value.ok());
179 EXPECT_EQ(ENOENT, value.error().code());
180
181 uid = TEST_UID;
182 EXPECT_EQ(0, mTc.changeUidOwnerRule(chain, uid, ALLOW, DENYLIST));
183 value = mFakeUidOwnerMap.readValue(uid);
184 EXPECT_FALSE(value.ok());
185 EXPECT_EQ(ENOENT, value.error().code());
186
187 uid = TEST_UID3;
188 EXPECT_EQ(-ENOENT, mTc.changeUidOwnerRule(chain, uid, ALLOW, DENYLIST));
189 value = mFakeUidOwnerMap.readValue(uid);
190 EXPECT_FALSE(value.ok());
191 EXPECT_EQ(ENOENT, value.error().code());
192 }
193
194 void checkEachUidValue(const std::vector<int32_t>& uids, UidOwnerMatchType match) {
195 for (uint32_t uid : uids) {
196 Result<UidOwnerValue> value = mFakeUidOwnerMap.readValue(uid);
197 EXPECT_RESULT_OK(value);
198 EXPECT_TRUE(value.value().rule & match);
199 }
200 std::set<uint32_t> uidSet(uids.begin(), uids.end());
201 const auto checkNoOtherUid = [&uidSet](const int32_t& key,
202 const BpfMap<uint32_t, UidOwnerValue>&) {
203 EXPECT_NE(uidSet.end(), uidSet.find(key));
204 return Result<void>();
205 };
206 EXPECT_RESULT_OK(mFakeUidOwnerMap.iterate(checkNoOtherUid));
207 }
208
209 void checkUidMapReplace(const std::string& name, const std::vector<int32_t>& uids,
210 UidOwnerMatchType match) {
211 bool isAllowlist = true;
212 EXPECT_EQ(0, mTc.replaceUidOwnerMap(name, isAllowlist, uids));
213 checkEachUidValue(uids, match);
214
215 isAllowlist = false;
216 EXPECT_EQ(0, mTc.replaceUidOwnerMap(name, isAllowlist, uids));
217 checkEachUidValue(uids, match);
218 }
219
Motomu Utsumi8b42e6d2022-05-19 06:23:40 +0000220 void expectUidOwnerMapValues(const std::vector<uint32_t>& appUids, uint32_t expectedRule,
Wayne Ma4d692332022-01-19 16:04:04 +0800221 uint32_t expectedIif) {
222 for (uint32_t uid : appUids) {
223 Result<UidOwnerValue> value = mFakeUidOwnerMap.readValue(uid);
224 EXPECT_RESULT_OK(value);
225 EXPECT_EQ(expectedRule, value.value().rule)
226 << "Expected rule for UID " << uid << " to be " << expectedRule << ", but was "
227 << value.value().rule;
228 EXPECT_EQ(expectedIif, value.value().iif)
229 << "Expected iif for UID " << uid << " to be " << expectedIif << ", but was "
230 << value.value().iif;
231 }
232 }
233
234 template <class Key, class Value>
235 void expectMapEmpty(BpfMap<Key, Value>& map) {
236 auto isEmpty = map.isEmpty();
237 EXPECT_RESULT_OK(isEmpty);
238 EXPECT_TRUE(isEmpty.value());
239 }
240
241 void expectUidPermissionMapValues(const std::vector<uid_t>& appUids, uint8_t expectedValue) {
242 for (uid_t uid : appUids) {
243 Result<uint8_t> value = mFakeUidPermissionMap.readValue(uid);
244 EXPECT_RESULT_OK(value);
245 EXPECT_EQ(expectedValue, value.value())
246 << "Expected value for UID " << uid << " to be " << expectedValue
247 << ", but was " << value.value();
248 }
249 }
250
251 void expectPrivilegedUserSet(const std::vector<uid_t>& appUids) {
252 std::lock_guard guard(mTc.mMutex);
253 EXPECT_EQ(appUids.size(), mTc.mPrivilegedUser.size());
254 for (uid_t uid : appUids) {
255 EXPECT_NE(mTc.mPrivilegedUser.end(), mTc.mPrivilegedUser.find(uid));
256 }
257 }
258
259 void expectPrivilegedUserSetEmpty() {
260 std::lock_guard guard(mTc.mMutex);
261 EXPECT_TRUE(mTc.mPrivilegedUser.empty());
262 }
263
Wayne Ma7be6bce2022-01-12 16:29:49 +0800264 Status updateUidOwnerMaps(const std::vector<uint32_t>& appUids,
265 UidOwnerMatchType matchType, TrafficController::IptOp op) {
266 Status ret(0);
267 for (auto uid : appUids) {
268 ret = mTc.updateUidOwnerMap(uid, matchType, op);
269 if(!isOk(ret)) break;
270 }
271 return ret;
272 }
273
Ken Chen2fb86362022-06-05 11:39:38 +0800274 Status dump(bool verbose, std::vector<std::string>& outputLines) {
275 if (!outputLines.empty()) return statusFromErrno(EUCLEAN, "Output buffer is not empty");
276
277 android::base::unique_fd localFd, remoteFd;
278 if (!Pipe(&localFd, &remoteFd)) return statusFromErrno(errno, "Failed on pipe");
279
280 // dump() blocks until another thread has consumed all its output.
281 std::thread dumpThread =
282 std::thread([this, remoteFd{std::move(remoteFd)}, verbose]() {
283 mTc.dump(remoteFd, verbose);
284 });
285
286 std::string dumpContent;
287 if (!android::base::ReadFdToString(localFd.get(), &dumpContent)) {
288 return statusFromErrno(errno, "Failed to read dump results from fd");
289 }
290 dumpThread.join();
291
292 std::stringstream dumpStream(std::move(dumpContent));
293 std::string line;
294 while (std::getline(dumpStream, line)) {
295 outputLines.push_back(line);
296 }
297
298 return netdutils::status::ok;
299 }
300
301 // Strings in the |expect| must exist in dump results in order. But no need to be consecutive.
302 bool expectDumpsysContains(std::vector<std::string>& expect) {
303 if (expect.empty()) return false;
304
305 std::vector<std::string> output;
306 Status result = dump(true, output);
307 if (!isOk(result)) {
308 GTEST_LOG_(ERROR) << "TrafficController dump failed: " << netdutils::toString(result);
309 return false;
310 }
311
312 int matched = 0;
313 auto it = expect.begin();
314 for (const auto& line : output) {
315 if (it == expect.end()) break;
316 if (std::string::npos != line.find(*it)) {
317 matched++;
318 ++it;
319 }
320 }
Ken Chen0dd74952022-06-06 18:25:18 +0800321
322 if (matched != expect.size()) {
323 // dump results for debugging
324 for (const auto& o : output) LOG(INFO) << "output: " << o;
325 for (const auto& e : expect) LOG(INFO) << "expect: " << e;
326 return false;
327 }
328 return true;
Ken Chen2fb86362022-06-05 11:39:38 +0800329 }
Hungming Chen410bb122022-06-09 01:32:00 +0800330
331 // Once called, the maps of TrafficController can't recover to valid maps which initialized
332 // in SetUp().
333 void makeTrafficControllerMapsInvalid() {
334 constexpr char INVALID_PATH[] = "invalid";
335
336 mFakeCookieTagMap.init(INVALID_PATH);
337 mTc.mCookieTagMap = mFakeCookieTagMap;
338 ASSERT_INVALID(mTc.mCookieTagMap);
339
340 mFakeAppUidStatsMap.init(INVALID_PATH);
341 mTc.mAppUidStatsMap = mFakeAppUidStatsMap;
342 ASSERT_INVALID(mTc.mAppUidStatsMap);
343
344 mFakeStatsMapA.init(INVALID_PATH);
345 mTc.mStatsMapA = mFakeStatsMapA;
346 ASSERT_INVALID(mTc.mStatsMapA);
347
348 mFakeStatsMapB.init(INVALID_PATH);
349 mTc.mStatsMapB = mFakeStatsMapB;
350 ASSERT_INVALID(mTc.mStatsMapB);
351
352 mFakeIfaceStatsMap.init(INVALID_PATH);
353 mTc.mIfaceStatsMap = mFakeIfaceStatsMap;
354 ASSERT_INVALID(mTc.mIfaceStatsMap);
355
356 mFakeConfigurationMap.init(INVALID_PATH);
357 mTc.mConfigurationMap = mFakeConfigurationMap;
358 ASSERT_INVALID(mTc.mConfigurationMap);
359
360 mFakeUidOwnerMap.init(INVALID_PATH);
361 mTc.mUidOwnerMap = mFakeUidOwnerMap;
362 ASSERT_INVALID(mTc.mUidOwnerMap);
363
364 mFakeUidPermissionMap.init(INVALID_PATH);
365 mTc.mUidPermissionMap = mFakeUidPermissionMap;
366 ASSERT_INVALID(mTc.mUidPermissionMap);
367
368 mFakeUidCounterSetMap.init(INVALID_PATH);
369 mTc.mUidCounterSetMap = mFakeUidCounterSetMap;
370 ASSERT_INVALID(mTc.mUidCounterSetMap);
371
372 mFakeIfaceIndexNameMap.init(INVALID_PATH);
373 mTc.mIfaceIndexNameMap = mFakeIfaceIndexNameMap;
374 ASSERT_INVALID(mTc.mIfaceIndexNameMap);
375 }
Wayne Ma4d692332022-01-19 16:04:04 +0800376};
377
Wayne Ma4d692332022-01-19 16:04:04 +0800378TEST_F(TrafficControllerTest, TestUpdateOwnerMapEntry) {
379 uint32_t uid = TEST_UID;
380 ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(STANDBY_MATCH, uid, DENY, DENYLIST)));
381 Result<UidOwnerValue> value = mFakeUidOwnerMap.readValue(uid);
382 ASSERT_RESULT_OK(value);
383 ASSERT_TRUE(value.value().rule & STANDBY_MATCH);
384
385 ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(DOZABLE_MATCH, uid, ALLOW, ALLOWLIST)));
386 value = mFakeUidOwnerMap.readValue(uid);
387 ASSERT_RESULT_OK(value);
388 ASSERT_TRUE(value.value().rule & DOZABLE_MATCH);
389
390 ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(DOZABLE_MATCH, uid, DENY, ALLOWLIST)));
391 value = mFakeUidOwnerMap.readValue(uid);
392 ASSERT_RESULT_OK(value);
393 ASSERT_FALSE(value.value().rule & DOZABLE_MATCH);
394
395 ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(STANDBY_MATCH, uid, ALLOW, DENYLIST)));
396 ASSERT_FALSE(mFakeUidOwnerMap.readValue(uid).ok());
397
398 uid = TEST_UID2;
399 ASSERT_FALSE(isOk(mTc.updateOwnerMapEntry(STANDBY_MATCH, uid, ALLOW, DENYLIST)));
400 ASSERT_FALSE(mFakeUidOwnerMap.readValue(uid).ok());
401}
402
403TEST_F(TrafficControllerTest, TestChangeUidOwnerRule) {
404 checkUidOwnerRuleForChain(DOZABLE, DOZABLE_MATCH);
405 checkUidOwnerRuleForChain(STANDBY, STANDBY_MATCH);
406 checkUidOwnerRuleForChain(POWERSAVE, POWERSAVE_MATCH);
407 checkUidOwnerRuleForChain(RESTRICTED, RESTRICTED_MATCH);
Robert Horvathd945bf02022-01-27 19:55:16 +0100408 checkUidOwnerRuleForChain(LOW_POWER_STANDBY, LOW_POWER_STANDBY_MATCH);
Motomu Utsumid9801492022-06-01 13:57:27 +0000409 checkUidOwnerRuleForChain(OEM_DENY_1, OEM_DENY_1_MATCH);
410 checkUidOwnerRuleForChain(OEM_DENY_2, OEM_DENY_2_MATCH);
Motomu Utsumi1d9054b2022-06-06 07:44:05 +0000411 checkUidOwnerRuleForChain(OEM_DENY_3, OEM_DENY_3_MATCH);
Wayne Ma4d692332022-01-19 16:04:04 +0800412 ASSERT_EQ(-EINVAL, mTc.changeUidOwnerRule(NONE, TEST_UID, ALLOW, ALLOWLIST));
413 ASSERT_EQ(-EINVAL, mTc.changeUidOwnerRule(INVALID_CHAIN, TEST_UID, ALLOW, ALLOWLIST));
414}
415
416TEST_F(TrafficControllerTest, TestReplaceUidOwnerMap) {
417 std::vector<int32_t> uids = {TEST_UID, TEST_UID2, TEST_UID3};
418 checkUidMapReplace("fw_dozable", uids, DOZABLE_MATCH);
419 checkUidMapReplace("fw_standby", uids, STANDBY_MATCH);
420 checkUidMapReplace("fw_powersave", uids, POWERSAVE_MATCH);
421 checkUidMapReplace("fw_restricted", uids, RESTRICTED_MATCH);
Robert Horvathd945bf02022-01-27 19:55:16 +0100422 checkUidMapReplace("fw_low_power_standby", uids, LOW_POWER_STANDBY_MATCH);
Motomu Utsumid9801492022-06-01 13:57:27 +0000423 checkUidMapReplace("fw_oem_deny_1", uids, OEM_DENY_1_MATCH);
424 checkUidMapReplace("fw_oem_deny_2", uids, OEM_DENY_2_MATCH);
Motomu Utsumi1d9054b2022-06-06 07:44:05 +0000425 checkUidMapReplace("fw_oem_deny_3", uids, OEM_DENY_3_MATCH);
Wayne Ma4d692332022-01-19 16:04:04 +0800426 ASSERT_EQ(-EINVAL, mTc.replaceUidOwnerMap("unknow", true, uids));
427}
428
429TEST_F(TrafficControllerTest, TestReplaceSameChain) {
430 std::vector<int32_t> uids = {TEST_UID, TEST_UID2, TEST_UID3};
431 checkUidMapReplace("fw_dozable", uids, DOZABLE_MATCH);
432 std::vector<int32_t> newUids = {TEST_UID2, TEST_UID3};
433 checkUidMapReplace("fw_dozable", newUids, DOZABLE_MATCH);
434}
435
436TEST_F(TrafficControllerTest, TestDenylistUidMatch) {
437 std::vector<uint32_t> appUids = {1000, 1001, 10012};
Wayne Ma7be6bce2022-01-12 16:29:49 +0800438 ASSERT_TRUE(isOk(updateUidOwnerMaps(appUids, PENALTY_BOX_MATCH,
439 TrafficController::IptOpInsert)));
Wayne Ma4d692332022-01-19 16:04:04 +0800440 expectUidOwnerMapValues(appUids, PENALTY_BOX_MATCH, 0);
Wayne Ma7be6bce2022-01-12 16:29:49 +0800441 ASSERT_TRUE(isOk(updateUidOwnerMaps(appUids, PENALTY_BOX_MATCH,
442 TrafficController::IptOpDelete)));
Wayne Ma4d692332022-01-19 16:04:04 +0800443 expectMapEmpty(mFakeUidOwnerMap);
444}
445
446TEST_F(TrafficControllerTest, TestAllowlistUidMatch) {
447 std::vector<uint32_t> appUids = {1000, 1001, 10012};
Wayne Ma7be6bce2022-01-12 16:29:49 +0800448 ASSERT_TRUE(isOk(updateUidOwnerMaps(appUids, HAPPY_BOX_MATCH, TrafficController::IptOpInsert)));
Wayne Ma4d692332022-01-19 16:04:04 +0800449 expectUidOwnerMapValues(appUids, HAPPY_BOX_MATCH, 0);
Wayne Ma7be6bce2022-01-12 16:29:49 +0800450 ASSERT_TRUE(isOk(updateUidOwnerMaps(appUids, HAPPY_BOX_MATCH, TrafficController::IptOpDelete)));
Wayne Ma4d692332022-01-19 16:04:04 +0800451 expectMapEmpty(mFakeUidOwnerMap);
452}
453
454TEST_F(TrafficControllerTest, TestReplaceMatchUid) {
455 std::vector<uint32_t> appUids = {1000, 1001, 10012};
456 // Add appUids to the denylist and expect that their values are all PENALTY_BOX_MATCH.
Wayne Ma7be6bce2022-01-12 16:29:49 +0800457 ASSERT_TRUE(isOk(updateUidOwnerMaps(appUids, PENALTY_BOX_MATCH,
458 TrafficController::IptOpInsert)));
Wayne Ma4d692332022-01-19 16:04:04 +0800459 expectUidOwnerMapValues(appUids, PENALTY_BOX_MATCH, 0);
460
461 // Add the same UIDs to the allowlist and expect that we get PENALTY_BOX_MATCH |
462 // HAPPY_BOX_MATCH.
Wayne Ma7be6bce2022-01-12 16:29:49 +0800463 ASSERT_TRUE(isOk(updateUidOwnerMaps(appUids, HAPPY_BOX_MATCH, TrafficController::IptOpInsert)));
Wayne Ma4d692332022-01-19 16:04:04 +0800464 expectUidOwnerMapValues(appUids, HAPPY_BOX_MATCH | PENALTY_BOX_MATCH, 0);
465
466 // Remove the same UIDs from the allowlist and check the PENALTY_BOX_MATCH is still there.
Wayne Ma7be6bce2022-01-12 16:29:49 +0800467 ASSERT_TRUE(isOk(updateUidOwnerMaps(appUids, HAPPY_BOX_MATCH, TrafficController::IptOpDelete)));
Wayne Ma4d692332022-01-19 16:04:04 +0800468 expectUidOwnerMapValues(appUids, PENALTY_BOX_MATCH, 0);
469
470 // Remove the same UIDs from the denylist and check the map is empty.
Wayne Ma7be6bce2022-01-12 16:29:49 +0800471 ASSERT_TRUE(isOk(updateUidOwnerMaps(appUids, PENALTY_BOX_MATCH,
472 TrafficController::IptOpDelete)));
Wayne Ma4d692332022-01-19 16:04:04 +0800473 ASSERT_FALSE(mFakeUidOwnerMap.getFirstKey().ok());
474}
475
476TEST_F(TrafficControllerTest, TestDeleteWrongMatchSilentlyFails) {
477 std::vector<uint32_t> appUids = {1000, 1001, 10012};
478 // If the uid does not exist in the map, trying to delete a rule about it will fail.
Wayne Ma7be6bce2022-01-12 16:29:49 +0800479 ASSERT_FALSE(isOk(updateUidOwnerMaps(appUids, HAPPY_BOX_MATCH,
480 TrafficController::IptOpDelete)));
Wayne Ma4d692332022-01-19 16:04:04 +0800481 expectMapEmpty(mFakeUidOwnerMap);
482
483 // Add denylist rules for appUids.
Wayne Ma7be6bce2022-01-12 16:29:49 +0800484 ASSERT_TRUE(isOk(updateUidOwnerMaps(appUids, HAPPY_BOX_MATCH,
485 TrafficController::IptOpInsert)));
Wayne Ma4d692332022-01-19 16:04:04 +0800486 expectUidOwnerMapValues(appUids, HAPPY_BOX_MATCH, 0);
487
488 // Delete (non-existent) denylist rules for appUids, and check that this silently does
489 // nothing if the uid is in the map but does not have denylist match. This is required because
490 // NetworkManagementService will try to remove a uid from denylist after adding it to the
491 // allowlist and if the remove fails it will not update the uid status.
Wayne Ma7be6bce2022-01-12 16:29:49 +0800492 ASSERT_TRUE(isOk(updateUidOwnerMaps(appUids, PENALTY_BOX_MATCH,
493 TrafficController::IptOpDelete)));
Wayne Ma4d692332022-01-19 16:04:04 +0800494 expectUidOwnerMapValues(appUids, HAPPY_BOX_MATCH, 0);
495}
496
497TEST_F(TrafficControllerTest, TestAddUidInterfaceFilteringRules) {
498 int iif0 = 15;
499 ASSERT_TRUE(isOk(mTc.addUidInterfaceRules(iif0, {1000, 1001})));
500 expectUidOwnerMapValues({1000, 1001}, IIF_MATCH, iif0);
501
502 // Add some non-overlapping new uids. They should coexist with existing rules
503 int iif1 = 16;
504 ASSERT_TRUE(isOk(mTc.addUidInterfaceRules(iif1, {2000, 2001})));
505 expectUidOwnerMapValues({1000, 1001}, IIF_MATCH, iif0);
506 expectUidOwnerMapValues({2000, 2001}, IIF_MATCH, iif1);
507
508 // Overwrite some existing uids
509 int iif2 = 17;
510 ASSERT_TRUE(isOk(mTc.addUidInterfaceRules(iif2, {1000, 2000})));
511 expectUidOwnerMapValues({1001}, IIF_MATCH, iif0);
512 expectUidOwnerMapValues({2001}, IIF_MATCH, iif1);
513 expectUidOwnerMapValues({1000, 2000}, IIF_MATCH, iif2);
514}
515
516TEST_F(TrafficControllerTest, TestRemoveUidInterfaceFilteringRules) {
517 int iif0 = 15;
518 int iif1 = 16;
519 ASSERT_TRUE(isOk(mTc.addUidInterfaceRules(iif0, {1000, 1001})));
520 ASSERT_TRUE(isOk(mTc.addUidInterfaceRules(iif1, {2000, 2001})));
521 expectUidOwnerMapValues({1000, 1001}, IIF_MATCH, iif0);
522 expectUidOwnerMapValues({2000, 2001}, IIF_MATCH, iif1);
523
524 // Rmove some uids
525 ASSERT_TRUE(isOk(mTc.removeUidInterfaceRules({1001, 2001})));
526 expectUidOwnerMapValues({1000}, IIF_MATCH, iif0);
527 expectUidOwnerMapValues({2000}, IIF_MATCH, iif1);
528 checkEachUidValue({1000, 2000}, IIF_MATCH); // Make sure there are only two uids remaining
529
530 // Remove non-existent uids shouldn't fail
531 ASSERT_TRUE(isOk(mTc.removeUidInterfaceRules({2000, 3000})));
532 expectUidOwnerMapValues({1000}, IIF_MATCH, iif0);
533 checkEachUidValue({1000}, IIF_MATCH); // Make sure there are only one uid remaining
534
535 // Remove everything
536 ASSERT_TRUE(isOk(mTc.removeUidInterfaceRules({1000})));
537 expectMapEmpty(mFakeUidOwnerMap);
538}
539
Motomu Utsumi8b42e6d2022-05-19 06:23:40 +0000540TEST_F(TrafficControllerTest, TestUpdateUidLockdownRule) {
541 // Add Lockdown rules
542 ASSERT_TRUE(isOk(mTc.updateUidLockdownRule(1000, true /* add */)));
543 ASSERT_TRUE(isOk(mTc.updateUidLockdownRule(1001, true /* add */)));
544 expectUidOwnerMapValues({1000, 1001}, LOCKDOWN_VPN_MATCH, 0);
545
546 // Remove one of Lockdown rules
547 ASSERT_TRUE(isOk(mTc.updateUidLockdownRule(1000, false /* add */)));
548 expectUidOwnerMapValues({1001}, LOCKDOWN_VPN_MATCH, 0);
549
550 // Remove remaining Lockdown rule
551 ASSERT_TRUE(isOk(mTc.updateUidLockdownRule(1001, false /* add */)));
552 expectMapEmpty(mFakeUidOwnerMap);
553}
554
Wayne Ma4d692332022-01-19 16:04:04 +0800555TEST_F(TrafficControllerTest, TestUidInterfaceFilteringRulesCoexistWithExistingMatches) {
556 // Set up existing PENALTY_BOX_MATCH rules
Wayne Ma7be6bce2022-01-12 16:29:49 +0800557 ASSERT_TRUE(isOk(updateUidOwnerMaps({1000, 1001, 10012}, PENALTY_BOX_MATCH,
558 TrafficController::IptOpInsert)));
Wayne Ma4d692332022-01-19 16:04:04 +0800559 expectUidOwnerMapValues({1000, 1001, 10012}, PENALTY_BOX_MATCH, 0);
560
561 // Add some partially-overlapping uid owner rules and check result
562 int iif1 = 32;
563 ASSERT_TRUE(isOk(mTc.addUidInterfaceRules(iif1, {10012, 10013, 10014})));
564 expectUidOwnerMapValues({1000, 1001}, PENALTY_BOX_MATCH, 0);
565 expectUidOwnerMapValues({10012}, PENALTY_BOX_MATCH | IIF_MATCH, iif1);
566 expectUidOwnerMapValues({10013, 10014}, IIF_MATCH, iif1);
567
568 // Removing some PENALTY_BOX_MATCH rules should not change uid interface rule
Wayne Ma7be6bce2022-01-12 16:29:49 +0800569 ASSERT_TRUE(isOk(updateUidOwnerMaps({1001, 10012}, PENALTY_BOX_MATCH,
570 TrafficController::IptOpDelete)));
Wayne Ma4d692332022-01-19 16:04:04 +0800571 expectUidOwnerMapValues({1000}, PENALTY_BOX_MATCH, 0);
572 expectUidOwnerMapValues({10012, 10013, 10014}, IIF_MATCH, iif1);
573
574 // Remove all uid interface rules
575 ASSERT_TRUE(isOk(mTc.removeUidInterfaceRules({10012, 10013, 10014})));
576 expectUidOwnerMapValues({1000}, PENALTY_BOX_MATCH, 0);
577 // Make sure these are the only uids left
578 checkEachUidValue({1000}, PENALTY_BOX_MATCH);
579}
580
581TEST_F(TrafficControllerTest, TestUidInterfaceFilteringRulesCoexistWithNewMatches) {
582 int iif1 = 56;
583 // Set up existing uid interface rules
584 ASSERT_TRUE(isOk(mTc.addUidInterfaceRules(iif1, {10001, 10002})));
585 expectUidOwnerMapValues({10001, 10002}, IIF_MATCH, iif1);
586
587 // Add some partially-overlapping doze rules
588 EXPECT_EQ(0, mTc.replaceUidOwnerMap("fw_dozable", true, {10002, 10003}));
589 expectUidOwnerMapValues({10001}, IIF_MATCH, iif1);
590 expectUidOwnerMapValues({10002}, DOZABLE_MATCH | IIF_MATCH, iif1);
591 expectUidOwnerMapValues({10003}, DOZABLE_MATCH, 0);
592
593 // Introduce a third rule type (powersave) on various existing UIDs
594 EXPECT_EQ(0, mTc.replaceUidOwnerMap("fw_powersave", true, {10000, 10001, 10002, 10003}));
595 expectUidOwnerMapValues({10000}, POWERSAVE_MATCH, 0);
596 expectUidOwnerMapValues({10001}, POWERSAVE_MATCH | IIF_MATCH, iif1);
597 expectUidOwnerMapValues({10002}, POWERSAVE_MATCH | DOZABLE_MATCH | IIF_MATCH, iif1);
598 expectUidOwnerMapValues({10003}, POWERSAVE_MATCH | DOZABLE_MATCH, 0);
599
600 // Remove all doze rules
601 EXPECT_EQ(0, mTc.replaceUidOwnerMap("fw_dozable", true, {}));
602 expectUidOwnerMapValues({10000}, POWERSAVE_MATCH, 0);
603 expectUidOwnerMapValues({10001}, POWERSAVE_MATCH | IIF_MATCH, iif1);
604 expectUidOwnerMapValues({10002}, POWERSAVE_MATCH | IIF_MATCH, iif1);
605 expectUidOwnerMapValues({10003}, POWERSAVE_MATCH, 0);
606
607 // Remove all powersave rules, expect ownerMap to only have uid interface rules left
608 EXPECT_EQ(0, mTc.replaceUidOwnerMap("fw_powersave", true, {}));
609 expectUidOwnerMapValues({10001, 10002}, IIF_MATCH, iif1);
610 // Make sure these are the only uids left
611 checkEachUidValue({10001, 10002}, IIF_MATCH);
612}
613
Motomu Utsumib08654c2022-05-11 05:56:26 +0000614TEST_F(TrafficControllerTest, TestAddUidInterfaceFilteringRulesWithWildcard) {
615 // iif=0 is a wildcard
616 int iif = 0;
617 // Add interface rule with wildcard to uids
618 ASSERT_TRUE(isOk(mTc.addUidInterfaceRules(iif, {1000, 1001})));
619 expectUidOwnerMapValues({1000, 1001}, IIF_MATCH, iif);
620}
621
622TEST_F(TrafficControllerTest, TestRemoveUidInterfaceFilteringRulesWithWildcard) {
623 // iif=0 is a wildcard
624 int iif = 0;
625 // Add interface rule with wildcard to two uids
626 ASSERT_TRUE(isOk(mTc.addUidInterfaceRules(iif, {1000, 1001})));
627 expectUidOwnerMapValues({1000, 1001}, IIF_MATCH, iif);
628
629 // Remove interface rule from one of the uids
630 ASSERT_TRUE(isOk(mTc.removeUidInterfaceRules({1000})));
631 expectUidOwnerMapValues({1001}, IIF_MATCH, iif);
632 checkEachUidValue({1001}, IIF_MATCH);
633
634 // Remove interface rule from the remaining uid
635 ASSERT_TRUE(isOk(mTc.removeUidInterfaceRules({1001})));
636 expectMapEmpty(mFakeUidOwnerMap);
637}
638
639TEST_F(TrafficControllerTest, TestUidInterfaceFilteringRulesWithWildcardAndExistingMatches) {
640 // Set up existing DOZABLE_MATCH and POWERSAVE_MATCH rule
641 ASSERT_TRUE(isOk(updateUidOwnerMaps({1000}, DOZABLE_MATCH,
642 TrafficController::IptOpInsert)));
643 ASSERT_TRUE(isOk(updateUidOwnerMaps({1000}, POWERSAVE_MATCH,
644 TrafficController::IptOpInsert)));
645
646 // iif=0 is a wildcard
647 int iif = 0;
648 // Add interface rule with wildcard to the existing uid
649 ASSERT_TRUE(isOk(mTc.addUidInterfaceRules(iif, {1000})));
650 expectUidOwnerMapValues({1000}, POWERSAVE_MATCH | DOZABLE_MATCH | IIF_MATCH, iif);
651
652 // Remove interface rule with wildcard from the existing uid
653 ASSERT_TRUE(isOk(mTc.removeUidInterfaceRules({1000})));
654 expectUidOwnerMapValues({1000}, POWERSAVE_MATCH | DOZABLE_MATCH, 0);
655}
656
657TEST_F(TrafficControllerTest, TestUidInterfaceFilteringRulesWithWildcardAndNewMatches) {
658 // iif=0 is a wildcard
659 int iif = 0;
660 // Set up existing interface rule with wildcard
661 ASSERT_TRUE(isOk(mTc.addUidInterfaceRules(iif, {1000})));
662
663 // Add DOZABLE_MATCH and POWERSAVE_MATCH rule to the existing uid
664 ASSERT_TRUE(isOk(updateUidOwnerMaps({1000}, DOZABLE_MATCH,
665 TrafficController::IptOpInsert)));
666 ASSERT_TRUE(isOk(updateUidOwnerMaps({1000}, POWERSAVE_MATCH,
667 TrafficController::IptOpInsert)));
668 expectUidOwnerMapValues({1000}, POWERSAVE_MATCH | DOZABLE_MATCH | IIF_MATCH, iif);
669
670 // Remove DOZABLE_MATCH and POWERSAVE_MATCH rule from the existing uid
671 ASSERT_TRUE(isOk(updateUidOwnerMaps({1000}, DOZABLE_MATCH,
672 TrafficController::IptOpDelete)));
673 ASSERT_TRUE(isOk(updateUidOwnerMaps({1000}, POWERSAVE_MATCH,
674 TrafficController::IptOpDelete)));
675 expectUidOwnerMapValues({1000}, IIF_MATCH, iif);
676}
677
Wayne Ma4d692332022-01-19 16:04:04 +0800678TEST_F(TrafficControllerTest, TestGrantInternetPermission) {
679 std::vector<uid_t> appUids = {TEST_UID, TEST_UID2, TEST_UID3};
680
681 mTc.setPermissionForUids(INetd::PERMISSION_INTERNET, appUids);
682 expectMapEmpty(mFakeUidPermissionMap);
683 expectPrivilegedUserSetEmpty();
684}
685
686TEST_F(TrafficControllerTest, TestRevokeInternetPermission) {
687 std::vector<uid_t> appUids = {TEST_UID, TEST_UID2, TEST_UID3};
688
689 mTc.setPermissionForUids(INetd::PERMISSION_NONE, appUids);
690 expectUidPermissionMapValues(appUids, INetd::PERMISSION_NONE);
691}
692
693TEST_F(TrafficControllerTest, TestPermissionUninstalled) {
694 std::vector<uid_t> appUids = {TEST_UID, TEST_UID2, TEST_UID3};
695
696 mTc.setPermissionForUids(INetd::PERMISSION_UPDATE_DEVICE_STATS, appUids);
697 expectUidPermissionMapValues(appUids, INetd::PERMISSION_UPDATE_DEVICE_STATS);
698 expectPrivilegedUserSet(appUids);
699
700 std::vector<uid_t> uidToRemove = {TEST_UID};
701 mTc.setPermissionForUids(INetd::PERMISSION_UNINSTALLED, uidToRemove);
702
703 std::vector<uid_t> uidRemain = {TEST_UID3, TEST_UID2};
704 expectUidPermissionMapValues(uidRemain, INetd::PERMISSION_UPDATE_DEVICE_STATS);
705 expectPrivilegedUserSet(uidRemain);
706
707 mTc.setPermissionForUids(INetd::PERMISSION_UNINSTALLED, uidRemain);
708 expectMapEmpty(mFakeUidPermissionMap);
709 expectPrivilegedUserSetEmpty();
710}
711
712TEST_F(TrafficControllerTest, TestGrantUpdateStatsPermission) {
713 std::vector<uid_t> appUids = {TEST_UID, TEST_UID2, TEST_UID3};
714
715 mTc.setPermissionForUids(INetd::PERMISSION_UPDATE_DEVICE_STATS, appUids);
716 expectUidPermissionMapValues(appUids, INetd::PERMISSION_UPDATE_DEVICE_STATS);
717 expectPrivilegedUserSet(appUids);
718
719 mTc.setPermissionForUids(INetd::PERMISSION_NONE, appUids);
720 expectPrivilegedUserSetEmpty();
721 expectUidPermissionMapValues(appUids, INetd::PERMISSION_NONE);
722}
723
724TEST_F(TrafficControllerTest, TestRevokeUpdateStatsPermission) {
725 std::vector<uid_t> appUids = {TEST_UID, TEST_UID2, TEST_UID3};
726
727 mTc.setPermissionForUids(INetd::PERMISSION_UPDATE_DEVICE_STATS, appUids);
728 expectPrivilegedUserSet(appUids);
729
730 std::vector<uid_t> uidToRemove = {TEST_UID};
731 mTc.setPermissionForUids(INetd::PERMISSION_NONE, uidToRemove);
732
733 std::vector<uid_t> uidRemain = {TEST_UID3, TEST_UID2};
734 expectPrivilegedUserSet(uidRemain);
735
736 mTc.setPermissionForUids(INetd::PERMISSION_NONE, uidRemain);
737 expectPrivilegedUserSetEmpty();
738}
739
740TEST_F(TrafficControllerTest, TestGrantWrongPermission) {
741 std::vector<uid_t> appUids = {TEST_UID, TEST_UID2, TEST_UID3};
742
743 mTc.setPermissionForUids(INetd::PERMISSION_NONE, appUids);
744 expectPrivilegedUserSetEmpty();
745 expectUidPermissionMapValues(appUids, INetd::PERMISSION_NONE);
746}
747
748TEST_F(TrafficControllerTest, TestGrantDuplicatePermissionSlientlyFail) {
749 std::vector<uid_t> appUids = {TEST_UID, TEST_UID2, TEST_UID3};
750
751 mTc.setPermissionForUids(INetd::PERMISSION_INTERNET, appUids);
752 expectMapEmpty(mFakeUidPermissionMap);
753
754 std::vector<uid_t> uidToAdd = {TEST_UID};
755 mTc.setPermissionForUids(INetd::PERMISSION_INTERNET, uidToAdd);
756
757 expectPrivilegedUserSetEmpty();
758
759 mTc.setPermissionForUids(INetd::PERMISSION_NONE, appUids);
760 expectUidPermissionMapValues(appUids, INetd::PERMISSION_NONE);
761
762 mTc.setPermissionForUids(INetd::PERMISSION_UPDATE_DEVICE_STATS, appUids);
763 expectPrivilegedUserSet(appUids);
764
765 mTc.setPermissionForUids(INetd::PERMISSION_UPDATE_DEVICE_STATS, uidToAdd);
766 expectPrivilegedUserSet(appUids);
767
768 mTc.setPermissionForUids(INetd::PERMISSION_NONE, appUids);
769 expectPrivilegedUserSetEmpty();
770}
771
Ken Chen2fb86362022-06-05 11:39:38 +0800772TEST_F(TrafficControllerTest, TestDumpsys) {
Ken Chen0dd74952022-06-06 18:25:18 +0800773 StatsKey tagStatsMapKey;
774 populateFakeStats(TEST_COOKIE, TEST_UID, TEST_TAG, &tagStatsMapKey);
775 populateFakeCounterSet(TEST_UID3, TEST_COUNTERSET);
Ken Chen2fb86362022-06-05 11:39:38 +0800776
Ken Chen0dd74952022-06-06 18:25:18 +0800777 // Expect: (part of this depends on hard-code values in populateFakeStats())
778 //
779 // mCookieTagMap:
780 // cookie=1 tag=0x2a uid=10086
781 //
782 // mUidCounterSetMap:
783 // 98765 1
784 //
785 // mAppUidStatsMap::
786 // uid rxBytes rxPackets txBytes txPackets
787 // 10086 100 1 0 0
788 //
789 // mStatsMapA:
790 // ifaceIndex ifaceName tag_hex uid_int cnt_set rxBytes rxPackets txBytes txPackets
791 // 999 test0 0x2a 10086 1 100 1 0 0
Ken Chen2fb86362022-06-05 11:39:38 +0800792 std::vector<std::string> expectedLines = {
Motomu Utsumi872c3692022-08-10 03:07:59 +0000793 "mCookieTagMap:",
Motomu Utsumi608c32c2022-08-16 04:16:25 +0000794 fmt::format("cookie={} tag={:#x} uid={}", TEST_COOKIE, TEST_TAG, TEST_UID)};
Ken Chen2fb86362022-06-05 11:39:38 +0800795
Ken Chen2fb86362022-06-05 11:39:38 +0800796 EXPECT_TRUE(expectDumpsysContains(expectedLines));
797}
798
Hungming Chen410bb122022-06-09 01:32:00 +0800799TEST_F(TrafficControllerTest, dumpsysInvalidMaps) {
800 makeTrafficControllerMapsInvalid();
801
Hungming Chen56b90132022-06-09 11:33:43 +0800802 const std::string kErrIterate = "print end with error: Get firstKey map -1 failed: "
803 "Bad file descriptor";
804 const std::string kErrReadRulesConfig = "read ownerMatch configure failed with error: "
805 "Read value of map -1 failed: Bad file descriptor";
Hungming Chen56b90132022-06-09 11:33:43 +0800806
Hungming Chen410bb122022-06-09 01:32:00 +0800807 std::vector<std::string> expectedLines = {
Motomu Utsumi809a3162022-08-16 08:50:46 +0000808 fmt::format("mCookieTagMap {}", kErrIterate)};
Hungming Chen410bb122022-06-09 01:32:00 +0800809 EXPECT_TRUE(expectDumpsysContains(expectedLines));
810}
811
Ken Chen77a6b712022-06-06 12:46:36 +0800812TEST_F(TrafficControllerTest, getFirewallType) {
813 static const struct TestConfig {
814 ChildChain childChain;
815 FirewallType firewallType;
816 } testConfigs[] = {
817 // clang-format off
818 {NONE, DENYLIST},
819 {DOZABLE, ALLOWLIST},
820 {STANDBY, DENYLIST},
821 {POWERSAVE, ALLOWLIST},
822 {RESTRICTED, ALLOWLIST},
823 {LOW_POWER_STANDBY, ALLOWLIST},
Ken Chen77a6b712022-06-06 12:46:36 +0800824 {OEM_DENY_1, DENYLIST},
825 {OEM_DENY_2, DENYLIST},
Ken Chend3a3af52022-06-08 02:54:09 +0000826 {OEM_DENY_3, DENYLIST},
Ken Chen77a6b712022-06-06 12:46:36 +0800827 {INVALID_CHAIN, DENYLIST},
828 // clang-format on
829 };
830
831 for (const auto& config : testConfigs) {
832 SCOPED_TRACE(fmt::format("testConfig: [{}, {}]", config.childChain, config.firewallType));
833 EXPECT_EQ(config.firewallType, mTc.getFirewallType(config.childChain));
834 }
835}
836
Patrick Rohr61e94672022-02-01 21:06:40 +0100837constexpr uint32_t SOCK_CLOSE_WAIT_US = 30 * 1000;
838constexpr uint32_t ENOBUFS_POLL_WAIT_US = 10 * 1000;
839
840using android::base::Error;
841using android::base::Result;
842using android::bpf::BpfMap;
843
844// This test set up a SkDestroyListener that is running parallel with the production
845// SkDestroyListener. The test will create thousands of sockets and tag them on the
846// production cookieUidTagMap and close them in a short time. When the number of
847// sockets get closed exceeds the buffer size, it will start to return ENOBUFF
848// error. The error will be ignored by the production SkDestroyListener and the
849// test will clean up the tags in tearDown if there is any remains.
850
851// TODO: Instead of test the ENOBUFF error, we can test the production
852// SkDestroyListener to see if it failed to delete a tagged socket when ENOBUFF
853// triggered.
854class NetlinkListenerTest : public testing::Test {
855 protected:
856 NetlinkListenerTest() {}
857 BpfMap<uint64_t, UidTagValue> mCookieTagMap;
858
859 void SetUp() {
Maciej Żenczykowskiced35312022-05-31 05:11:12 -0700860 mCookieTagMap.init(COOKIE_TAG_MAP_PATH);
Patrick Rohr61e94672022-02-01 21:06:40 +0100861 ASSERT_TRUE(mCookieTagMap.isValid());
862 }
863
864 void TearDown() {
865 const auto deleteTestCookieEntries = [](const uint64_t& key, const UidTagValue& value,
866 BpfMap<uint64_t, UidTagValue>& map) {
867 if ((value.uid == TEST_UID) && (value.tag == TEST_TAG)) {
868 Result<void> res = map.deleteValue(key);
869 if (res.ok() || (res.error().code() == ENOENT)) {
870 return Result<void>();
871 }
Maciej Żenczykowskie0f58462022-05-17 13:59:22 -0700872 ALOGE("Failed to delete data(cookie = %" PRIu64 "): %s", key,
Patrick Rohr61e94672022-02-01 21:06:40 +0100873 strerror(res.error().code()));
874 }
875 // Move forward to next cookie in the map.
876 return Result<void>();
877 };
878 EXPECT_RESULT_OK(mCookieTagMap.iterateWithValue(deleteTestCookieEntries));
879 }
880
881 Result<void> checkNoGarbageTagsExist() {
882 const auto checkGarbageTags = [](const uint64_t&, const UidTagValue& value,
883 const BpfMap<uint64_t, UidTagValue>&) -> Result<void> {
884 if ((TEST_UID == value.uid) && (TEST_TAG == value.tag)) {
885 return Error(EUCLEAN) << "Closed socket is not untagged";
886 }
887 return {};
888 };
889 return mCookieTagMap.iterateWithValue(checkGarbageTags);
890 }
891
892 bool checkMassiveSocketDestroy(int totalNumber, bool expectError) {
893 std::unique_ptr<android::netdutils::NetlinkListenerInterface> skDestroyListener;
894 auto result = android::net::TrafficController::makeSkDestroyListener();
895 if (!isOk(result)) {
896 ALOGE("Unable to create SkDestroyListener: %s", toString(result).c_str());
897 } else {
898 skDestroyListener = std::move(result.value());
899 }
900 int rxErrorCount = 0;
901 // Rx handler extracts nfgenmsg looks up and invokes registered dispatch function.
902 const auto rxErrorHandler = [&rxErrorCount](const int, const int) { rxErrorCount++; };
903 skDestroyListener->registerSkErrorHandler(rxErrorHandler);
904 int fds[totalNumber];
905 for (int i = 0; i < totalNumber; i++) {
906 fds[i] = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
907 // The likely reason for a failure is running out of available file descriptors.
908 EXPECT_LE(0, fds[i]) << i << " of " << totalNumber;
909 if (fds[i] < 0) {
910 // EXPECT_LE already failed above, so test case is a failure, but we don't
911 // want potentially tens of thousands of extra failures creating and then
912 // closing all these fds cluttering up the logs.
913 totalNumber = i;
914 break;
915 };
916 libnetd_updatable_tagSocket(fds[i], TEST_TAG, TEST_UID, 1000);
917 }
918
919 // TODO: Use a separate thread that has its own fd table so we can
920 // close sockets even faster simply by terminating that thread.
921 for (int i = 0; i < totalNumber; i++) {
922 EXPECT_EQ(0, close(fds[i]));
923 }
924 // wait a bit for netlink listener to handle all the messages.
925 usleep(SOCK_CLOSE_WAIT_US);
926 if (expectError) {
927 // If ENOBUFS triggered, check it only called into the handler once, ie.
928 // that the netlink handler is not spinning.
929 int currentErrorCount = rxErrorCount;
930 // 0 error count is acceptable because the system has chances to close all sockets
931 // normally.
932 EXPECT_LE(0, rxErrorCount);
933 if (!rxErrorCount) return true;
934
935 usleep(ENOBUFS_POLL_WAIT_US);
936 EXPECT_EQ(currentErrorCount, rxErrorCount);
937 } else {
938 EXPECT_RESULT_OK(checkNoGarbageTagsExist());
939 EXPECT_EQ(0, rxErrorCount);
940 }
941 return false;
942 }
943};
944
945TEST_F(NetlinkListenerTest, TestAllSocketUntagged) {
946 checkMassiveSocketDestroy(10, false);
947 checkMassiveSocketDestroy(100, false);
948}
949
950// Disabled because flaky on blueline-userdebug; this test relies on the main thread
951// winning a race against the NetlinkListener::run() thread. There's no way to ensure
952// things will be scheduled the same way across all architectures and test environments.
953TEST_F(NetlinkListenerTest, DISABLED_TestSkDestroyError) {
954 bool needRetry = false;
955 int retryCount = 0;
956 do {
957 needRetry = checkMassiveSocketDestroy(32500, true);
958 if (needRetry) retryCount++;
959 } while (needRetry && retryCount < 3);
960 // Should review test if it can always close all sockets correctly.
961 EXPECT_GT(3, retryCount);
962}
963
964
Wayne Ma4d692332022-01-19 16:04:04 +0800965} // namespace net
966} // namespace android