summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChiachang <chiachangwang@google.com>2022-05-12 05:55:45 +0000
committerCherrypicker Worker <android-build-cherrypicker-worker@google.com>2022-06-02 12:45:58 +0000
commit3aa56610449ec05da56bbb83ceafb15a52ebaa1b (patch)
treec9abb5e0345d4f93cb339b274019943c743905a0
parent89e504e6c3bbcce06850100a99f5f9f2874ca36c (diff)
downloadnetd-3aa56610449ec05da56bbb83ceafb15a52ebaa1b.tar.gz
Restrict the local network range
If the network assigns a range that is not a defined local network range, it should not be considered as a local network range. Thus, intersect the network assigned range with RFC1918/ CGNAT/LINK LOCAL ranges to ensure it's an accepted local network range. Bug: 184750836 Test: cd system/netd ; atest Change-Id: I3ac6bba439986b72dbddec99c6aca3394c6d3235 (cherry picked from commit cff5e88c75a4d23d472544b7008a4e51af1381c4) Merged-In: I3ac6bba439986b72dbddec99c6aca3394c6d3235
-rw-r--r--server/RouteController.cpp22
-rw-r--r--server/RouteController.h1
-rw-r--r--tests/binder_test.cpp63
3 files changed, 68 insertions, 18 deletions
diff --git a/server/RouteController.cpp b/server/RouteController.cpp
index 465e5b90..d2af9a37 100644
--- a/server/RouteController.cpp
+++ b/server/RouteController.cpp
@@ -64,6 +64,14 @@ const char* const ROUTE_TABLE_NAME_MAIN = "main";
const char* const RouteController::LOCAL_MANGLE_INPUT = "routectrl_mangle_INPUT";
+const IPPrefix V4_LOCAL_ADDR[] = {
+ IPPrefix::forString("169.254.0.0/16"), // Link Local
+ IPPrefix::forString("100.64.0.0/10"), // CGNAT
+ IPPrefix::forString("10.0.0.0/8"), // RFC1918
+ IPPrefix::forString("172.16.0.0/12"), // RFC1918
+ IPPrefix::forString("192.168.0.0/16") // RFC1918
+};
+
const uint8_t AF_FAMILIES[] = {AF_INET, AF_INET6};
const uid_t UID_ROOT = 0;
@@ -1384,13 +1392,23 @@ int RouteController::removeInterfaceFromDefaultNetwork(const char* interface,
return modifyDefaultNetwork(RTM_DELRULE, interface, permission);
}
+bool RouteController::isTargetV4LocalRange(const char* dst) {
+ for (IPPrefix addr : V4_LOCAL_ADDR) {
+ if (addr.contains(IPPrefix::forString(dst))) {
+ return true;
+ }
+ }
+ return false;
+}
+
bool RouteController::isLocalAddress(TableType tableType, const char* destination,
const char* nexthop) {
IPPrefix prefix = IPPrefix::forString(destination);
- // TODO: Intersect with RFC1918/CGNAT/LINK LOCAL range.
return nexthop == nullptr && tableType == RouteController::INTERFACE &&
// Skip default route to prevent network being modeled as point-to-point interfaces.
- (prefix.family() == AF_INET6 && prefix != IPPrefix::forString("::/0"));
+ ((prefix.family() == AF_INET6 && prefix != IPPrefix::forString("::/0")) ||
+ // Skip adding non-target local network range.
+ (prefix.family() == AF_INET && isTargetV4LocalRange(destination)));
}
int RouteController::addRoute(const char* interface, const char* destination, const char* nexthop,
diff --git a/server/RouteController.h b/server/RouteController.h
index 74d005ac..ff41678d 100644
--- a/server/RouteController.h
+++ b/server/RouteController.h
@@ -231,6 +231,7 @@ public:
static int modifyUidLocalNetworkRule(const char* interface, uid_t uidStart, uid_t uidEnd,
bool add);
static bool isLocalAddress(TableType tableType, const char* destination, const char* nexthop);
+ static bool isTargetV4LocalRange(const char* addrstr);
};
// Public because they are called by by RouteControllerTest.cpp.
diff --git a/tests/binder_test.cpp b/tests/binder_test.cpp
index 2133e1da..f423ea38 100644
--- a/tests/binder_test.cpp
+++ b/tests/binder_test.cpp
@@ -1633,21 +1633,51 @@ TEST_F(NetdBinderTest, NetworkAddRemoveRouteToLocalExcludeTable) {
const char* testDest;
const char* testNextHop;
const bool expectInLocalTable;
- } kTestData[] = {
- {IP_RULE_V6, "::/0", "fe80::", false},
- {IP_RULE_V6, "::/0", "", false},
- {IP_RULE_V6, "2001:db8:cafe::/64", "fe80::", false},
- {IP_RULE_V6, "fe80::/64", "", true},
- {IP_RULE_V6, "2001:db8:cafe::/48", "", true},
- {IP_RULE_V6, "2001:db8:cafe::/64", "unreachable", false},
- {IP_RULE_V6, "2001:db8:ca00::/40", "", true},
- };
-
+ } kTestData[] = {{IP_RULE_V6, "::/0", "fe80::", false},
+ {IP_RULE_V6, "::/0", "", false},
+ {IP_RULE_V6, "2001:db8:cafe::/64", "fe80::", false},
+ {IP_RULE_V6, "fe80::/64", "", true},
+ {IP_RULE_V6, "2001:db8:cafe::/48", "", true},
+ {IP_RULE_V6, "2001:db8:cafe::/64", "unreachable", false},
+ {IP_RULE_V6, "2001:db8:ca00::/40", "", true},
+ {IP_RULE_V4, "0.0.0.0/0", "10.251.10.1", false},
+ {IP_RULE_V4, "192.1.0.0/16", "", false},
+ {IP_RULE_V4, "192.168.0.0/15", "", false},
+ {IP_RULE_V4, "192.168.0.0/16", "", true},
+ {IP_RULE_V4, "192.168.0.0/24", "", true},
+ {IP_RULE_V4, "100.1.0.0/16", "", false},
+ {IP_RULE_V4, "100.0.0.0/8", "", false},
+ {IP_RULE_V4, "100.64.0.0/10", "", true},
+ {IP_RULE_V4, "100.64.0.0/16", "", true},
+ {IP_RULE_V4, "100.64.0.0/10", "throw", false},
+ {IP_RULE_V4, "172.0.0.0/8", "", false},
+ {IP_RULE_V4, "172.16.0.0/12", "", true},
+ {IP_RULE_V4, "172.16.0.0/16", "", true},
+ {IP_RULE_V4, "172.16.0.0/12", "unreachable", false},
+ {IP_RULE_V4, "172.32.0.0/12", "", false},
+ {IP_RULE_V4, "169.0.0.0/8", "", false},
+ {IP_RULE_V4, "169.254.0.0/16", "", true},
+ {IP_RULE_V4, "169.254.0.0/20", "", true},
+ {IP_RULE_V4, "169.254.3.0/24", "", true},
+ {IP_RULE_V4, "170.254.0.0/16", "", false},
+ {IP_RULE_V4, "10.0.0.0/8", "", true},
+ {IP_RULE_V4, "10.0.0.0/7", "", false},
+ {IP_RULE_V4, "10.0.0.0/16", "", true},
+ {IP_RULE_V4, "10.251.0.0/16", "", true},
+ {IP_RULE_V4, "10.251.250.0/24", "", true},
+ {IP_RULE_V4, "10.251.10.2/31", "throw", false},
+ {IP_RULE_V4, "10.251.10.2/31", "unreachable", false}};
+
+ // To ensure that the nexthops for the above are reachable.
+ // Otherwise, the routes can't be created.
static const struct {
const char* ipVersion;
const char* testDest;
const char* testNextHop;
- } kLinkLocalRoutes[] = {{IP_RULE_V6, "2001:db8::/32", ""}};
+ } kDirectlyConnectedRoutes[] = {
+ {IP_RULE_V4, "10.251.10.0/30", ""},
+ {IP_RULE_V6, "2001:db8::/32", ""},
+ };
// Add test physical network
const auto& config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
@@ -1664,8 +1694,8 @@ TEST_F(NetdBinderTest, NetworkAddRemoveRouteToLocalExcludeTable) {
std::string localTableName = std::string(sTun.name() + "_local");
// Set up link-local routes for connectivity to the "gateway"
- for (size_t i = 0; i < std::size(kLinkLocalRoutes); i++) {
- const auto& td = kLinkLocalRoutes[i];
+ for (size_t i = 0; i < std::size(kDirectlyConnectedRoutes); i++) {
+ const auto& td = kDirectlyConnectedRoutes[i];
binder::Status status =
mNetd->networkAddRoute(TEST_NETID1, sTun.name(), td.testDest, td.testNextHop);
@@ -1679,7 +1709,8 @@ TEST_F(NetdBinderTest, NetworkAddRemoveRouteToLocalExcludeTable) {
for (size_t i = 0; i < std::size(kTestData); i++) {
const auto& td = kTestData[i];
-
+ SCOPED_TRACE(StringPrintf("case ip:%s, dest:%s, nexHop:%s, expect:%d", td.ipVersion,
+ td.testDest, td.testNextHop, td.expectInLocalTable));
binder::Status status =
mNetd->networkAddRoute(TEST_NETID1, sTun.name(), td.testDest, td.testNextHop);
EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
@@ -1698,8 +1729,8 @@ TEST_F(NetdBinderTest, NetworkAddRemoveRouteToLocalExcludeTable) {
localTableName.c_str());
}
- for (size_t i = 0; i < std::size(kLinkLocalRoutes); i++) {
- const auto& td = kLinkLocalRoutes[i];
+ for (size_t i = 0; i < std::size(kDirectlyConnectedRoutes); i++) {
+ const auto& td = kDirectlyConnectedRoutes[i];
status = mNetd->networkRemoveRoute(TEST_NETID1, sTun.name(), td.testDest, td.testNextHop);
EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
}