From e4259d3e5353475673f361828aca949a60f7e1d5 Mon Sep 17 00:00:00 2001 From: evitayan Date: Thu, 22 Mar 2018 17:53:08 -0700 Subject: [PATCH] Check to ensure UDP-encap is used only for IPv4 This commit checks if UDP-encapsulation is used for unsupported address family and throws IllegalArgumentException when it happens. Bug: 74213459 Test: Tests added in testCreateTransportModeTransformWithEncap and testCreateTunnelModeTransformWithEncap. Command: runtest frameworks-net Verified on taimen. Change-Id: I10c01f2bad6aca23430849ea9ef6c1eb157ae131 --- .../java/com/android/server/IpSecService.java | 35 ++++++++++++++ .../server/IpSecServiceParameterizedTest.java | 46 ++++++++++++++----- 2 files changed, 69 insertions(+), 12 deletions(-) diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java index a69d41683c29e..8c25917c74362 100644 --- a/services/core/java/com/android/server/IpSecService.java +++ b/services/core/java/com/android/server/IpSecService.java @@ -19,6 +19,8 @@ package com.android.server; import static android.Manifest.permission.DUMP; import static android.net.IpSecManager.INVALID_RESOURCE_ID; import static android.system.OsConstants.AF_INET; +import static android.system.OsConstants.AF_INET6; +import static android.system.OsConstants.AF_UNSPEC; import static android.system.OsConstants.EINVAL; import static android.system.OsConstants.IPPROTO_UDP; import static android.system.OsConstants.SOCK_DGRAM; @@ -63,6 +65,8 @@ import com.android.internal.util.Preconditions; import java.io.FileDescriptor; import java.io.IOException; import java.io.PrintWriter; +import java.net.Inet4Address; +import java.net.Inet6Address; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.UnknownHostException; @@ -1426,6 +1430,17 @@ public class IpSecService extends IIpSecService.Stub { + "or Encryption algorithms"); } + private int getFamily(String inetAddress) { + int family = AF_UNSPEC; + InetAddress checkAddress = NetworkUtils.numericToInetAddress(inetAddress); + if (checkAddress instanceof Inet4Address) { + family = AF_INET; + } else if (checkAddress instanceof Inet6Address) { + family = AF_INET6; + } + return family; + } + /** * Checks an IpSecConfig parcel to ensure that the contents are sane and throws an * IllegalArgumentException if they are not. @@ -1479,6 +1494,26 @@ public class IpSecService extends IIpSecService.Stub { // Require a valid source address for all transforms. checkInetAddress(config.getSourceAddress()); + // Check to ensure source and destination have the same address family. + String sourceAddress = config.getSourceAddress(); + String destinationAddress = config.getDestinationAddress(); + int sourceFamily = getFamily(sourceAddress); + int destinationFamily = getFamily(destinationAddress); + if (sourceFamily != destinationFamily) { + throw new IllegalArgumentException( + "Source address (" + + sourceAddress + + ") and destination address (" + + destinationAddress + + ") have different address families."); + } + + // Throw an error if UDP Encapsulation is not used in IPv4. + if (config.getEncapType() != IpSecTransform.ENCAP_NONE && sourceFamily != AF_INET) { + throw new IllegalArgumentException( + "UDP Encapsulation is not supported for this address family"); + } + switch (config.getMode()) { case IpSecTransform.MODE_TRANSPORT: break; diff --git a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java index 26985c1f0bfe2..9b919abfa41d5 100644 --- a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java +++ b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java @@ -16,6 +16,8 @@ package com.android.server; +import static android.system.OsConstants.AF_INET; +import static android.system.OsConstants.AF_INET6; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; @@ -64,16 +66,17 @@ public class IpSecServiceParameterizedTest { private static final int TEST_SPI = 0xD1201D; - private final String mDestinationAddr; private final String mSourceAddr; + private final String mDestinationAddr; private final LinkAddress mLocalInnerAddress; + private final int mFamily; @Parameterized.Parameters public static Collection ipSecConfigs() { return Arrays.asList( new Object[][] { - {"1.2.3.4", "8.8.4.4", "10.0.1.1/24"}, - {"2601::2", "2601::10", "2001:db8::1/64"} + {"1.2.3.4", "8.8.4.4", "10.0.1.1/24", AF_INET}, + {"2601::2", "2601::10", "2001:db8::1/64", AF_INET6} }); } @@ -134,10 +137,11 @@ public class IpSecServiceParameterizedTest { private static final int REMOTE_ENCAP_PORT = 4500; public IpSecServiceParameterizedTest( - String sourceAddr, String destAddr, String localInnerAddr) { + String sourceAddr, String destAddr, String localInnerAddr, int family) { mSourceAddr = sourceAddr; mDestinationAddr = destAddr; mLocalInnerAddress = new LinkAddress(localInnerAddr); + mFamily = family; } @Before @@ -340,11 +344,20 @@ public class IpSecServiceParameterizedTest { addAuthAndCryptToIpSecConfig(ipSecConfig); addEncapSocketToIpSecConfig(udpSock.resourceId, ipSecConfig); - IpSecTransformResponse createTransformResp = - mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage"); - assertEquals(IpSecManager.Status.OK, createTransformResp.status); + if (mFamily == AF_INET) { + IpSecTransformResponse createTransformResp = + mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage"); + assertEquals(IpSecManager.Status.OK, createTransformResp.status); - verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp, udpSock.port); + verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp, udpSock.port); + } else { + try { + IpSecTransformResponse createTransformResp = + mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage"); + fail("Expected IllegalArgumentException on attempt to use UDP Encap in IPv6"); + } catch (IllegalArgumentException expected) { + } + } } @Test @@ -357,11 +370,20 @@ public class IpSecServiceParameterizedTest { addAuthAndCryptToIpSecConfig(ipSecConfig); addEncapSocketToIpSecConfig(udpSock.resourceId, ipSecConfig); - IpSecTransformResponse createTransformResp = - mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage"); - assertEquals(IpSecManager.Status.OK, createTransformResp.status); + if (mFamily == AF_INET) { + IpSecTransformResponse createTransformResp = + mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage"); + assertEquals(IpSecManager.Status.OK, createTransformResp.status); - verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp, udpSock.port); + verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp, udpSock.port); + } else { + try { + IpSecTransformResponse createTransformResp = + mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage"); + fail("Expected IllegalArgumentException on attempt to use UDP Encap in IPv6"); + } catch (IllegalArgumentException expected) { + } + } } @Test