Merge "[AWARE] Add UID checking to WifiAwareNetworkSpecifier"
am: 2fd19ffa06
Change-Id: I8e4a38b113d6e8f81bc382715dda5c279771e454
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user