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
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user