Allow Carrier app to request for CBS capability
Test: unit test and CTS
Bug: 194332512
Change-Id: I29680b56d790106ad082f1a398c2bddb030f834a
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index fa7dfa9..8137551 100644
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -249,6 +249,7 @@
import com.android.net.module.util.PermissionUtils;
import com.android.net.module.util.netlink.InetDiagMessage;
import com.android.server.connectivity.AutodestructReference;
+import com.android.server.connectivity.CarrierPrivilegeAuthenticator;
import com.android.server.connectivity.ConnectivityFlags;
import com.android.server.connectivity.DnsManager;
import com.android.server.connectivity.DnsManager.PrivateDnsValidationUpdate;
@@ -593,6 +594,13 @@
// Handle private DNS validation status updates.
private static final int EVENT_PRIVATE_DNS_VALIDATION_UPDATE = 38;
+ /**
+ * used to remove a network request, either a listener or a real request and call unavailable
+ * arg1 = UID of caller
+ * obj = NetworkRequest
+ */
+ private static final int EVENT_RELEASE_NETWORK_REQUEST_AND_CALL_UNAVAILABLE = 39;
+
/**
* Event for NetworkMonitor/NetworkAgentInfo to inform ConnectivityService that the network has
* been tested.
@@ -760,6 +768,7 @@
private Set<String> mWolSupportedInterfaces;
private final TelephonyManager mTelephonyManager;
+ private final CarrierPrivilegeAuthenticator mCarrierPrivilegeAuthenticator;
private final AppOpsManager mAppOpsManager;
private final LocationPermissionChecker mLocationPermissionChecker;
@@ -1406,6 +1415,12 @@
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;
+ }
// To ensure uid state is synchronized with Network Policy, register for
// NetworkPolicyManagerService events must happen prior to NetworkPolicyManagerService
@@ -4140,6 +4155,15 @@
}
}
+ private boolean hasCarrierPrivilegeForNetworkRequest(int callingUid,
+ NetworkRequest networkRequest) {
+ if (SdkLevel.isAtLeastT() && mCarrierPrivilegeAuthenticator != null) {
+ return mCarrierPrivilegeAuthenticator.hasCarrierPrivilegeForNetworkRequest(callingUid,
+ networkRequest);
+ }
+ return false;
+ }
+
private void handleRegisterNetworkRequestWithIntent(@NonNull final Message msg) {
final NetworkRequestInfo nri = (NetworkRequestInfo) (msg.obj);
// handleRegisterNetworkRequestWithIntent() doesn't apply to multilayer requests.
@@ -4163,6 +4187,7 @@
private void handleRegisterNetworkRequests(@NonNull final Set<NetworkRequestInfo> nris) {
ensureRunningOnConnectivityServiceThread();
+ NetworkRequest requestToBeReleased = null;
for (final NetworkRequestInfo nri : nris) {
mNetworkRequestInfoLogs.log("REGISTER " + nri);
checkNrisConsistency(nri);
@@ -4177,7 +4202,15 @@
}
}
}
+ if (req.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
+ if (!hasCarrierPrivilegeForNetworkRequest(nri.mUid, req)
+ && !checkConnectivityRestrictedNetworksPermission(
+ nri.mPid, nri.mUid)) {
+ requestToBeReleased = req;
+ }
+ }
}
+
// If this NRI has a satisfier already, it is replacing an older request that
// has been removed. Track it.
final NetworkRequest activeRequest = nri.getActiveRequest();
@@ -4187,6 +4220,11 @@
}
}
+ if (requestToBeReleased != null) {
+ releaseNetworkRequestAndCallOnUnavailable(requestToBeReleased);
+ return;
+ }
+
if (mFlags.noRematchAllRequestsOnRegister()) {
rematchNetworksAndRequests(nris);
} else {
@@ -5026,6 +5064,11 @@
/* callOnUnavailable */ false);
break;
}
+ case EVENT_RELEASE_NETWORK_REQUEST_AND_CALL_UNAVAILABLE: {
+ handleReleaseNetworkRequest((NetworkRequest) msg.obj, msg.arg1,
+ /* callOnUnavailable */ true);
+ break;
+ }
case EVENT_SET_ACCEPT_UNVALIDATED: {
Network network = (Network) msg.obj;
handleSetAcceptUnvalidated(network, toBool(msg.arg1), toBool(msg.arg2));
@@ -6330,12 +6373,24 @@
private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities,
String callingPackageName, String callingAttributionTag) {
if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) == false) {
- enforceConnectivityRestrictedNetworksPermission();
+ if (!networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
+ enforceConnectivityRestrictedNetworksPermission();
+ }
} else {
enforceChangePermission(callingPackageName, callingAttributionTag);
}
}
+ private boolean checkConnectivityRestrictedNetworksPermission(int callerPid, int callerUid) {
+ if (checkAnyPermissionOf(callerPid, callerUid,
+ android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS)
+ || checkAnyPermissionOf(callerPid, callerUid,
+ android.Manifest.permission.CONNECTIVITY_INTERNAL)) {
+ return true;
+ }
+ return false;
+ }
+
@Override
public boolean requestBandwidthUpdate(Network network) {
enforceAccessPermission();
@@ -6402,7 +6457,6 @@
ensureValidNetworkSpecifier(networkCapabilities);
restrictRequestUidsForCallerAndSetRequestorInfo(networkCapabilities,
callingUid, callingPackageName);
-
NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE,
nextNetworkRequestId(), NetworkRequest.Type.REQUEST);
NetworkRequestInfo nri = new NetworkRequestInfo(callingUid, networkRequest, operation,
@@ -6518,6 +6572,13 @@
EVENT_RELEASE_NETWORK_REQUEST, mDeps.getCallingUid(), 0, networkRequest));
}
+ private void releaseNetworkRequestAndCallOnUnavailable(NetworkRequest networkRequest) {
+ ensureNetworkRequestHasType(networkRequest);
+ mHandler.sendMessage(mHandler.obtainMessage(
+ EVENT_RELEASE_NETWORK_REQUEST_AND_CALL_UNAVAILABLE, mDeps.getCallingUid(), 0,
+ networkRequest));
+ }
+
private void handleRegisterNetworkProvider(NetworkProviderInfo npi) {
if (mNetworkProviderInfos.containsKey(npi.messenger)) {
// Avoid creating duplicates. even if an app makes a direct AIDL call.