Require IPSEC_TUNNEL_MIGRATION feature flag to migrate transforms
Bug: 169169973
Test: atest IpSecServiceParameterizedTest (new tests added)
Change-Id: I3dd45b29163cd1e0cdbef08cb8aabdb629cf73bc
diff --git a/framework-t/src/android/net/IpSecManager.java b/framework-t/src/android/net/IpSecManager.java
index 6013769..1c83e09 100644
--- a/framework-t/src/android/net/IpSecManager.java
+++ b/framework-t/src/android/net/IpSecManager.java
@@ -66,6 +66,24 @@
private static final String TAG = "IpSecManager";
/**
+ * Feature flag to declare the kernel support of updating IPsec SAs.
+ *
+ * <p>Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: The device
+ * has the requisite kernel support for migrating IPsec tunnels to new source/destination
+ * addresses.
+ *
+ * <p>This feature implies that the device supports XFRM Migration (CONFIG_XFRM_MIGRATE) and has
+ * the kernel fixes to allow XFRM Migration correctly
+ *
+ * @see android.content.pm.PackageManager#FEATURE_IPSEC_TUNNEL_MIGRATION
+ * @hide
+ */
+ // Redefine this flag here so that IPsec code shipped in a mainline module can build on old
+ // platforms before FEATURE_IPSEC_TUNNEL_MIGRATION API is released.
+ public static final String FEATURE_IPSEC_TUNNEL_MIGRATION =
+ "android.software.ipsec_tunnel_migration";
+
+ /**
* Used when applying a transform to direct traffic through an {@link IpSecTransform}
* towards the host.
*
@@ -1015,8 +1033,7 @@
* @param newDestinationAddress the new destination address
* @hide
*/
- // TODO: b/169169973 Require FEATURE_IPSEC_MIGRATE
- @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS)
+ @RequiresFeature(FEATURE_IPSEC_TUNNEL_MIGRATION)
@RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS)
public void startMigration(
@NonNull IpSecTransform transform,
diff --git a/service-t/src/com/android/server/IpSecService.java b/service-t/src/com/android/server/IpSecService.java
index ca96c06..9e71eb3 100644
--- a/service-t/src/com/android/server/IpSecService.java
+++ b/service-t/src/com/android/server/IpSecService.java
@@ -17,6 +17,7 @@
package com.android.server;
import static android.Manifest.permission.DUMP;
+import static android.net.IpSecManager.FEATURE_IPSEC_TUNNEL_MIGRATION;
import static android.net.IpSecManager.INVALID_RESOURCE_ID;
import static android.system.OsConstants.AF_INET;
import static android.system.OsConstants.AF_INET6;
@@ -1681,6 +1682,14 @@
android.Manifest.permission.MANAGE_IPSEC_TUNNELS, "IpSecService");
}
+ private void enforceMigrateFeature() {
+ if (!mContext.getPackageManager().hasSystemFeature(FEATURE_IPSEC_TUNNEL_MIGRATION)) {
+ throw new UnsupportedOperationException(
+ "IPsec Tunnel migration requires"
+ + " PackageManager.FEATURE_IPSEC_TUNNEL_MIGRATION");
+ }
+ }
+
private void createOrUpdateTransform(
IpSecConfig c, int resourceId, SpiRecord spiRecord, EncapSocketRecord socketRecord)
throws RemoteException {
@@ -1807,6 +1816,7 @@
Objects.requireNonNull(newDestinationAddress, "newDestinationAddress was null");
enforceTunnelFeatureAndPermissions(callingPackage);
+ enforceMigrateFeature();
UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
TransformRecord transformInfo =
@@ -1962,6 +1972,14 @@
createOrUpdateTransform(c, transformResourceId, spiRecord, socketRecord);
if (transformInfo.isMigrating()) {
+ if (!mContext.getPackageManager()
+ .hasSystemFeature(FEATURE_IPSEC_TUNNEL_MIGRATION)) {
+ Log.wtf(
+ TAG,
+ "Attempted to migrate a transform without"
+ + " FEATURE_IPSEC_TUNNEL_MIGRATION");
+ }
+
for (int selAddrFamily : ADDRESS_FAMILIES) {
final IpSecMigrateInfoParcel migrateInfo =
new IpSecMigrateInfoParcel(
diff --git a/tests/unit/java/com/android/server/IpSecServiceParameterizedTest.java b/tests/unit/java/com/android/server/IpSecServiceParameterizedTest.java
index 6887885..1618a62 100644
--- a/tests/unit/java/com/android/server/IpSecServiceParameterizedTest.java
+++ b/tests/unit/java/com/android/server/IpSecServiceParameterizedTest.java
@@ -23,6 +23,7 @@
import static android.net.IpSecManager.DIRECTION_FWD;
import static android.net.IpSecManager.DIRECTION_IN;
import static android.net.IpSecManager.DIRECTION_OUT;
+import static android.net.IpSecManager.FEATURE_IPSEC_TUNNEL_MIGRATION;
import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
import static android.system.OsConstants.AF_INET;
import static android.system.OsConstants.AF_INET6;
@@ -1097,7 +1098,7 @@
}
@Test
- public void testFeatureFlagVerification() throws Exception {
+ public void testFeatureFlagIpSecTunnelsVerification() throws Exception {
when(mMockPkgMgr.hasSystemFeature(eq(PackageManager.FEATURE_IPSEC_TUNNELS)))
.thenReturn(false);
@@ -1109,4 +1110,17 @@
} catch (UnsupportedOperationException expected) {
}
}
+
+ @Test
+ @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
+ public void testFeatureFlagIpSecTunnelMigrationVerification() throws Exception {
+ when(mMockPkgMgr.hasSystemFeature(eq(FEATURE_IPSEC_TUNNEL_MIGRATION))).thenReturn(false);
+
+ try {
+ mIpSecService.migrateTransform(
+ 1 /* transformId */, NEW_SRC_ADDRESS, NEW_DST_ADDRESS, BLESSED_PACKAGE);
+ fail("Expected UnsupportedOperationException for disabled feature");
+ } catch (UnsupportedOperationException expected) {
+ }
+ }
}