Support bringing up restricted wifi

This CL allows the Carrier Config app to request restricted WiFi nework
by setting the correspoding subscription ID in the network request.

Bug: 315835605
Test: atest android.net.cts.NetworkRequestTest
      atest ConnectivityCoverageTests:android.net.connectivity.com.android.server.connectivity.CarrierPrivilegeAuthenticatorTest
      atest ConnectivityCoverageTests:android.net.connectivity.com.android.server.ConnectivityServiceTest

Change-Id: I237e692d092ff5f969ce4b7962f6d58099a6f3a9
This commit is contained in:
Ying Xu 2024-01-15 18:40:15 -08:00
commit 7cabd32bc5

View file

@ -113,6 +113,8 @@ import static com.android.net.module.util.PermissionUtils.enforceNetworkStackPer
import static com.android.net.module.util.PermissionUtils.enforceNetworkStackPermissionOr;
import static com.android.net.module.util.PermissionUtils.hasAnyPermissionOf;
import static com.android.server.ConnectivityStatsLog.CONNECTIVITY_STATE_SAMPLE;
import static com.android.server.connectivity.CarrierPrivilegeAuthenticator.CarrierPrivilegesLostListener;
import static com.android.server.connectivity.ConnectivityFlags.REQUEST_RESTRICTED_WIFI;
import android.Manifest;
import android.annotation.CheckResult;
@ -467,6 +469,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
private volatile boolean mLockdownEnabled;
private final boolean mRequestRestrictedWifiEnabled;
/**
* Stale copy of uid blocked reasons provided by NPMS. As long as they are accessed only in
* internal handler thread, they don't need a lock.
@ -831,6 +835,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
*/
private static final int EVENT_UID_FROZEN_STATE_CHANGED = 61;
/**
* Event to inform the ConnectivityService handler when a uid has lost carrier privileges.
*/
private static final int EVENT_UID_CARRIER_PRIVILEGES_LOST = 62;
/**
* Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
* should be shown.
@ -1270,6 +1279,18 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
private final LegacyTypeTracker mLegacyTypeTracker = new LegacyTypeTracker(this);
private final CarrierPrivilegesLostListenerImpl mCarrierPrivilegesLostListenerImpl =
new CarrierPrivilegesLostListenerImpl();
private class CarrierPrivilegesLostListenerImpl implements CarrierPrivilegesLostListener {
@Override
public void onCarrierPrivilegesLost(int uid) {
if (mRequestRestrictedWifiEnabled) {
mHandler.sendMessage(mHandler.obtainMessage(
EVENT_UID_CARRIER_PRIVILEGES_LOST, uid, 0 /* arg2 */));
}
}
}
final LocalPriorityDump mPriorityDumper = new LocalPriorityDump();
/**
* Helper class which parses out priority arguments and dumps sections according to their
@ -1328,6 +1349,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
@VisibleForTesting
CarrierPrivilegesLostListener getCarrierPrivilegesLostListener() {
return mCarrierPrivilegesLostListenerImpl;
}
/**
* Dependencies of ConnectivityService, for injection in tests.
*/
@ -1488,9 +1514,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
*/
@Nullable
public CarrierPrivilegeAuthenticator makeCarrierPrivilegeAuthenticator(
@NonNull final Context context, @NonNull final TelephonyManager tm) {
@NonNull final Context context,
@NonNull final TelephonyManager tm,
boolean requestRestrictedWifiEnabled,
@NonNull CarrierPrivilegesLostListener listener) {
if (isAtLeastT()) {
return new CarrierPrivilegeAuthenticator(context, tm);
return new CarrierPrivilegeAuthenticator(
context, tm, requestRestrictedWifiEnabled, listener);
} else {
return null;
}
@ -1759,8 +1789,11 @@ 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);
mCarrierPrivilegeAuthenticator =
mDeps.makeCarrierPrivilegeAuthenticator(mContext, mTelephonyManager);
mRequestRestrictedWifiEnabled = mDeps.isAtLeastU()
&& mDeps.isFeatureEnabled(context, REQUEST_RESTRICTED_WIFI);
mCarrierPrivilegeAuthenticator = mDeps.makeCarrierPrivilegeAuthenticator(
mContext, mTelephonyManager, mRequestRestrictedWifiEnabled,
mCarrierPrivilegesLostListenerImpl);
// To ensure uid state is synchronized with Network Policy, register for
// NetworkPolicyManagerService events must happen prior to NetworkPolicyManagerService
@ -6410,6 +6443,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
UidFrozenStateChangedArgs args = (UidFrozenStateChangedArgs) msg.obj;
handleFrozenUids(args.mUids, args.mFrozenStates);
break;
case EVENT_UID_CARRIER_PRIVILEGES_LOST:
handleUidCarrierPrivilegesLost(msg.arg1);
break;
}
}
}
@ -7490,9 +7526,14 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
mAppOpsManager.checkPackage(callerUid, callerPackageName);
if (!nc.getSubscriptionIds().isEmpty()) {
enforceNetworkFactoryPermission();
if (nc.getSubscriptionIds().isEmpty()) {
return;
}
if (mRequestRestrictedWifiEnabled
&& canRequestRestrictedNetworkDueToCarrierPrivileges(nc, callerUid)) {
return;
}
enforceNetworkFactoryPermission();
}
private int[] getSignalStrengthThresholds(@NonNull final NetworkAgentInfo nai) {
@ -7772,6 +7813,22 @@ public class ConnectivityService extends IConnectivityManager.Stub
applicationNetworkCapabilities.enforceSelfCertifiedNetworkCapabilitiesDeclared(
networkCapabilities);
}
private boolean canRequestRestrictedNetworkDueToCarrierPrivileges(
NetworkCapabilities networkCapabilities, int callingUid) {
if (mRequestRestrictedWifiEnabled) {
// For U+ devices, callers with carrier privilege could request restricted networks
// with CBS capabilities, or any restricted WiFi networks.
return ((networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)
|| networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI))
&& hasCarrierPrivilegeForNetworkCaps(callingUid, networkCapabilities));
} else {
// For T+ devices, callers with carrier privilege could request with CBS
// capabilities.
return (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)
&& hasCarrierPrivilegeForNetworkCaps(callingUid, networkCapabilities));
}
}
private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities,
String callingPackageName, String callingAttributionTag, final int callingUid) {
if (shouldCheckCapabilitiesDeclaration(networkCapabilities, callingUid,
@ -7779,13 +7836,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
enforceRequestCapabilitiesDeclaration(callingPackageName, networkCapabilities,
callingUid);
}
if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) == false) {
// For T+ devices, callers with carrier privilege could request with CBS capabilities.
if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)
&& hasCarrierPrivilegeForNetworkCaps(callingUid, networkCapabilities)) {
return;
if (!networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) {
if (!canRequestRestrictedNetworkDueToCarrierPrivileges(
networkCapabilities, callingUid)) {
enforceConnectivityRestrictedNetworksPermission(true /* checkUidsAllowedList */);
}
enforceConnectivityRestrictedNetworksPermission(true /* checkUidsAllowedList */);
} else {
enforceChangePermission(callingPackageName, callingAttributionTag);
}
@ -9052,6 +9107,38 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
private void handleUidCarrierPrivilegesLost(int uid) {
ensureRunningOnConnectivityServiceThread();
// A NetworkRequest needs to be revoked when all the conditions are met
// 1. It requests restricted network
// 2. The requestor uid matches the uid with the callback
// 3. The app doesn't have Carrier Privileges
// 4. The app doesn't have permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS
for (final NetworkRequest nr : mNetworkRequests.keySet()) {
if ((nr.isRequest() || nr.isListen())
&& !nr.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)
&& nr.getRequestorUid() == uid
&& !hasConnectivityRestrictedNetworksPermission(uid, true)) {
declareNetworkRequestUnfulfillable(nr);
}
}
// A NetworkAgent's allowedUids may need to be updated if the app has lost
// carrier config
for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
if (nai.networkCapabilities.getAllowedUidsNoCopy().contains(uid)) {
final NetworkCapabilities nc = new NetworkCapabilities(nai.networkCapabilities);
NetworkAgentInfo.restrictCapabilitiesFromNetworkAgent(
nc,
uid,
false /* hasAutomotiveFeature (irrelevant) */,
mDeps,
mCarrierPrivilegeAuthenticator);
updateCapabilities(nai.getScore(), nai, nc);
}
}
}
/**
* Update the NetworkCapabilities for {@code nai} to {@code nc}. Specifically:
*
@ -9499,7 +9586,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
final ArraySet<Integer> toAdd = new ArraySet<>(newUids);
toRemove.removeAll(newUids);
toAdd.removeAll(prevUids);
try {
if (!toAdd.isEmpty()) {
mNetd.networkAddUidRangesParcel(new NativeUidRangeConfig(