Add internal support for IPsec forward policies
This change adds support for IPsec forward policies, which are necessary for packets to be allowed to be forwarded to another interface, as is the case with tethering. This is necessary and useful only within the system server, and as such is not exposed as a public API. This change is safe, since the addition of a FWD policy on IPsec tunnel interfaces will by default block forwarded traffic (as would be the case without this patch). In the event that the (system) owner of the tunnel requires support for forwarded packets (eg tethering), this patch allows application of transforms in the FWD direction as well. This will be used to ensure that the VCN can be used as the underlying network for the purposes of tethering. Bug: 185495453 Test: atest IpSecServiceTest Test: atest IpSecServiceParameterizedTest Test: manual testing with tethering over VCN Change-Id: I74ecea71f1954029f6fbdbe34598c82e0aac386b
This commit is contained in:
@@ -78,6 +78,16 @@ public final class IpSecManager {
|
|||||||
*/
|
*/
|
||||||
public static final int DIRECTION_OUT = 1;
|
public static final int DIRECTION_OUT = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used when applying a transform to direct traffic through an {@link IpSecTransform} for
|
||||||
|
* forwarding between interfaces.
|
||||||
|
*
|
||||||
|
* <p>See {@link #applyTransportModeTransform(Socket, int, IpSecTransform)}.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static final int DIRECTION_FWD = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Security Parameter Index (SPI) 0 indicates an unknown or invalid index.
|
* The Security Parameter Index (SPI) 0 indicates an unknown or invalid index.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ import android.net.util.NetdService;
|
|||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.ParcelFileDescriptor;
|
import android.os.ParcelFileDescriptor;
|
||||||
|
import android.os.Process;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ServiceSpecificException;
|
import android.os.ServiceSpecificException;
|
||||||
import android.system.ErrnoException;
|
import android.system.ErrnoException;
|
||||||
@@ -65,6 +66,7 @@ import com.android.internal.annotations.GuardedBy;
|
|||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.util.Preconditions;
|
import com.android.internal.util.Preconditions;
|
||||||
import com.android.net.module.util.NetdUtils;
|
import com.android.net.module.util.NetdUtils;
|
||||||
|
import com.android.net.module.util.PermissionUtils;
|
||||||
|
|
||||||
import libcore.io.IoUtils;
|
import libcore.io.IoUtils;
|
||||||
|
|
||||||
@@ -466,8 +468,7 @@ public class IpSecService extends IIpSecService.Stub {
|
|||||||
|
|
||||||
/** Safety method; guards against access of other user's UserRecords */
|
/** Safety method; guards against access of other user's UserRecords */
|
||||||
private void checkCallerUid(int uid) {
|
private void checkCallerUid(int uid) {
|
||||||
if (uid != Binder.getCallingUid()
|
if (uid != Binder.getCallingUid() && Process.SYSTEM_UID != Binder.getCallingUid()) {
|
||||||
&& android.os.Process.SYSTEM_UID != Binder.getCallingUid()) {
|
|
||||||
throw new SecurityException("Attempted access of unowned resources");
|
throw new SecurityException("Attempted access of unowned resources");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1105,11 +1106,15 @@ public class IpSecService extends IIpSecService.Stub {
|
|||||||
* Checks the user-provided direction field and throws an IllegalArgumentException if it is not
|
* Checks the user-provided direction field and throws an IllegalArgumentException if it is not
|
||||||
* DIRECTION_IN or DIRECTION_OUT
|
* DIRECTION_IN or DIRECTION_OUT
|
||||||
*/
|
*/
|
||||||
private static void checkDirection(int direction) {
|
private void checkDirection(int direction) {
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
case IpSecManager.DIRECTION_OUT:
|
case IpSecManager.DIRECTION_OUT:
|
||||||
case IpSecManager.DIRECTION_IN:
|
case IpSecManager.DIRECTION_IN:
|
||||||
return;
|
return;
|
||||||
|
case IpSecManager.DIRECTION_FWD:
|
||||||
|
// Only NETWORK_STACK or PERMISSION_NETWORK_STACK allowed to use forward policies
|
||||||
|
PermissionUtils.enforceNetworkStackPermission(mContext);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
throw new IllegalArgumentException("Invalid Direction: " + direction);
|
throw new IllegalArgumentException("Invalid Direction: " + direction);
|
||||||
}
|
}
|
||||||
@@ -1353,6 +1358,16 @@ public class IpSecService extends IIpSecService.Stub {
|
|||||||
ikey,
|
ikey,
|
||||||
0xffffffff,
|
0xffffffff,
|
||||||
resourceId);
|
resourceId);
|
||||||
|
netd.ipSecAddSecurityPolicy(
|
||||||
|
callerUid,
|
||||||
|
selAddrFamily,
|
||||||
|
IpSecManager.DIRECTION_FWD,
|
||||||
|
remoteAddr,
|
||||||
|
localAddr,
|
||||||
|
0,
|
||||||
|
ikey,
|
||||||
|
0xffffffff,
|
||||||
|
resourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
userRecord.mTunnelInterfaceRecords.put(
|
userRecord.mTunnelInterfaceRecords.put(
|
||||||
@@ -1820,7 +1835,7 @@ public class IpSecService extends IIpSecService.Stub {
|
|||||||
int mark =
|
int mark =
|
||||||
(direction == IpSecManager.DIRECTION_OUT)
|
(direction == IpSecManager.DIRECTION_OUT)
|
||||||
? tunnelInterfaceInfo.getOkey()
|
? tunnelInterfaceInfo.getOkey()
|
||||||
: tunnelInterfaceInfo.getIkey();
|
: tunnelInterfaceInfo.getIkey(); // Ikey also used for FWD policies
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Default to using the invalid SPI of 0 for inbound SAs. This allows policies to skip
|
// Default to using the invalid SPI of 0 for inbound SAs. This allows policies to skip
|
||||||
|
|||||||
Reference in New Issue
Block a user