summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchiachangwang <chiachangwang@google.com>2022-06-03 02:52:32 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2022-06-03 02:52:32 +0000
commitea80b5bcfd2425df1f64484fe7040ca7179535a6 (patch)
treee073fef85d9e4fbf95235cbacd949ace1006bc49
parentedcf50bc3741e4e30f930bea4472452fee9d86a9 (diff)
parentf693a01e8fcf446c3d36430a94e479fe0d93c415 (diff)
downloadnetd-ea80b5bcfd2425df1f64484fe7040ca7179535a6.tar.gz
Add app default local rule am: 776b68cecb am: f693a01e8f
Original change: https://googleplex-android-review.googlesource.com/c/platform/system/netd/+/18714757 Change-Id: Ia4fc5b8fe2df8e83257198a942b12ea63157fa84 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--server/RouteController.cpp33
-rw-r--r--server/RouteController.h22
-rw-r--r--tests/binder_test.cpp8
3 files changed, 54 insertions, 9 deletions
diff --git a/server/RouteController.cpp b/server/RouteController.cpp
index d63dbd2e..ea8baea8 100644
--- a/server/RouteController.cpp
+++ b/server/RouteController.cpp
@@ -859,6 +859,13 @@ int RouteController::modifyPhysicalNetwork(unsigned netId, const char* interface
subPriority, add)) {
return ret;
}
+
+ // Per-UID local network rules must always match per-app default network rules,
+ // because their purpose is to allow the UIDs to use the default network for
+ // local destinations within it.
+ if (int ret = modifyUidLocalNetworkRule(interface, range.start, range.stop, add)) {
+ return ret;
+ }
}
}
}
@@ -906,6 +913,32 @@ int RouteController::modifyPhysicalNetwork(unsigned netId, const char* interface
return 0;
}
+int RouteController::modifyUidLocalNetworkRule(const char* interface, uid_t uidStart, uid_t uidEnd,
+ bool add) {
+ uint32_t table = getRouteTableForInterface(interface, true /* local */);
+ if (table == RT_TABLE_UNSPEC) {
+ return -ESRCH;
+ }
+
+ if ((uidStart == INVALID_UID) || (uidEnd == INVALID_UID)) {
+ ALOGE("modifyUidLocalNetworkRule, invalid UIDs (%u, %u)", uidStart, uidEnd);
+ return -EUSERS;
+ }
+
+ Fwmark fwmark;
+ Fwmark mask;
+
+ fwmark.explicitlySelected = false;
+ mask.explicitlySelected = true;
+
+ // Access to this network is controlled by UID rules, not permission bits.
+ fwmark.permission = PERMISSION_NONE;
+ mask.permission = PERMISSION_NONE;
+
+ return modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE, RULE_PRIORITY_UID_LOCAL_ROUTES, table,
+ fwmark.intValue, mask.intValue, IIF_LOOPBACK, OIF_NONE, uidStart, uidEnd);
+}
+
[[nodiscard]] static int modifyUidUnreachableRule(unsigned netId, uid_t uidStart, uid_t uidEnd,
int32_t subPriority, bool add,
bool explicitSelect) {
diff --git a/server/RouteController.h b/server/RouteController.h
index 9b04cfd2..887187c8 100644
--- a/server/RouteController.h
+++ b/server/RouteController.h
@@ -55,11 +55,17 @@ constexpr int32_t RULE_PRIORITY_TETHERING = 21000;
constexpr int32_t RULE_PRIORITY_UID_IMPLICIT_NETWORK = 22000;
constexpr int32_t RULE_PRIORITY_IMPLICIT_NETWORK = 23000;
constexpr int32_t RULE_PRIORITY_BYPASSABLE_VPN_NO_LOCAL_EXCLUSION = 24000;
-// Rules used for excluding local route in the VPN network.
-constexpr int32_t RULE_PRIORITY_LOCAL_ROUTES = 25000;
-constexpr int32_t RULE_PRIORITY_BYPASSABLE_VPN_LOCAL_EXCLUSION = 26000;
-constexpr int32_t RULE_PRIORITY_VPN_FALLTHROUGH = 27000;
-constexpr int32_t RULE_PRIORITY_UID_DEFAULT_NETWORK = 28000;
+// Sets of rules used for excluding local routes from the VPN. Look up tables
+// that contain directly-connected local routes taken from the default network.
+// The first set is used for apps that have a per-UID default network. The rule
+// UID ranges match those of the per-UID default network rule for that network.
+// The second set has no UID ranges and is used for apps whose default network
+// is the system default network network.
+constexpr int32_t RULE_PRIORITY_UID_LOCAL_ROUTES = 25000;
+constexpr int32_t RULE_PRIORITY_LOCAL_ROUTES = 26000;
+constexpr int32_t RULE_PRIORITY_BYPASSABLE_VPN_LOCAL_EXCLUSION = 27000;
+constexpr int32_t RULE_PRIORITY_VPN_FALLTHROUGH = 28000;
+constexpr int32_t RULE_PRIORITY_UID_DEFAULT_NETWORK = 29000;
// Rule used when framework wants to disable default network from specified applications. There will
// be a small interval the same uid range exists in both UID_DEFAULT_UNREACHABLE and
// UID_DEFAULT_NETWORK when framework is switching user preferences.
@@ -74,8 +80,8 @@ constexpr int32_t RULE_PRIORITY_UID_DEFAULT_NETWORK = 28000;
// The priority is lower than UID_DEFAULT_NETWORK. Otherwise, the app will be told by
// ConnectivityService that it has a network in step 1 of the second case. But if it tries to use
// the network, it will not work. That will potentially cause a user-visible error.
-constexpr int32_t RULE_PRIORITY_UID_DEFAULT_UNREACHABLE = 29000;
-constexpr int32_t RULE_PRIORITY_DEFAULT_NETWORK = 30000;
+constexpr int32_t RULE_PRIORITY_UID_DEFAULT_UNREACHABLE = 30000;
+constexpr int32_t RULE_PRIORITY_DEFAULT_NETWORK = 31000;
constexpr int32_t RULE_PRIORITY_UNREACHABLE = 32000;
// clang-format on
@@ -221,6 +227,8 @@ public:
bool modifyNonUidBasedRules, bool excludeLocalRoutes);
static void updateTableNamesFile() EXCLUDES(sInterfaceToTableLock);
static int modifyVpnLocalExclusionRule(bool add, const char* physicalInterface);
+ static int modifyUidLocalNetworkRule(const char* interface, uid_t uidStart, uid_t uidEnd,
+ bool add);
};
// Public because they are called by by RouteControllerTest.cpp.
diff --git a/tests/binder_test.cpp b/tests/binder_test.cpp
index c01d78e9..5f5dff11 100644
--- a/tests/binder_test.cpp
+++ b/tests/binder_test.cpp
@@ -129,6 +129,7 @@ using android::net::RULE_PRIORITY_UID_DEFAULT_NETWORK;
using android::net::RULE_PRIORITY_UID_DEFAULT_UNREACHABLE;
using android::net::RULE_PRIORITY_UID_EXPLICIT_NETWORK;
using android::net::RULE_PRIORITY_UID_IMPLICIT_NETWORK;
+using android::net::RULE_PRIORITY_UID_LOCAL_ROUTES;
using android::net::RULE_PRIORITY_VPN_FALLTHROUGH;
using android::net::SockDiag;
using android::net::TetherOffloadRuleParcel;
@@ -3287,8 +3288,8 @@ void NetdBinderTest::createVpnNetworkWithUid(bool secure, uid_t uid, int vpnNetI
INetd::PERMISSION_NONE, false, false);
EXPECT_TRUE(mNetd->networkCreate(config).isOk());
EXPECT_TRUE(mNetd->networkAddInterface(fallthroughNetId, sTun.name()).isOk());
- // Create a physical network to test that local network access does not include the non-default
- // networks.
+ // Create another physical network in order to test VPN behaviour with multiple networks
+ // connected, of which one may be the default.
auto nonDefaultNetworkConfig = makeNativeNetworkConfig(
nonDefaultNetId, NativeNetworkType::PHYSICAL, INetd::PERMISSION_NONE, false, false);
EXPECT_TRUE(mNetd->networkCreate(nonDefaultNetworkConfig).isOk());
@@ -4025,6 +4026,7 @@ void verifyAppUidRules(std::vector<bool>&& expectedResults, std::vector<UidRange
ASSERT_EQ(expectedResults.size(), uidRanges.size());
if (iface.size()) {
std::string action = StringPrintf("lookup %s ", iface.c_str());
+ std::string action_local = StringPrintf("lookup %s_local ", iface.c_str());
for (unsigned long i = 0; i < uidRanges.size(); i++) {
EXPECT_EQ(expectedResults[i],
ipRuleExistsForRange(RULE_PRIORITY_UID_EXPLICIT_NETWORK + subPriority,
@@ -4035,6 +4037,8 @@ void verifyAppUidRules(std::vector<bool>&& expectedResults, std::vector<UidRange
EXPECT_EQ(expectedResults[i],
ipRuleExistsForRange(RULE_PRIORITY_UID_DEFAULT_NETWORK + subPriority,
uidRanges[i], action));
+ EXPECT_EQ(expectedResults[i], ipRuleExistsForRange(RULE_PRIORITY_UID_LOCAL_ROUTES,
+ uidRanges[i], action_local));
}
} else {
std::string action = "unreachable";