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

Commit e0347166 authored by Lorenzo Colitti's avatar Lorenzo Colitti Committed by Android (Google) Code Review
Browse files

Merge "Block address families with routes, not NetworkAgent side channel" into lmp-dev

parents ef686b3c 60446165
Loading
Loading
Loading
Loading
+2 −31
Original line number Original line Diff line number Diff line
@@ -106,20 +106,6 @@ public abstract class NetworkAgent extends Handler {
     */
     */
    public static final int EVENT_UID_RANGES_REMOVED = BASE + 6;
    public static final int EVENT_UID_RANGES_REMOVED = BASE + 6;


    /**
     * Sent by the NetworkAgent to ConnectivityService to block all routes for a certain address
     * family (AF_INET or AF_INET6) on this Network. For VPNs only.
     * obj = Integer representing the family (AF_INET or AF_INET6)
     */
    public static final int EVENT_BLOCK_ADDRESS_FAMILY = BASE + 7;

    /**
     * Sent by the NetworkAgent to ConnectivityService to unblock routes for a certain address
     * family (AF_INET or AF_INET6) on this Network. For VPNs only.
     * obj = Integer representing the family (AF_INET or AF_INET6)
     */
    public static final int EVENT_UNBLOCK_ADDRESS_FAMILY = BASE + 8;

    /**
    /**
     * Sent by ConnectivitySerice to the NetworkAgent to inform the agent of the
     * Sent by ConnectivitySerice to the NetworkAgent to inform the agent of the
     * networks status - whether we could use the network or could not, due to
     * networks status - whether we could use the network or could not, due to
@@ -127,7 +113,7 @@ public abstract class NetworkAgent extends Handler {
     *
     *
     * arg1 = either {@code VALID_NETWORK} or {@code INVALID_NETWORK}
     * arg1 = either {@code VALID_NETWORK} or {@code INVALID_NETWORK}
     */
     */
    public static final int CMD_REPORT_NETWORK_STATUS = BASE + 9;
    public static final int CMD_REPORT_NETWORK_STATUS = BASE + 7;


    public static final int VALID_NETWORK = 1;
    public static final int VALID_NETWORK = 1;
    public static final int INVALID_NETWORK = 2;
    public static final int INVALID_NETWORK = 2;
@@ -137,7 +123,7 @@ public abstract class NetworkAgent extends Handler {
     * explicitly selected.  This should be sent before the NetworkInfo is marked
     * explicitly selected.  This should be sent before the NetworkInfo is marked
     * CONNECTED so it can be given special treatment at that time.
     * CONNECTED so it can be given special treatment at that time.
     */
     */
    public static final int EVENT_SET_EXPLICITLY_SELECTED = BASE + 10;
    public static final int EVENT_SET_EXPLICITLY_SELECTED = BASE + 8;


    public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
    public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
            NetworkCapabilities nc, LinkProperties lp, int score) {
            NetworkCapabilities nc, LinkProperties lp, int score) {
@@ -272,21 +258,6 @@ public abstract class NetworkAgent extends Handler {
        queueOrSendMessage(EVENT_UID_RANGES_REMOVED, ranges);
        queueOrSendMessage(EVENT_UID_RANGES_REMOVED, ranges);
    }
    }


    /**
     * Called by the VPN code when it wants to block an address family from being routed, typically
     * because the VPN network doesn't support that family.
     */
    public void blockAddressFamily(int family) {
        queueOrSendMessage(EVENT_BLOCK_ADDRESS_FAMILY, family);
    }

    /**
     * Called by the VPN code when it wants to unblock an address family from being routed.
     */
    public void unblockAddressFamily(int family) {
        queueOrSendMessage(EVENT_UNBLOCK_ADDRESS_FAMILY, family);
    }

    /**
    /**
     * Called by the bearer to indicate this network was manually selected by the user.
     * Called by the bearer to indicate this network was manually selected by the user.
     * This should be called before the NetworkInfo is marked CONNECTED so that this
     * This should be called before the NetworkInfo is marked CONNECTED so that this
+0 −3
Original line number Original line Diff line number Diff line
@@ -410,7 +410,4 @@ interface INetworkManagementService


    void addInterfaceToLocalNetwork(String iface, in List<RouteInfo> routes);
    void addInterfaceToLocalNetwork(String iface, in List<RouteInfo> routes);
    void removeInterfaceFromLocalNetwork(String iface);
    void removeInterfaceFromLocalNetwork(String iface);

    void blockAddressFamily(int family, int netId, String iface);
    void unblockAddressFamily(int family, int netId, String iface);
}
}
+0 −30
Original line number Original line Diff line number Diff line
@@ -1884,36 +1884,6 @@ public class ConnectivityService extends IConnectivityManager.Stub {
                    }
                    }
                    break;
                    break;
                }
                }
                case NetworkAgent.EVENT_BLOCK_ADDRESS_FAMILY: {
                    NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
                    if (nai == null) {
                        loge("EVENT_BLOCK_ADDRESS_FAMILY from unknown NetworkAgent");
                        break;
                    }
                    try {
                        mNetd.blockAddressFamily((Integer) msg.obj, nai.network.netId,
                                nai.linkProperties.getInterfaceName());
                    } catch (Exception e) {
                        // Never crash!
                        loge("Exception in blockAddressFamily: " + e);
                    }
                    break;
                }
                case NetworkAgent.EVENT_UNBLOCK_ADDRESS_FAMILY: {
                    NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
                    if (nai == null) {
                        loge("EVENT_UNBLOCK_ADDRESS_FAMILY from unknown NetworkAgent");
                        break;
                    }
                    try {
                        mNetd.unblockAddressFamily((Integer) msg.obj, nai.network.netId,
                                nai.linkProperties.getInterfaceName());
                    } catch (Exception e) {
                        // Never crash!
                        loge("Exception in blockAddressFamily: " + e);
                    }
                    break;
                }
                case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: {
                case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: {
                    NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
                    NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
                    if (nai == null) {
                    if (nai == null) {
+0 −35
Original line number Original line Diff line number Diff line
@@ -28,8 +28,6 @@ import static android.net.TrafficStats.UID_TETHERING;
import static android.net.RouteInfo.RTN_THROW;
import static android.net.RouteInfo.RTN_THROW;
import static android.net.RouteInfo.RTN_UNICAST;
import static android.net.RouteInfo.RTN_UNICAST;
import static android.net.RouteInfo.RTN_UNREACHABLE;
import static android.net.RouteInfo.RTN_UNREACHABLE;
import static android.system.OsConstants.AF_INET;
import static android.system.OsConstants.AF_INET6;
import static com.android.server.NetworkManagementService.NetdResponseCode.ClatdStatusResult;
import static com.android.server.NetworkManagementService.NetdResponseCode.ClatdStatusResult;
import static com.android.server.NetworkManagementService.NetdResponseCode.InterfaceGetCfgResult;
import static com.android.server.NetworkManagementService.NetdResponseCode.InterfaceGetCfgResult;
import static com.android.server.NetworkManagementService.NetdResponseCode.InterfaceListResult;
import static com.android.server.NetworkManagementService.NetdResponseCode.InterfaceListResult;
@@ -2131,37 +2129,4 @@ public class NetworkManagementService extends INetworkManagementService.Stub
    public void removeInterfaceFromLocalNetwork(String iface) {
    public void removeInterfaceFromLocalNetwork(String iface) {
        modifyInterfaceInNetwork("remove", "local", iface);
        modifyInterfaceInNetwork("remove", "local", iface);
    }
    }

    @Override
    public void blockAddressFamily(int family, int netId, String iface) {
        modifyAddressFamily("add", family, netId, iface);
    }

    @Override
    public void unblockAddressFamily(int family, int netId, String iface) {
        modifyAddressFamily("remove", family, netId, iface);
    }

    // TODO: get rid of this and add RTN_UNREACHABLE routes instead.
    private void modifyAddressFamily(String action, int family, int netId, String iface) {
        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);

        final Command cmd = new Command("network", "route", action, netId, iface);

        if (family == AF_INET) {
            cmd.appendArg(Inet4Address.ANY.getHostAddress() + "/0");
        } else if (family == AF_INET6) {
            cmd.appendArg(Inet6Address.ANY.getHostAddress() + "/0");
        } else {
            throw new IllegalStateException(family + " is neither " + AF_INET + " nor " + AF_INET6);
        }

        cmd.appendArg("unreachable");

        try {
            mConnector.execute(cmd);
        } catch (NativeDaemonConnectorException e) {
            throw e.rethrowAsParcelableException();
        }
    }
}
}
+48 −54
Original line number Original line Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.connectivity;
import static android.Manifest.permission.BIND_VPN_SERVICE;
import static android.Manifest.permission.BIND_VPN_SERVICE;
import static android.os.UserHandle.PER_USER_RANGE;
import static android.os.UserHandle.PER_USER_RANGE;
import static android.net.RouteInfo.RTN_THROW;
import static android.net.RouteInfo.RTN_THROW;
import static android.net.RouteInfo.RTN_UNREACHABLE;
import static android.system.OsConstants.AF_INET;
import static android.system.OsConstants.AF_INET;
import static android.system.OsConstants.AF_INET6;
import static android.system.OsConstants.AF_INET6;


@@ -107,8 +108,6 @@ public class Vpn {
    private String mPackage;
    private String mPackage;
    private int mOwnerUID;
    private int mOwnerUID;
    private String mInterface;
    private String mInterface;
    private boolean mAllowIPv4;
    private boolean mAllowIPv6;
    private Connection mConnection;
    private Connection mConnection;
    private LegacyVpnRunner mLegacyVpnRunner;
    private LegacyVpnRunner mLegacyVpnRunner;
    private PendingIntent mStatusIntent;
    private PendingIntent mStatusIntent;
@@ -344,31 +343,45 @@ public class Vpn {
        return mNetworkInfo;
        return mNetworkInfo;
    }
    }


    private void agentConnect() {
    private LinkProperties makeLinkProperties() {
        boolean allowIPv4 = mConfig.allowIPv4;
        boolean allowIPv6 = mConfig.allowIPv6;

        LinkProperties lp = new LinkProperties();
        LinkProperties lp = new LinkProperties();

        lp.setInterfaceName(mInterface);
        lp.setInterfaceName(mInterface);


        boolean hasDefaultRoute = false;
        if (mConfig.addresses != null) {
            for (LinkAddress address : mConfig.addresses) {
                lp.addLinkAddress(address);
                allowIPv4 |= address.getAddress() instanceof Inet4Address;
                allowIPv6 |= address.getAddress() instanceof Inet6Address;
            }
        }

        if (mConfig.routes != null) {
            for (RouteInfo route : mConfig.routes) {
            for (RouteInfo route : mConfig.routes) {
                lp.addRoute(route);
                lp.addRoute(route);
            if (route.isDefaultRoute()) hasDefaultRoute = true;
                InetAddress address = route.getDestination().getAddress();
                allowIPv4 |= address instanceof Inet4Address;
                allowIPv6 |= address instanceof Inet6Address;
            }
            }
        if (hasDefaultRoute) {
            mNetworkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
        } else {
            mNetworkCapabilities.removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
        }
        }


        if (mConfig.dnsServers != null) {
        if (mConfig.dnsServers != null) {
            for (String dnsServer : mConfig.dnsServers) {
            for (String dnsServer : mConfig.dnsServers) {
                InetAddress address = InetAddress.parseNumericAddress(dnsServer);
                InetAddress address = InetAddress.parseNumericAddress(dnsServer);
                lp.addDnsServer(address);
                lp.addDnsServer(address);
                if (address instanceof Inet4Address) {
                allowIPv4 |= address instanceof Inet4Address;
                    mAllowIPv4 = true;
                allowIPv6 |= address instanceof Inet6Address;
                } else {
            }
                    mAllowIPv6 = true;
        }
        }

        if (!allowIPv4) {
            lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), RTN_UNREACHABLE));
        }
        }
        if (!allowIPv6) {
            lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE));
        }
        }


        // Concatenate search domains into a string.
        // Concatenate search domains into a string.
@@ -380,6 +393,20 @@ public class Vpn {
        }
        }
        lp.setDomains(buffer.toString().trim());
        lp.setDomains(buffer.toString().trim());


        // TODO: Stop setting the MTU in jniCreate and set it here.

        return lp;
    }

    private void agentConnect() {
        LinkProperties lp = makeLinkProperties();

        if (lp.hasIPv4DefaultRoute() || lp.hasIPv6DefaultRoute()) {
            mNetworkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
        } else {
            mNetworkCapabilities.removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
        }

        mNetworkInfo.setIsAvailable(true);
        mNetworkInfo.setIsAvailable(true);
        mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, null);
        mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, null);


@@ -399,13 +426,6 @@ public class Vpn {
            Binder.restoreCallingIdentity(token);
            Binder.restoreCallingIdentity(token);
        }
        }


        if (!mAllowIPv4) {
            mNetworkAgent.blockAddressFamily(AF_INET);
        }
        if (!mAllowIPv6) {
            mNetworkAgent.blockAddressFamily(AF_INET6);
        }

        addVpnUserLocked(mUserHandle);
        addVpnUserLocked(mUserHandle);
        // If we are owner assign all Restricted Users to this VPN
        // If we are owner assign all Restricted Users to this VPN
        if (mUserHandle == UserHandle.USER_OWNER) {
        if (mUserHandle == UserHandle.USER_OWNER) {
@@ -491,8 +511,6 @@ public class Vpn {
        NetworkAgent oldNetworkAgent = mNetworkAgent;
        NetworkAgent oldNetworkAgent = mNetworkAgent;
        mNetworkAgent = null;
        mNetworkAgent = null;
        List<UidRange> oldUsers = mVpnUsers;
        List<UidRange> oldUsers = mVpnUsers;
        boolean oldAllowIPv4 = mAllowIPv4;
        boolean oldAllowIPv6 = mAllowIPv6;


        // Configure the interface. Abort if any of these steps fails.
        // Configure the interface. Abort if any of these steps fails.
        ParcelFileDescriptor tun = ParcelFileDescriptor.adoptFd(jniCreate(config.mtu));
        ParcelFileDescriptor tun = ParcelFileDescriptor.adoptFd(jniCreate(config.mtu));
@@ -525,8 +543,6 @@ public class Vpn {


            // Set up forwarding and DNS rules.
            // Set up forwarding and DNS rules.
            mVpnUsers = new ArrayList<UidRange>();
            mVpnUsers = new ArrayList<UidRange>();
            mAllowIPv4 = mConfig.allowIPv4;
            mAllowIPv6 = mConfig.allowIPv6;


            agentConnect();
            agentConnect();


@@ -556,8 +572,6 @@ public class Vpn {
            mVpnUsers = oldUsers;
            mVpnUsers = oldUsers;
            mNetworkAgent = oldNetworkAgent;
            mNetworkAgent = oldNetworkAgent;
            mInterface = oldInterface;
            mInterface = oldInterface;
            mAllowIPv4 = oldAllowIPv4;
            mAllowIPv6 = oldAllowIPv6;
            throw e;
            throw e;
        }
        }
        Log.i(TAG, "Established by " + config.user + " on " + mInterface);
        Log.i(TAG, "Established by " + config.user + " on " + mInterface);
@@ -780,25 +794,9 @@ public class Vpn {
            return false;
            return false;
        }
        }
        boolean success = jniAddAddress(mInterface, address, prefixLength);
        boolean success = jniAddAddress(mInterface, address, prefixLength);
        if (success && (!mAllowIPv4 || !mAllowIPv6)) {
        if (mNetworkAgent != null) {
            try {
            mNetworkAgent.sendLinkProperties(makeLinkProperties());
                InetAddress inetAddress = InetAddress.parseNumericAddress(address);
                if ((inetAddress instanceof Inet4Address) && !mAllowIPv4) {
                    mAllowIPv4 = true;
                    mNetworkAgent.unblockAddressFamily(AF_INET);
                } else if ((inetAddress instanceof Inet6Address) && !mAllowIPv6) {
                    mAllowIPv6 = true;
                    mNetworkAgent.unblockAddressFamily(AF_INET6);
                }
            } catch (IllegalArgumentException e) {
                // ignore
            }
        }
        }
        // Ideally, we'd call mNetworkAgent.sendLinkProperties() here to notify ConnectivityService
        // that the LinkAddress has changed. But we don't do so for two reasons: (1) We don't set
        // LinkAddresses on the LinkProperties we establish in the first place (see agentConnect())
        // and (2) CS doesn't do anything with LinkAddresses anyway (see updateLinkProperties()).
        // TODO: Maybe fix this.
        return success;
        return success;
    }
    }


@@ -807,11 +805,9 @@ public class Vpn {
            return false;
            return false;
        }
        }
        boolean success = jniDelAddress(mInterface, address, prefixLength);
        boolean success = jniDelAddress(mInterface, address, prefixLength);
        // Ideally, we'd call mNetworkAgent.sendLinkProperties() here to notify ConnectivityService
        if (mNetworkAgent != null) {
        // that the LinkAddress has changed. But we don't do so for two reasons: (1) We don't set
            mNetworkAgent.sendLinkProperties(makeLinkProperties());
        // LinkAddresses on the LinkProperties we establish in the first place (see agentConnect())
        }
        // and (2) CS doesn't do anything with LinkAddresses anyway (see updateLinkProperties()).
        // TODO: Maybe fix this.
        return success;
        return success;
    }
    }


@@ -1284,8 +1280,6 @@ public class Vpn {
                    // Now INetworkManagementEventObserver is watching our back.
                    // Now INetworkManagementEventObserver is watching our back.
                    mInterface = mConfig.interfaze;
                    mInterface = mConfig.interfaze;
                    mVpnUsers = new ArrayList<UidRange>();
                    mVpnUsers = new ArrayList<UidRange>();
                    mAllowIPv4 = mConfig.allowIPv4;
                    mAllowIPv6 = mConfig.allowIPv6;


                    agentConnect();
                    agentConnect();