diff --git a/core/java/android/net/IIpSecService.aidl b/core/java/android/net/IIpSecService.aidl index b5a2a16c7f..d6774d47b4 100644 --- a/core/java/android/net/IIpSecService.aidl +++ b/core/java/android/net/IIpSecService.aidl @@ -72,8 +72,4 @@ interface IIpSecService int tunnelResourceId, int direction, int transformResourceId, in String callingPackage); void removeTransportModeTransforms(in ParcelFileDescriptor socket); - - int lockEncapSocketForNattKeepalive(int encapSocketResourceId, int requesterUid); - - void releaseNattKeepalive(int nattKeepaliveResourceId, int ownerUid); } diff --git a/core/java/android/net/IpSecManager.java b/core/java/android/net/IpSecManager.java index 7d34381f73..83813da80c 100644 --- a/core/java/android/net/IpSecManager.java +++ b/core/java/android/net/IpSecManager.java @@ -19,11 +19,13 @@ import static com.android.internal.util.Preconditions.checkNotNull; import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.RequiresFeature; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; import android.content.Context; +import android.content.pm.PackageManager; import android.os.Binder; import android.os.ParcelFileDescriptor; import android.os.RemoteException; @@ -749,6 +751,7 @@ public final class IpSecManager { * @hide */ @SystemApi + @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS) @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS) public void addAddress(@NonNull InetAddress address, int prefixLen) throws IOException { try { @@ -771,6 +774,7 @@ public final class IpSecManager { * @hide */ @SystemApi + @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS) @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS) public void removeAddress(@NonNull InetAddress address, int prefixLen) throws IOException { try { @@ -886,6 +890,7 @@ public final class IpSecManager { */ @SystemApi @NonNull + @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS) @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS) public IpSecTunnelInterface createIpSecTunnelInterface(@NonNull InetAddress localAddress, @NonNull InetAddress remoteAddress, @NonNull Network underlyingNetwork) @@ -916,6 +921,7 @@ public final class IpSecManager { * @hide */ @SystemApi + @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS) @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS) public void applyTunnelModeTransform(@NonNull IpSecTunnelInterface tunnel, @PolicyDirection int direction, @NonNull IpSecTransform transform) throws IOException { diff --git a/core/java/android/net/IpSecTransform.java b/core/java/android/net/IpSecTransform.java index e519fdf65e..36111f2a37 100644 --- a/core/java/android/net/IpSecTransform.java +++ b/core/java/android/net/IpSecTransform.java @@ -21,9 +21,11 @@ import static com.android.internal.util.Preconditions.checkNotNull; import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.RequiresFeature; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.content.Context; +import android.content.pm.PackageManager; import android.os.Binder; import android.os.Handler; import android.os.IBinder; @@ -483,6 +485,7 @@ public final class IpSecTransform implements AutoCloseable { */ @SystemApi @NonNull + @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS) @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS) public IpSecTransform buildTunnelModeTransform( @NonNull InetAddress sourceAddress, diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java index c1f52552ea..fe22dcda96 100644 --- a/services/core/java/com/android/server/IpSecService.java +++ b/services/core/java/com/android/server/IpSecService.java @@ -28,7 +28,6 @@ import static android.system.OsConstants.SOCK_DGRAM; import static com.android.internal.util.Preconditions.checkNotNull; import android.annotation.NonNull; -import android.annotation.Nullable; import android.app.AppOpsManager; import android.content.Context; import android.content.pm.PackageManager; @@ -44,7 +43,6 @@ import android.net.IpSecTunnelInterfaceResponse; import android.net.IpSecUdpEncapResponse; import android.net.LinkAddress; import android.net.Network; -import android.net.NetworkStack; import android.net.NetworkUtils; import android.net.TrafficStats; import android.net.util.NetdService; @@ -77,8 +75,6 @@ import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.UnknownHostException; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; import java.util.List; /** @@ -179,14 +175,6 @@ public class IpSecService extends IIpSecService.Stub { void freeUnderlyingResources() throws RemoteException; } - /** - * Sentinel value placeholder for a real binder in RefcountedResources. - * - *
Used for cases where there the allocating party is a system service, and thus is expected
- * to track the resource lifecycles instead of IpSecService.
- */
- private static final Binder DUMMY_BINDER = new Binder();
-
/**
* RefcountedResource manages references and dependencies in an exclusively acyclic graph.
*
@@ -201,42 +189,24 @@ public class IpSecService extends IIpSecService.Stub {
*/
@VisibleForTesting
public class RefcountedResource This class ensures that while a NATT-keepalive is active, the UDP encap socket that it is
- * supporting will stay open until the NATT-keepalive is finished. NATT-keepalive offload
- * lifecycles will be managed by ConnectivityService, which will validate that the UDP Encap
- * socket is owned by the requester, and take a reference to it via this NattKeepaliveRecord
- *
- * It shall be the responsibility of the caller to ensure that instances of an EncapSocket do
- * not spawn multiple instances of NATT keepalives (and thereby register duplicate records)
- */
- private final class NattKeepaliveRecord extends OwnedResourceRecord {
- NattKeepaliveRecord(int resourceId) {
- super(resourceId);
- }
-
- @Override
- @GuardedBy("IpSecService.this")
- public void freeUnderlyingResources() {
- Log.d(TAG, "Natt Keepalive released: " + mResourceId);
-
- getResourceTracker().give();
- }
-
- @Override
- protected ResourceTracker getResourceTracker() {
- return getUserRecord().mNattKeepaliveQuotaTracker;
- }
-
- @Override
- public void invalidate() {
- getUserRecord().removeNattKeepaliveRecord(mResourceId);
- }
-
- @Override
- public String toString() {
- return new StringBuilder()
- .append("{super=")
- .append(super.toString())
- .append("}")
- .toString();
- }
- }
-
/**
* Constructs a new IpSecService instance
*
@@ -1369,7 +1277,7 @@ public class IpSecService extends IIpSecService.Stub {
public synchronized IpSecTunnelInterfaceResponse createTunnelInterface(
String localAddr, String remoteAddr, Network underlyingNetwork, IBinder binder,
String callingPackage) {
- enforceTunnelPermissions(callingPackage);
+ enforceTunnelFeatureAndPermissions(callingPackage);
checkNotNull(binder, "Null Binder passed to createTunnelInterface");
checkNotNull(underlyingNetwork, "No underlying network was specified");
checkInetAddress(localAddr);
@@ -1455,7 +1363,7 @@ public class IpSecService extends IIpSecService.Stub {
@Override
public synchronized void addAddressToTunnelInterface(
int tunnelResourceId, LinkAddress localAddr, String callingPackage) {
- enforceTunnelPermissions(callingPackage);
+ enforceTunnelFeatureAndPermissions(callingPackage);
UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
// Get tunnelInterface record; if no such interface is found, will throw
@@ -1484,7 +1392,7 @@ public class IpSecService extends IIpSecService.Stub {
@Override
public synchronized void removeAddressFromTunnelInterface(
int tunnelResourceId, LinkAddress localAddr, String callingPackage) {
- enforceTunnelPermissions(callingPackage);
+ enforceTunnelFeatureAndPermissions(callingPackage);
UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
// Get tunnelInterface record; if no such interface is found, will throw
@@ -1513,7 +1421,7 @@ public class IpSecService extends IIpSecService.Stub {
@Override
public synchronized void deleteTunnelInterface(
int resourceId, String callingPackage) throws RemoteException {
- enforceTunnelPermissions(callingPackage);
+ enforceTunnelFeatureAndPermissions(callingPackage);
UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
releaseResource(userRecord.mTunnelInterfaceRecords, resourceId);
}
@@ -1642,7 +1550,12 @@ public class IpSecService extends IIpSecService.Stub {
private static final String TUNNEL_OP = AppOpsManager.OPSTR_MANAGE_IPSEC_TUNNELS;
- private void enforceTunnelPermissions(String callingPackage) {
+ private void enforceTunnelFeatureAndPermissions(String callingPackage) {
+ if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_IPSEC_TUNNELS)) {
+ throw new UnsupportedOperationException(
+ "IPsec Tunnel Mode requires PackageManager.FEATURE_IPSEC_TUNNELS");
+ }
+
checkNotNull(callingPackage, "Null calling package cannot create IpSec tunnels");
switch (getAppOpsManager().noteOp(TUNNEL_OP, Binder.getCallingUid(), callingPackage)) {
case AppOpsManager.MODE_DEFAULT:
@@ -1714,7 +1627,7 @@ public class IpSecService extends IIpSecService.Stub {
IpSecConfig c, IBinder binder, String callingPackage) throws RemoteException {
checkNotNull(c);
if (c.getMode() == IpSecTransform.MODE_TUNNEL) {
- enforceTunnelPermissions(callingPackage);
+ enforceTunnelFeatureAndPermissions(callingPackage);
}
checkIpSecConfig(c);
checkNotNull(binder, "Null Binder passed to createTransform");
@@ -1822,7 +1735,7 @@ public class IpSecService extends IIpSecService.Stub {
public synchronized void applyTunnelModeTransform(
int tunnelResourceId, int direction,
int transformResourceId, String callingPackage) throws RemoteException {
- enforceTunnelPermissions(callingPackage);
+ enforceTunnelFeatureAndPermissions(callingPackage);
checkDirection(direction);
int callingUid = Binder.getCallingUid();
@@ -1911,57 +1824,6 @@ public class IpSecService extends IIpSecService.Stub {
}
}
- private void verifyNetworkStackCaller() {
- if (mContext.checkCallingOrSelfPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK)
- != PackageManager.PERMISSION_GRANTED
- && mContext.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_STACK)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException(
- "Requires permission NETWORK_STACK or MAINLINE_NETWORK_STACK");
- }
- }
-
- /**
- * Validates that a provided UID owns the encapSocket, and creates a NATT keepalive record
- *
- * For system server use only. Caller must have NETWORK_STACK permission
- *
- * @param encapSocketResourceId resource identifier of the encap socket record
- * @param ownerUid the UID of the caller. Used to verify ownership.
- * @return
- */
- public synchronized int lockEncapSocketForNattKeepalive(
- int encapSocketResourceId, int ownerUid) {
- verifyNetworkStackCaller();
-
- // Verify ownership. Will throw IllegalArgumentException if the UID specified does not
- // own the specified UDP encapsulation socket
- UserRecord userRecord = mUserResourceTracker.getUserRecord(ownerUid);
- RefcountedResource