Loading core/java/android/net/NetworkSpecifier.java +16 −0 Original line number Diff line number Diff line Loading @@ -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 } } services/core/java/com/android/server/ConnectivityService.java +17 −14 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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) { Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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); Loading @@ -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(), Loading tests/net/java/com/android/server/ConnectivityServiceTest.java +34 −0 Original line number Diff line number Diff line Loading @@ -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(); Loading wifi/java/android/net/wifi/aware/WifiAwareManager.java +5 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 */ Loading Loading @@ -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 { Loading wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java +27 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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 = Loading @@ -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 Loading @@ -164,6 +176,7 @@ public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements dest.writeByteArray(peerMac); dest.writeByteArray(pmk); dest.writeString(passphrase); dest.writeInt(requestorUid); } /** @hide */ Loading @@ -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; } Loading @@ -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 */ Loading @@ -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"); } } } Loading
core/java/android/net/NetworkSpecifier.java +16 −0 Original line number Diff line number Diff line Loading @@ -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 } }
services/core/java/com/android/server/ConnectivityService.java +17 −14 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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) { Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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); Loading @@ -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(), Loading
tests/net/java/com/android/server/ConnectivityServiceTest.java +34 −0 Original line number Diff line number Diff line Loading @@ -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(); Loading
wifi/java/android/net/wifi/aware/WifiAwareManager.java +5 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 */ Loading Loading @@ -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 { Loading
wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java +27 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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 = Loading @@ -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 Loading @@ -164,6 +176,7 @@ public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements dest.writeByteArray(peerMac); dest.writeByteArray(pmk); dest.writeString(passphrase); dest.writeInt(requestorUid); } /** @hide */ Loading @@ -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; } Loading @@ -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 */ Loading @@ -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"); } } }