diff options
| author | 2020-03-25 05:50:51 +0000 | |
|---|---|---|
| committer | 2020-03-25 06:14:13 +0000 | |
| commit | d78ad3d41adf27fa71bfa4c4927bd12d966af85a (patch) | |
| tree | 830b0beefd29f7df0257cecfc4ea87fee4f8d21f | |
| parent | a37692088f54f2142350a50b67dea256020128df (diff) | |
Automatically set IPsec tunnel interface as up
This change makes IPsec tunnel interfaces automatically get brought up
once they are created. Originally this was considered to be an
additional safety check, as they would not be start routing traffic
until explicitly brought up. However, in the intervening time, the
NetworkManagementController now requires the NETWORK_STACK permission to
set an interface as up. Additionally, that call is a hidden API, and
thus not usable for use cases such as IWLAN.
Bug: 149348618
Test: FrameworksNetTests, CtsNetTestCases passing.
Change-Id: I55b63a748463a388e1e2991d2d5d6b3023545e60
Merged-In: I55b63a748463a388e1e2991d2d5d6b3023545e60
(cherry picked from commit 7c5704d177a903034ae1b6ae4800cc3b8457977a)
5 files changed, 35 insertions, 14 deletions
diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java index 599485b11c72..905c489e1dcb 100644 --- a/services/core/java/com/android/server/IpSecService.java +++ b/services/core/java/com/android/server/IpSecService.java @@ -46,6 +46,7 @@ import android.net.TrafficStats; import android.net.util.NetdService; import android.os.Binder; import android.os.IBinder; +import android.os.INetworkManagementService; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.os.ServiceSpecificException; @@ -114,6 +115,9 @@ public class IpSecService extends IIpSecService.Stub { /* Binder context for this service */ private final Context mContext; + /* NetworkManager instance */ + private final INetworkManagementService mNetworkManager; + /** * The next non-repeating global ID for tracking resources between users, this service, and * kernel data structures. Accessing this variable is not thread safe, so it is only read or @@ -992,12 +996,13 @@ public class IpSecService extends IIpSecService.Stub { * * @param context Binder context for this service */ - private IpSecService(Context context) { - this(context, IpSecServiceConfiguration.GETSRVINSTANCE); + private IpSecService(Context context, INetworkManagementService networkManager) { + this(context, networkManager, IpSecServiceConfiguration.GETSRVINSTANCE); } - static IpSecService create(Context context) throws InterruptedException { - final IpSecService service = new IpSecService(context); + static IpSecService create(Context context, INetworkManagementService networkManager) + throws InterruptedException { + final IpSecService service = new IpSecService(context, networkManager); service.connectNativeNetdService(); return service; } @@ -1011,9 +1016,11 @@ public class IpSecService extends IIpSecService.Stub { /** @hide */ @VisibleForTesting - public IpSecService(Context context, IpSecServiceConfiguration config) { + public IpSecService(Context context, INetworkManagementService networkManager, + IpSecServiceConfiguration config) { this( context, + networkManager, config, (fd, uid) -> { try { @@ -1027,9 +1034,10 @@ public class IpSecService extends IIpSecService.Stub { /** @hide */ @VisibleForTesting - public IpSecService( - Context context, IpSecServiceConfiguration config, UidFdTagger uidFdTagger) { + public IpSecService(Context context, INetworkManagementService networkManager, + IpSecServiceConfiguration config, UidFdTagger uidFdTagger) { mContext = context; + mNetworkManager = Objects.requireNonNull(networkManager); mSrvConfig = config; mUidFdTagger = uidFdTagger; } @@ -1308,6 +1316,10 @@ public class IpSecService extends IIpSecService.Stub { final INetd netd = mSrvConfig.getNetdInstance(); netd.ipSecAddTunnelInterface(intfName, localAddr, remoteAddr, ikey, okey, resourceId); + Binder.withCleanCallingIdentity(() -> { + mNetworkManager.setInterfaceUp(intfName); + }); + for (int selAddrFamily : ADDRESS_FAMILIES) { // Always send down correct local/remote addresses for template. netd.ipSecAddSecurityPolicy( diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index b019e9dd03ba..adbe6df4f028 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -1413,7 +1413,7 @@ public final class SystemServer { t.traceBegin("StartIpSecService"); try { - ipSecService = IpSecService.create(context); + ipSecService = IpSecService.create(context, networkManagement); ServiceManager.addService(Context.IPSEC_SERVICE, ipSecService); } catch (Throwable e) { reportWtf("starting IpSec Service", e); diff --git a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java index 71b72b84de81..23098ec067d2 100644 --- a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java +++ b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java @@ -46,6 +46,7 @@ import android.net.LinkAddress; import android.net.Network; import android.net.NetworkUtils; import android.os.Binder; +import android.os.INetworkManagementService; import android.os.ParcelFileDescriptor; import android.system.Os; import android.test.mock.MockContext; @@ -135,6 +136,7 @@ public class IpSecServiceParameterizedTest { }; INetd mMockNetd; + INetworkManagementService mNetworkManager; PackageManager mMockPkgMgr; IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig; IpSecService mIpSecService; @@ -160,9 +162,10 @@ public class IpSecServiceParameterizedTest { @Before public void setUp() throws Exception { mMockNetd = mock(INetd.class); + mNetworkManager = mock(INetworkManagementService.class); mMockPkgMgr = mock(PackageManager.class); mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class); - mIpSecService = new IpSecService(mMockContext, mMockIpSecSrvConfig); + mIpSecService = new IpSecService(mMockContext, mNetworkManager, mMockIpSecSrvConfig); // Injecting mock netd when(mMockIpSecSrvConfig.getNetdInstance()).thenReturn(mMockNetd); @@ -609,6 +612,7 @@ public class IpSecServiceParameterizedTest { anyInt(), anyInt(), anyInt()); + verify(mNetworkManager).setInterfaceUp(createTunnelResp.interfaceName); } @Test diff --git a/tests/net/java/com/android/server/IpSecServiceRefcountedResourceTest.java b/tests/net/java/com/android/server/IpSecServiceRefcountedResourceTest.java index 22a2c94fc194..788e4efe097e 100644 --- a/tests/net/java/com/android/server/IpSecServiceRefcountedResourceTest.java +++ b/tests/net/java/com/android/server/IpSecServiceRefcountedResourceTest.java @@ -31,6 +31,7 @@ import static org.mockito.Mockito.verify; import android.content.Context; import android.os.Binder; import android.os.IBinder; +import android.os.INetworkManagementService; import android.os.RemoteException; import androidx.test.filters.SmallTest; @@ -61,7 +62,8 @@ public class IpSecServiceRefcountedResourceTest { public void setUp() throws Exception { mMockContext = mock(Context.class); mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class); - mIpSecService = new IpSecService(mMockContext, mMockIpSecSrvConfig); + mIpSecService = new IpSecService( + mMockContext, mock(INetworkManagementService.class), mMockIpSecSrvConfig); } private void assertResourceState( diff --git a/tests/net/java/com/android/server/IpSecServiceTest.java b/tests/net/java/com/android/server/IpSecServiceTest.java index 4a35015044ff..536e98327e1f 100644 --- a/tests/net/java/com/android/server/IpSecServiceTest.java +++ b/tests/net/java/com/android/server/IpSecServiceTest.java @@ -42,6 +42,7 @@ import android.net.IpSecManager; import android.net.IpSecSpiResponse; import android.net.IpSecUdpEncapResponse; import android.os.Binder; +import android.os.INetworkManagementService; import android.os.ParcelFileDescriptor; import android.os.Process; import android.system.ErrnoException; @@ -115,6 +116,7 @@ public class IpSecServiceTest { } Context mMockContext; + INetworkManagementService mMockNetworkManager; INetd mMockNetd; IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig; IpSecService mIpSecService; @@ -122,9 +124,10 @@ public class IpSecServiceTest { @Before public void setUp() throws Exception { mMockContext = mock(Context.class); + mMockNetworkManager = mock(INetworkManagementService.class); mMockNetd = mock(INetd.class); mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class); - mIpSecService = new IpSecService(mMockContext, mMockIpSecSrvConfig); + mIpSecService = new IpSecService(mMockContext, mMockNetworkManager, mMockIpSecSrvConfig); // Injecting mock netd when(mMockIpSecSrvConfig.getNetdInstance()).thenReturn(mMockNetd); @@ -132,7 +135,7 @@ public class IpSecServiceTest { @Test public void testIpSecServiceCreate() throws InterruptedException { - IpSecService ipSecSrv = IpSecService.create(mMockContext); + IpSecService ipSecSrv = IpSecService.create(mMockContext, mMockNetworkManager); assertNotNull(ipSecSrv); } @@ -604,8 +607,8 @@ public class IpSecServiceTest { @Test public void testOpenUdpEncapSocketTagsSocket() throws Exception { IpSecService.UidFdTagger mockTagger = mock(IpSecService.UidFdTagger.class); - IpSecService testIpSecService = - new IpSecService(mMockContext, mMockIpSecSrvConfig, mockTagger); + IpSecService testIpSecService = new IpSecService( + mMockContext, mMockNetworkManager, mMockIpSecSrvConfig, mockTagger); IpSecUdpEncapResponse udpEncapResp = testIpSecService.openUdpEncapsulationSocket(0, new Binder()); |