diff --git a/framework/src/android/net/NetworkCapabilities.java b/framework/src/android/net/NetworkCapabilities.java index e8b4642429..9b099e42b8 100644 --- a/framework/src/android/net/NetworkCapabilities.java +++ b/framework/src/android/net/NetworkCapabilities.java @@ -169,6 +169,15 @@ public final class NetworkCapabilities implements Parcelable { @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final long REDACT_FOR_NETWORK_SETTINGS = 1 << 2; + /** + * Redact any fields that need {@link android.Manifest.permission#THREAD_NETWORK_PRIVILEGED} + * permission since the receiving app does not hold this permission. + * + * @see android.Manifest.permission#THREAD_NETWORK_PRIVILEGED + * @hide for only {@code ThreadNetworkSpecifier} which is in the same module + */ + public static final long REDACT_FOR_THREAD_NETWORK_PRIVILEGED = 1 << 3; + /** * Redact all fields in this object that require any relevant permission. * @hide @@ -182,6 +191,7 @@ public final class NetworkCapabilities implements Parcelable { REDACT_FOR_ACCESS_FINE_LOCATION, REDACT_FOR_LOCAL_MAC_ADDRESS, REDACT_FOR_NETWORK_SETTINGS, + REDACT_FOR_THREAD_NETWORK_PRIVILEGED, REDACT_ALL }) @Retention(RetentionPolicy.SOURCE) diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java index cfceca3c65..20026ccafb 100644 --- a/service/src/com/android/server/ConnectivityService.java +++ b/service/src/com/android/server/ConnectivityService.java @@ -109,6 +109,7 @@ import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_5; import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION; import static android.net.NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS; import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS; +import static android.net.NetworkCapabilities.REDACT_FOR_THREAD_NETWORK_PRIVILEGED; import static android.net.NetworkCapabilities.RES_ID_MATCH_ALL_RESERVATIONS; import static android.net.NetworkCapabilities.RES_ID_UNSET; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; @@ -3208,6 +3209,7 @@ public class ConnectivityService extends IConnectivityManager.Stub private Boolean mHasLocationPermission = null; private Boolean mHasLocalMacAddressPermission = null; private Boolean mHasSettingsPermission = null; + private Boolean mHasThreadNetworkPrivilegedPermission = null; RedactionPermissionChecker(int callingPid, int callingUid, @NonNull String callingPackageName, @Nullable String callingAttributionTag) { @@ -3267,6 +3269,20 @@ public class ConnectivityService extends IConnectivityManager.Stub } return mHasSettingsPermission; } + + /** + * Returns whether the app holds THREAD_NETWORK_PRIVILEGED permission or not (might return + * cached result if the permission was already checked before). + */ + @CheckResult + private boolean hasThreadNetworkPrivilegedPermission() { + if (mHasThreadNetworkPrivilegedPermission == null) { + // If there is no cached result, perform the check now. + mHasThreadNetworkPrivilegedPermission = ConnectivityService.this + .hasThreadNetworkPrivilegedPermission(mCallingPid, mCallingUid); + } + return mHasThreadNetworkPrivilegedPermission; + } } private static boolean shouldRedact(@NetworkCapabilities.RedactionType long redactions, @@ -3301,6 +3317,11 @@ public class ConnectivityService extends IConnectivityManager.Stub redactions &= ~REDACT_FOR_NETWORK_SETTINGS; } } + if (shouldRedact(redactions, REDACT_FOR_THREAD_NETWORK_PRIVILEGED)) { + if (redactionPermissionChecker.hasThreadNetworkPrivilegedPermission()) { + redactions &= ~REDACT_FOR_THREAD_NETWORK_PRIVILEGED; + } + } return redactions; } @@ -4269,6 +4290,16 @@ public class ConnectivityService extends IConnectivityManager.Stub Manifest.permission.LOCAL_MAC_ADDRESS, pid, uid); } + @CheckResult + private boolean hasThreadNetworkPrivilegedPermission(int pid, int uid) { + // The THREAD_NETWORK_PRIVILEGED permission was added in Android V + if (!SdkLevel.isAtLeastV()) { + return false; + } + return PERMISSION_GRANTED == mContext.checkPermission( + Manifest.permission.THREAD_NETWORK_PRIVILEGED, pid, uid); + } + private void sendConnectedBroadcast(NetworkInfo info) { sendGeneralBroadcast(info, CONNECTIVITY_ACTION); }