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

Commit 2fd19ffa authored by Etan Cohen's avatar Etan Cohen Committed by Gerrit Code Review
Browse files

Merge "[AWARE] Add UID checking to WifiAwareNetworkSpecifier"

parents 7d4a354f 859748f0
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -33,4 +33,20 @@ public abstract class NetworkSpecifier {
     * @hide
     */
    public abstract boolean satisfiedBy(NetworkSpecifier other);

    /**
     * Optional method which can be overriden by concrete implementations of NetworkSpecifier to
     * check a self-reported UID. A concrete implementation may contain a UID which would be self-
     * reported by the caller (since NetworkSpecifier implementations should be non-mutable). This
     * function is called by ConnectivityService and is passed the actual UID of the caller -
     * allowing the verification of the self-reported UID. In cases of mismatch the implementation
     * should throw a SecurityException.
     *
     * @param requestorUid The UID of the requestor as obtained from its binder.
     *
     * @hide
     */
    public void assertValidFromUid(int requestorUid) {
        // empty
    }
}
+17 −14
Original line number Diff line number Diff line
@@ -49,7 +49,6 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.PacketKeepalive;
@@ -70,6 +69,7 @@ import android.net.NetworkInfo.DetailedState;
import android.net.NetworkMisc;
import android.net.NetworkQuotaInfo;
import android.net.NetworkRequest;
import android.net.NetworkSpecifier;
import android.net.NetworkState;
import android.net.NetworkUtils;
import android.net.Proxy;
@@ -110,7 +110,6 @@ import android.util.ArraySet;
import android.util.LocalLog;
import android.util.LocalLog.ReadOnlyLocalLog;
import android.util.Log;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
@@ -4131,6 +4130,18 @@ public class ConnectivityService extends IConnectivityManager.Stub
                0, 0, thresholds);
    }

    private void ensureValidNetworkSpecifier(NetworkCapabilities nc) {
        if (nc == null) {
            return;
        }
        NetworkSpecifier ns = nc.getNetworkSpecifier();
        if (ns == null) {
            return;
        }
        MatchAllNetworkSpecifier.checkNotMatchAllNetworkSpecifier(ns);
        ns.assertValidFromUid(Binder.getCallingUid());
    }

    @Override
    public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities,
            Messenger messenger, int timeoutMs, IBinder binder, int legacyType) {
@@ -4156,9 +4167,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
        if (timeoutMs < 0) {
            throw new IllegalArgumentException("Bad timeout specified");
        }

        MatchAllNetworkSpecifier.checkNotMatchAllNetworkSpecifier(
                networkCapabilities.getNetworkSpecifier());
        ensureValidNetworkSpecifier(networkCapabilities);

        NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, legacyType,
                nextNetworkRequestId(), type);
@@ -4230,9 +4239,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
        enforceNetworkRequestPermissions(networkCapabilities);
        enforceMeteredApnPolicy(networkCapabilities);
        ensureRequestableCapabilities(networkCapabilities);

        MatchAllNetworkSpecifier.checkNotMatchAllNetworkSpecifier(
                networkCapabilities.getNetworkSpecifier());
        ensureValidNetworkSpecifier(networkCapabilities);

        NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE,
                nextNetworkRequestId(), NetworkRequest.Type.REQUEST);
@@ -4294,9 +4301,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
            // can't request networks.
            nc.addCapability(NET_CAPABILITY_FOREGROUND);
        }

        MatchAllNetworkSpecifier.checkNotMatchAllNetworkSpecifier(
                networkCapabilities.getNetworkSpecifier());
        ensureValidNetworkSpecifier(networkCapabilities);

        NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(),
                NetworkRequest.Type.LISTEN);
