summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLorenzo Colitti <lorenzo@google.com>2015-02-27 16:45:55 +0900
committerLorenzo Colitti <lorenzo@google.com>2015-02-27 16:45:55 +0900
commit57947f02c00bb03651e3f9427c880211c689db7f (patch)
tree33b45eabd9dc617f8d3aa0bd3f0aa2f4116d536f
parent32d768792bcd5860512998543f6904d91da1a9b7 (diff)
downloadnetd-57947f02c00bb03651e3f9427c880211c689db7f.tar.gz
Add oif rules that allow UID 0 to bypass the VPN.
This is needed for wifi calling so that the kernel (which does not set marks) can tee packets towards the modem. It also fixes things like not being able to reply to DHCP requests from tethered clients when a VPN is up. System apps can already bypass the VPN using explicit marks, so allowing UID 0 to do so does not create additional bypass VPN issues. Bug: 19500693 Change-Id: Ie324026893637e9bd8e7aa65a37579569390e7b7
-rw-r--r--server/RouteController.cpp33
1 files changed, 22 insertions, 11 deletions
diff --git a/server/RouteController.cpp b/server/RouteController.cpp
index 6a6a470d..40734050 100644
--- a/server/RouteController.cpp
+++ b/server/RouteController.cpp
@@ -38,6 +38,7 @@ namespace {
// BEGIN CONSTANTS --------------------------------------------------------------------------------
const uint32_t RULE_PRIORITY_VPN_OVERRIDE_SYSTEM = 10000;
+const uint32_t RULE_PRIORITY_VPN_OVERRIDE_OIF = 10500;
const uint32_t RULE_PRIORITY_VPN_OUTPUT_TO_LOCAL = 11000;
const uint32_t RULE_PRIORITY_SECURE_VPN = 12000;
const uint32_t RULE_PRIORITY_EXPLICIT_NETWORK = 13000;
@@ -539,15 +540,25 @@ WARN_UNUSED_RESULT int modifyExplicitNetworkRule(unsigned netId, uint32_t table,
//
// Supports apps that use SO_BINDTODEVICE or IP_PKTINFO options and the kernel that already knows
// the outgoing interface (typically for link-local communications).
-WARN_UNUSED_RESULT int modifyOutputInterfaceRule(const char* interface, uint32_t table,
- Permission permission, uid_t uidStart,
- uid_t uidEnd, bool add) {
+WARN_UNUSED_RESULT int modifyOutputInterfaceRules(const char* interface, uint32_t table,
+ Permission permission, uid_t uidStart,
+ uid_t uidEnd, bool add) {
Fwmark fwmark;
Fwmark mask;
fwmark.permission = permission;
mask.permission = permission;
+ // If this rule does not specify a UID range, then also add a corresponding high-priority rule
+ // for UID. This covers forwarded packets and system daemons such as the tethering DHCP server.
+ if (uidStart == INVALID_UID && uidEnd == INVALID_UID) {
+ if (int ret = modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE, RULE_PRIORITY_VPN_OVERRIDE_OIF,
+ table, fwmark.intValue, mask.intValue, IIF_NONE, interface,
+ UID_ROOT, UID_ROOT)) {
+ return ret;
+ }
+ }
+
return modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE, RULE_PRIORITY_OUTPUT_INTERFACE, table,
fwmark.intValue, mask.intValue, IIF_NONE, interface, uidStart, uidEnd);
}
@@ -663,9 +674,9 @@ int configureDummyNetwork() {
return -errno;
}
- if ((ret = modifyOutputInterfaceRule(interface, table, PERMISSION_NONE,
- INVALID_UID, INVALID_UID, ACTION_ADD))) {
- ALOGE("Can't create oif rule for %s: %s", interface, strerror(-ret));
+ if ((ret = modifyOutputInterfaceRules(interface, table, PERMISSION_NONE,
+ INVALID_UID, INVALID_UID, ACTION_ADD))) {
+ ALOGE("Can't create oif rules for %s: %s", interface, strerror(-ret));
return ret;
}
@@ -711,8 +722,8 @@ WARN_UNUSED_RESULT int modifyLocalNetwork(unsigned netId, const char* interface,
if (int ret = modifyIncomingPacketMark(netId, interface, PERMISSION_NONE, add)) {
return ret;
}
- return modifyOutputInterfaceRule(interface, ROUTE_TABLE_LOCAL_NETWORK, PERMISSION_NONE,
- INVALID_UID, INVALID_UID, add);
+ return modifyOutputInterfaceRules(interface, ROUTE_TABLE_LOCAL_NETWORK, PERMISSION_NONE,
+ INVALID_UID, INVALID_UID, add);
}
WARN_UNUSED_RESULT int modifyPhysicalNetwork(unsigned netId, const char* interface,
@@ -729,7 +740,7 @@ WARN_UNUSED_RESULT int modifyPhysicalNetwork(unsigned netId, const char* interfa
add)) {
return ret;
}
- if (int ret = modifyOutputInterfaceRule(interface, table, permission, INVALID_UID, INVALID_UID,
+ if (int ret = modifyOutputInterfaceRules(interface, table, permission, INVALID_UID, INVALID_UID,
add)) {
return ret;
}
@@ -752,8 +763,8 @@ WARN_UNUSED_RESULT int modifyVirtualNetwork(unsigned netId, const char* interfac
range.second, add)) {
return ret;
}
- if (int ret = modifyOutputInterfaceRule(interface, table, PERMISSION_NONE, range.first,
- range.second, add)) {
+ if (int ret = modifyOutputInterfaceRules(interface, table, PERMISSION_NONE, range.first,
+ range.second, add)) {
return ret;
}
}