summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/net/NetworkSpecifier.java16
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java31
-rw-r--r--tests/net/java/com/android/server/ConnectivityServiceTest.java34
-rw-r--r--wifi/java/android/net/wifi/aware/WifiAwareManager.java7
-rw-r--r--wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java30
5 files changed, 99 insertions, 19 deletions
diff --git a/core/java/android/net/NetworkSpecifier.java b/core/java/android/net/NetworkSpecifier.java
index 87a2b05a4430..9ce2a5bd1b54 100644
--- a/core/java/android/net/NetworkSpecifier.java
+++ b/core/java/android/net/NetworkSpecifier.java
@@ -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
+ }
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index dca3b35f14f1..0748816a8957 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -42,7 +42,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;
@@ -63,6 +62,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;
@@ -102,7 +102,6 @@ import android.text.TextUtils;
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;
@@ -4007,6 +4006,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) {
@@ -4032,9 +4043,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);
@@ -4102,9 +4111,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);
@@ -4166,9 +4173,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);
@@ -4186,9 +4191,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(),
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 6140a896b1a8..633a914778a5 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -1997,6 +1997,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();
mCm.registerDefaultNetworkCallback(defaultNetworkCallback);
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareManager.java b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
index d3ed79245426..87f199292dd8 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareManager.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
@@ -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 {
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java b/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java
index 59934806f398..e152f6ced571 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java
@@ -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");
+ }
+ }
}