Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e4259d3e authored by evitayan's avatar evitayan
Browse files

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
parent 0a7d3e34
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -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;
+36 −14
Original line number Diff line number Diff line
@@ -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);

        if (mFamily == AF_INET) {
            IpSecTransformResponse createTransformResp =
                    mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
            assertEquals(IpSecManager.Status.OK, createTransformResp.status);

            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);

        if (mFamily == AF_INET) {
            IpSecTransformResponse createTransformResp =
                    mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
            assertEquals(IpSecManager.Status.OK, createTransformResp.status);

            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