@@ -4314,9 +4319,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
        if (!hasWifiNetworkListenPermission(networkCapabilities)) {
            enforceAccessPermission();
        }

        MatchAllNetworkSpecifier.checkNotMatchAllNetworkSpecifier(
                networkCapabilities.getNetworkSpecifier());
        ensureValidNetworkSpecifier(networkCapabilities);

        NetworkRequest networkRequest = new NetworkRequest(
                new NetworkCapabilities(networkCapabilities), TYPE_NONE, nextNetworkRequestId(),
+34 −0
Original line number Diff line number Diff line
@@ -1992,6 +1992,40 @@ public class ConnectivityServiceTest extends AndroidTestCase {
        }
    }

    @SmallTest
    public void testNetworkSpecifierUidSpoofSecurityException() {
        class UidAwareNetworkSpecifier extends NetworkSpecifier implements Parcelable {
            @Override
            public boolean satisfiedBy(NetworkSpecifier other) {
                return true;
            }

            @Override
            public void assertValidFromUid(int requestorUid) {
                throw new SecurityException("failure");
            }

            @Override
            public int describeContents() { return 0; }
            @Override
            public void writeToParcel(Parcel dest, int flags) {}
        }

        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
        mWiFiNetworkAgent.connect(false);

        UidAwareNetworkSpecifier networkSpecifier = new UidAwareNetworkSpecifier();
        NetworkRequest networkRequest = newWifiRequestBuilder().setNetworkSpecifier(
                networkSpecifier).build();
        TestNetworkCallback networkCallback = new TestNetworkCallback();
        try {
            mCm.requestNetwork(networkRequest, networkCallback);
            fail("Network request with spoofed UID did not throw a SecurityException");
        } catch (SecurityException e) {
            // expected
        }
    }

    @SmallTest
    public void testRegisterDefaultNetworkCallback() throws Exception {
        final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback();
+5 −2
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
import android.util.Log;
import android.util.SparseArray;
@@ -453,7 +454,8 @@ public class WifiAwareManager {
                peerHandle != null ? peerHandle.peerId : 0, // 0 is an invalid peer ID
                null, // peerMac (not used in this method)
                pmk,
                passphrase);
                passphrase,
                Process.myUid());
    }

    /** @hide */
@@ -490,7 +492,8 @@ public class WifiAwareManager {
                0, // 0 is an invalid peer ID
                peer,
                pmk,
                passphrase);
                passphrase,
                Process.myUid());
    }

    private static class WifiAwareEventCallbackProxy extends IWifiAwareEventCallback.Stub {
+27 −3
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.net.wifi.aware;
import android.net.NetworkSpecifier;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;

import java.util.Arrays;
import java.util.Objects;
@@ -115,9 +116,18 @@ public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements
     */
    public final String passphrase;

    /**
     * The UID of the process initializing this network specifier. Validated by receiver using
     * checkUidIfNecessary() and is used by satisfiedBy() to determine whether matches the
     * offered network.
     *
     * @hide
     */
    public final int requestorUid;

    /** @hide */
    public WifiAwareNetworkSpecifier(int type, int role, int clientId, int sessionId, int peerId,
            byte[] peerMac, byte[] pmk, String passphrase) {
            byte[] peerMac, byte[] pmk, String passphrase, int requestorUid) {
        this.type = type;
        this.role = role;
        this.clientId = clientId;
@@ -126,6 +136,7 @@ public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements
        this.peerMac = peerMac;
        this.pmk = pmk;
        this.passphrase = passphrase;
        this.requestorUid = requestorUid;
    }

    public static final Creator<WifiAwareNetworkSpecifier> CREATOR =
@@ -140,7 +151,8 @@ public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements
                        in.readInt(), // peerId
                        in.createByteArray(), // peerMac
                        in.createByteArray(), // pmk
                        in.readString()); // passphrase
                        in.readString(), // passphrase
                        in.readInt()); // requestorUid
                }

                @Override
@@ -164,6 +176,7 @@ public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements
        dest.writeByteArray(peerMac);
        dest.writeByteArray(pmk);
        dest.writeString(passphrase);
        dest.writeInt(requestorUid);
    }

    /** @hide */
@@ -186,6 +199,7 @@ public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements
        result = 31 * result + Arrays.hashCode(peerMac);
        result = 31 * result + Arrays.hashCode(pmk);
        result = 31 * result + Objects.hashCode(passphrase);
        result = 31 * result + requestorUid;

        return result;
    }
@@ -210,7 +224,8 @@ public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements
                && peerId == lhs.peerId
                && Arrays.equals(peerMac, lhs.peerMac)
                && Arrays.equals(pmk, lhs.pmk)
                && Objects.equals(passphrase, lhs.passphrase);
                && Objects.equals(passphrase, lhs.passphrase)
                && requestorUid == lhs.requestorUid;
    }

    /** @hide */
@@ -228,7 +243,16 @@ public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements
                .append(", pmk=").append((pmk == null) ? "<null>" : "<non-null>")
                // masking PII
                .append(", passphrase=").append((passphrase == null) ? "<null>" : "<non-null>")
                .append(", requestorUid=").append(requestorUid)
                .append("]");
        return sb.toString();
    }

    /** @hide */
    @Override
    public void assertValidFromUid(int requestorUid) {
        if (this.requestorUid != requestorUid) {
            throw new SecurityException("mismatched UIDs");
        }
    }
}