Merge changes Ic6a1aa92,I685f924a,I50fab91e
* changes: Use packBitList to prevent long-related mistakes Introduce ensureListenableCapabilities Accept accessUids from telephony when it's the carrier config app
This commit is contained in:
@@ -1338,6 +1338,18 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
return new LocationPermissionChecker(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see CarrierPrivilegeAuthenticator
|
||||
*/
|
||||
public CarrierPrivilegeAuthenticator makeCarrierPrivilegeAuthenticator(
|
||||
@NonNull final Context context, @NonNull final TelephonyManager tm) {
|
||||
if (SdkLevel.isAtLeastT()) {
|
||||
return new CarrierPrivilegeAuthenticator(context, tm);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DeviceConfigUtils#isFeatureEnabled
|
||||
*/
|
||||
@@ -1426,12 +1438,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
|
||||
mLocationPermissionChecker = mDeps.makeLocationPermissionChecker(mContext);
|
||||
if (SdkLevel.isAtLeastT()) {
|
||||
mCarrierPrivilegeAuthenticator =
|
||||
new CarrierPrivilegeAuthenticator(mContext, mTelephonyManager);
|
||||
} else {
|
||||
mCarrierPrivilegeAuthenticator = null;
|
||||
}
|
||||
mCarrierPrivilegeAuthenticator =
|
||||
mDeps.makeCarrierPrivilegeAuthenticator(mContext, mTelephonyManager);
|
||||
|
||||
// To ensure uid state is synchronized with Network Policy, register for
|
||||
// NetworkPolicyManagerService events must happen prior to NetworkPolicyManagerService
|
||||
@@ -4157,11 +4165,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasCarrierPrivilegeForNetworkRequest(int callingUid,
|
||||
NetworkRequest networkRequest) {
|
||||
private boolean hasCarrierPrivilegeForNetworkCaps(final int callingUid,
|
||||
@NonNull final NetworkCapabilities caps) {
|
||||
if (SdkLevel.isAtLeastT() && mCarrierPrivilegeAuthenticator != null) {
|
||||
return mCarrierPrivilegeAuthenticator.hasCarrierPrivilegeForNetworkRequest(callingUid,
|
||||
networkRequest);
|
||||
return mCarrierPrivilegeAuthenticator.hasCarrierPrivilegeForNetworkCapabilities(
|
||||
callingUid, caps);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -4205,7 +4213,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
}
|
||||
}
|
||||
if (req.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
|
||||
if (!hasCarrierPrivilegeForNetworkRequest(nri.mUid, req)
|
||||
if (!hasCarrierPrivilegeForNetworkCaps(nri.mUid, req.networkCapabilities)
|
||||
&& !checkConnectivityRestrictedNetworksPermission(
|
||||
nri.mPid, nri.mUid)) {
|
||||
requestToBeReleased = req;
|
||||
@@ -6140,13 +6148,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
private void ensureRequestableCapabilities(NetworkCapabilities networkCapabilities) {
|
||||
final String badCapability = networkCapabilities.describeFirstNonRequestableCapability();
|
||||
if (badCapability != null) {
|
||||
throw new IllegalArgumentException("Cannot request network with " + badCapability);
|
||||
}
|
||||
}
|
||||
|
||||
// This checks that the passed capabilities either do not request a
|
||||
// specific SSID/SignalStrength, or the calling app has permission to do so.
|
||||
private void ensureSufficientPermissionsForRequest(NetworkCapabilities nc,
|
||||
@@ -6204,7 +6205,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
nai.onSignalStrengthThresholdsUpdated(thresholdsArray);
|
||||
}
|
||||
|
||||
private void ensureValidNetworkSpecifier(NetworkCapabilities nc) {
|
||||
private static void ensureValidNetworkSpecifier(NetworkCapabilities nc) {
|
||||
if (nc == null) {
|
||||
return;
|
||||
}
|
||||
@@ -6217,7 +6218,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
private void ensureValid(NetworkCapabilities nc) {
|
||||
private static void ensureListenableCapabilities(@NonNull final NetworkCapabilities nc) {
|
||||
ensureValidNetworkSpecifier(nc);
|
||||
if (nc.isPrivateDnsBroken()) {
|
||||
throw new IllegalArgumentException("Can't request broken private DNS");
|
||||
@@ -6227,6 +6228,14 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
private void ensureRequestableCapabilities(@NonNull final NetworkCapabilities nc) {
|
||||
ensureListenableCapabilities(nc);
|
||||
final String badCapability = nc.describeFirstNonRequestableCapability();
|
||||
if (badCapability != null) {
|
||||
throw new IllegalArgumentException("Cannot request network with " + badCapability);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Set the mini sdk to 31 and remove @TargetApi annotation when b/205923322 is addressed.
|
||||
@TargetApi(Build.VERSION_CODES.S)
|
||||
private boolean isTargetSdkAtleast(int version, int callingUid,
|
||||
@@ -6319,7 +6328,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
if (timeoutMs < 0) {
|
||||
throw new IllegalArgumentException("Bad timeout specified");
|
||||
}
|
||||
ensureValid(networkCapabilities);
|
||||
|
||||
final NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, legacyType,
|
||||
nextNetworkRequestId(), reqType);
|
||||
@@ -6461,7 +6469,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
Binder.getCallingPid(), callingUid, callingPackageName);
|
||||
restrictRequestUidsForCallerAndSetRequestorInfo(networkCapabilities,
|
||||
callingUid, callingPackageName);
|
||||
ensureValid(networkCapabilities);
|
||||
|
||||
NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE,
|
||||
nextNetworkRequestId(), NetworkRequest.Type.REQUEST);
|
||||
@@ -6528,7 +6535,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
// There is no need to do this for requests because an app without CHANGE_NETWORK_STATE
|
||||
// can't request networks.
|
||||
restrictBackgroundRequestForCaller(nc);
|
||||
ensureValid(nc);
|
||||
ensureListenableCapabilities(nc);
|
||||
|
||||
NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(),
|
||||
NetworkRequest.Type.LISTEN);
|
||||
@@ -6550,7 +6557,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
if (!hasWifiNetworkListenPermission(networkCapabilities)) {
|
||||
enforceAccessPermission();
|
||||
}
|
||||
ensureValid(networkCapabilities);
|
||||
ensureListenableCapabilities(networkCapabilities);
|
||||
ensureSufficientPermissionsForRequest(networkCapabilities,
|
||||
Binder.getCallingPid(), callingUid, callingPackageName);
|
||||
final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
|
||||
@@ -7495,7 +7502,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
nc.setOwnerUid(nai.networkCapabilities.getOwnerUid());
|
||||
}
|
||||
nai.declaredCapabilities = new NetworkCapabilities(nc);
|
||||
NetworkAgentInfo.restrictCapabilitiesFromNetworkAgent(nc, nai.creatorUid);
|
||||
NetworkAgentInfo.restrictCapabilitiesFromNetworkAgent(nc, nai.creatorUid,
|
||||
mCarrierPrivilegeAuthenticator);
|
||||
}
|
||||
|
||||
/** Modifies |newNc| based on the capabilities of |underlyingNetworks| and |agentCaps|. */
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.server.connectivity;
|
||||
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_CBS;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.content.BroadcastReceiver;
|
||||
@@ -25,7 +26,7 @@ import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.NetworkRequest;
|
||||
import android.net.NetworkCapabilities;
|
||||
import android.net.NetworkSpecifier;
|
||||
import android.net.TelephonyNetworkSpecifier;
|
||||
import android.os.Build;
|
||||
@@ -235,24 +236,30 @@ public class CarrierPrivilegeAuthenticator extends BroadcastReceiver {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if network request is allowed based upon carrrier service package.
|
||||
* Check if a UID is the carrier service app of the subscription ID in the provided capabilities
|
||||
*
|
||||
* Network request for {@link NET_CAPABILITY_CBS} is allowed if the caller has
|
||||
* carrier privilege and provides the carrier config. This function checks if caller
|
||||
* has the same and returns true if it has else false.
|
||||
* This returns whether the passed UID is the carrier service package for the subscription ID
|
||||
* stored in the telephony network specifier in the passed network capabilities.
|
||||
* If the capabilities don't code for a cellular network, or if they don't have the
|
||||
* subscription ID in their specifier, this returns false.
|
||||
*
|
||||
* @param callingUid user identifier that uniquely identifies the caller.
|
||||
* @param networkRequest the network request for which the carrier privilege is checked.
|
||||
* @return true if caller has carrier privilege and provides the carrier config else false.
|
||||
* This method can be used to check that a network request for {@link NET_CAPABILITY_CBS} is
|
||||
* allowed for the UID of a caller, which must hold carrier privilege and provide the carrier
|
||||
* config.
|
||||
* It can also be used to check that a factory is entitled to grant access to a given network
|
||||
* to a given UID on grounds that it is the carrier service package.
|
||||
*
|
||||
* @param callingUid uid of the app claimed to be the carrier service package.
|
||||
* @param networkCapabilities the network capabilities for which carrier privilege is checked.
|
||||
* @return true if uid provides the relevant carrier config else false.
|
||||
*/
|
||||
public boolean hasCarrierPrivilegeForNetworkRequest(int callingUid,
|
||||
NetworkRequest networkRequest) {
|
||||
if (callingUid != Process.INVALID_UID) {
|
||||
final int subId = getSubIdFromNetworkSpecifier(
|
||||
networkRequest.getNetworkSpecifier());
|
||||
return callingUid == getCarrierServiceUidForSubId(subId);
|
||||
}
|
||||
return false;
|
||||
public boolean hasCarrierPrivilegeForNetworkCapabilities(int callingUid,
|
||||
@NonNull NetworkCapabilities networkCapabilities) {
|
||||
if (callingUid == Process.INVALID_UID) return false;
|
||||
if (!networkCapabilities.hasSingleTransport(TRANSPORT_CELLULAR)) return false;
|
||||
final int subId = getSubIdFromNetworkSpecifier(networkCapabilities.getNetworkSpecifier());
|
||||
if (SubscriptionManager.INVALID_SUBSCRIPTION_ID == subId) return false;
|
||||
return callingUid == getCarrierServiceUidForSubId(subId);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -286,7 +293,7 @@ public class CarrierPrivilegeAuthenticator extends BroadcastReceiver {
|
||||
if (specifier instanceof TelephonyNetworkSpecifier) {
|
||||
return ((TelephonyNetworkSpecifier) specifier).getSubscriptionId();
|
||||
}
|
||||
return SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
|
||||
return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
|
||||
@@ -60,6 +60,7 @@ import android.util.Pair;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import com.android.internal.util.WakeupMessage;
|
||||
import com.android.modules.utils.build.SdkLevel;
|
||||
import com.android.server.ConnectivityService;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
@@ -1196,21 +1197,26 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo>, NetworkRa
|
||||
*
|
||||
* @param nc the capabilities to sanitize
|
||||
* @param creatorUid the UID of the process creating this network agent
|
||||
* @param authenticator the carrier privilege authenticator to check for telephony constraints
|
||||
*/
|
||||
public static void restrictCapabilitiesFromNetworkAgent(@NonNull final NetworkCapabilities nc,
|
||||
final int creatorUid) {
|
||||
final int creatorUid, @NonNull final CarrierPrivilegeAuthenticator authenticator) {
|
||||
if (nc.hasTransport(TRANSPORT_TEST)) {
|
||||
nc.restrictCapabilitiesForTestNetwork(creatorUid);
|
||||
}
|
||||
if (!areAccessUidsAcceptableFromNetworkAgent(nc)) {
|
||||
if (!areAccessUidsAcceptableFromNetworkAgent(nc, authenticator)) {
|
||||
nc.setAccessUids(new ArraySet<>());
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean areAccessUidsAcceptableFromNetworkAgent(
|
||||
@NonNull final NetworkCapabilities nc) {
|
||||
@NonNull final NetworkCapabilities nc,
|
||||
@Nullable final CarrierPrivilegeAuthenticator carrierPrivilegeAuthenticator) {
|
||||
// NCs without access UIDs are fine.
|
||||
if (!nc.hasAccessUids()) return true;
|
||||
// S and below must never accept access UIDs, even if an agent sends them, because netd
|
||||
// didn't support the required feature in S.
|
||||
if (!SdkLevel.isAtLeastT()) return false;
|
||||
|
||||
// On a non-restricted network, access UIDs make no sense
|
||||
if (nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) return false;
|
||||
@@ -1219,7 +1225,18 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo>, NetworkRa
|
||||
// access UIDs
|
||||
if (nc.hasTransport(TRANSPORT_TEST)) return true;
|
||||
|
||||
// TODO : accept more supported cases
|
||||
// Factories that make cell networks can allow the UID for the carrier service package.
|
||||
// This can only work in T where there is support for CarrierPrivilegeAuthenticator
|
||||
if (null != carrierPrivilegeAuthenticator
|
||||
&& nc.hasSingleTransport(TRANSPORT_CELLULAR)
|
||||
&& (1 == nc.getAccessUidsNoCopy().size())
|
||||
&& (carrierPrivilegeAuthenticator.hasCarrierPrivilegeForNetworkCapabilities(
|
||||
nc.getAccessUidsNoCopy().valueAt(0), nc))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO : accept Railway callers
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user