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

Commit 48547ce1 authored by Jeffrey Vander Stoep's avatar Jeffrey Vander Stoep Committed by android-build-merger
Browse files

Merge "Fix FD leak in ConnectivityManager.getConnectionOwnerUid" am: 20bdc266

am: 0b6d9747

Change-Id: I5d3b329018a1f640f086887ec222c5cf7e2975b4
parents 7adcb62d 0b6d9747
Loading
Loading
Loading
Loading
+16 −11
Original line number Diff line number Diff line
@@ -16,26 +16,23 @@

package android.net.netlink;

import static android.os.Process.INVALID_UID;
import static android.net.netlink.NetlinkConstants.SOCK_DIAG_BY_FAMILY;
import static android.net.netlink.NetlinkSocket.DEFAULT_RECV_BUFSIZE;
import static android.net.netlink.StructNlMsgHdr.NLM_F_DUMP;
import static android.net.netlink.StructNlMsgHdr.NLM_F_REQUEST;
import static android.os.Process.INVALID_UID;
import static android.system.OsConstants.AF_INET;
import static android.system.OsConstants.AF_INET6;
import static android.system.OsConstants.IPPROTO_UDP;
import static android.system.OsConstants.NETLINK_INET_DIAG;

import android.os.Build;
import android.os.Process;
import android.net.util.SocketUtils;
import android.system.ErrnoException;
import android.util.Log;

import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.DatagramSocket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetSocketAddress;
@@ -163,17 +160,25 @@ public class InetDiagMessage extends NetlinkMessage {
     */
    public static int getConnectionOwnerUid(int protocol, InetSocketAddress local,
                                            InetSocketAddress remote) {
        int uid = INVALID_UID;
        FileDescriptor fd = null;
        try {
            final FileDescriptor fd = NetlinkSocket.forProto(NETLINK_INET_DIAG);
            fd = NetlinkSocket.forProto(NETLINK_INET_DIAG);
            NetlinkSocket.connectToKernel(fd);

            return lookupUid(protocol, local, remote, fd);

            uid = lookupUid(protocol, local, remote, fd);
        } catch (ErrnoException | SocketException | IllegalArgumentException
                | InterruptedIOException e) {
            Log.e(TAG, e.toString());
        } finally {
            if (fd != null) {
                try {
                    SocketUtils.closeSocket(fd);
                } catch (IOException e) {
                    Log.e(TAG, e.toString());
                }
        return INVALID_UID;
            }
        }
        return uid;
    }

    @Override
+21 −14
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package android.net.netlink;

import static android.net.netlink.StructNlMsgHdr.NLM_F_DUMP;
import static android.net.netlink.StructNlMsgHdr.NLM_F_REQUEST;
import static android.os.Process.INVALID_UID;
import static android.system.OsConstants.AF_INET;
import static android.system.OsConstants.AF_INET6;
import static android.system.OsConstants.IPPROTO_TCP;
@@ -28,6 +27,7 @@ import static android.system.OsConstants.SOCK_STREAM;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

@@ -45,7 +45,6 @@ import androidx.test.runner.AndroidJUnit4;
import libcore.util.HexEncoding;

import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;

@@ -152,9 +151,13 @@ public class InetDiagSocketTest {

    private void checkConnectionOwnerUid(int protocol, InetSocketAddress local,
                                         InetSocketAddress remote, boolean expectSuccess) {
        final int expectedUid = expectSuccess ? Process.myUid() : INVALID_UID;
        final int uid = mCm.getConnectionOwnerUid(protocol, local, remote);
        assertEquals(expectedUid, uid);

        if (expectSuccess) {
            assertEquals(Process.myUid(), uid);
        } else {
            assertNotEquals(Process.myUid(), uid);
        }
    }

    private int findLikelyFreeUdpPort(UdpConnection conn) throws Exception {
@@ -165,11 +168,11 @@ public class InetDiagSocketTest {
        return localPort;
    }

    public void checkGetConnectionOwnerUid(String to, String from) throws Exception {
    /**
         * For TCP connections, create a test connection and verify that this
     * Create a test connection for UDP and TCP sockets and verify that this
     * {protocol, local, remote} socket result in receiving a valid UID.
     */
    public void checkGetConnectionOwnerUid(String to, String from) throws Exception {
        TcpConnection tcp = new TcpConnection(to, from);
        checkConnectionOwnerUid(tcp.protocol, tcp.local, tcp.remote, true);
        checkConnectionOwnerUid(IPPROTO_UDP, tcp.local, tcp.remote, false);
@@ -177,20 +180,14 @@ public class InetDiagSocketTest {
        checkConnectionOwnerUid(tcp.protocol, tcp.local, new InetSocketAddress(0), false);
        tcp.close();

        /**
         * For UDP connections, either a complete match {protocol, local, remote} or a
         * partial match {protocol, local} should return a valid UID.
         */
        UdpConnection udp = new UdpConnection(to,from);
        checkConnectionOwnerUid(udp.protocol, udp.local, udp.remote, true);
        checkConnectionOwnerUid(udp.protocol, udp.local, new InetSocketAddress(0), true);
        checkConnectionOwnerUid(IPPROTO_TCP, udp.local, udp.remote, false);
        checkConnectionOwnerUid(udp.protocol, new InetSocketAddress(findLikelyFreeUdpPort(udp)),
                udp.remote, false);
        udp.close();
    }

    @Ignore
    @Test
    public void testGetConnectionOwnerUid() throws Exception {
        checkGetConnectionOwnerUid("::", null);
@@ -203,6 +200,16 @@ public class InetDiagSocketTest {
        checkGetConnectionOwnerUid("::1", "::1");
    }

    /* Verify fix for b/141603906 */
    @Test
    public void testB141603906() throws Exception {
        final InetSocketAddress src = new InetSocketAddress(0);
        final InetSocketAddress dst = new InetSocketAddress(0);
        for (int i = 1; i <= 100000; i++) {
            mCm.getConnectionOwnerUid(IPPROTO_TCP, src, dst);
        }
    }

    // Hexadecimal representation of InetDiagReqV2 request.
    private static final String INET_DIAG_REQ_V2_UDP_INET4_HEX =
            // struct nlmsghdr