diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 051cb2d805..1106262ce1 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -1577,6 +1577,16 @@ public class ConnectivityService extends IConnectivityManager.Stub "ConnectivityService"); } + private void enforceConnectivityRestrictedNetworksPermission() { + try { + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS, + "ConnectivityService"); + return; + } catch (SecurityException e) { /* fallback to ConnectivityInternalPermission */ } + enforceConnectivityInternalPermission(); + } + private void enforceKeepalivePermission() { mContext.enforceCallingOrSelfPermission(KeepaliveTracker.PERMISSION, "ConnectivityService"); } @@ -4109,7 +4119,7 @@ public class ConnectivityService extends IConnectivityManager.Stub private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities) { if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) == false) { - enforceConnectivityInternalPermission(); + enforceConnectivityRestrictedNetworksPermission(); } else { enforceChangePermission(); } diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java index eb1c77e97c..e084ff827c 100644 --- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java +++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java @@ -18,6 +18,7 @@ package com.android.server.connectivity; import static android.Manifest.permission.CHANGE_NETWORK_STATE; import static android.Manifest.permission.CONNECTIVITY_INTERNAL; +import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS; import static android.content.pm.ApplicationInfo.FLAG_SYSTEM; import static android.content.pm.ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; import static android.content.pm.PackageManager.GET_PERMISSIONS; @@ -65,10 +66,10 @@ public class PermissionMonitor { private final BroadcastReceiver mIntentReceiver; // Values are User IDs. - private final Set mUsers = new HashSet(); + private final Set mUsers = new HashSet<>(); // Keys are App IDs. Values are true for SYSTEM permission and false for NETWORK permission. - private final Map mApps = new HashMap(); + private final Map mApps = new HashMap<>(); public PermissionMonitor(Context context, INetworkManagementService netd) { mContext = context; @@ -126,14 +127,14 @@ public class PermissionMonitor { } boolean isNetwork = hasNetworkPermission(app); - boolean isSystem = hasSystemPermission(app); + boolean hasRestrictedPermission = hasRestrictedNetworkPermission(app); - if (isNetwork || isSystem) { + if (isNetwork || hasRestrictedPermission) { Boolean permission = mApps.get(uid); // If multiple packages share a UID (cf: android:sharedUserId) and ask for different // permissions, don't downgrade (i.e., if it's already SYSTEM, leave it as is). if (permission == null || permission == NETWORK) { - mApps.put(uid, isSystem); + mApps.put(uid, hasRestrictedPermission); } } } @@ -164,12 +165,13 @@ public class PermissionMonitor { return hasPermission(app, CHANGE_NETWORK_STATE); } - private boolean hasSystemPermission(PackageInfo app) { + private boolean hasRestrictedNetworkPermission(PackageInfo app) { int flags = app.applicationInfo != null ? app.applicationInfo.flags : 0; if ((flags & FLAG_SYSTEM) != 0 || (flags & FLAG_UPDATED_SYSTEM_APP) != 0) { return true; } - return hasPermission(app, CONNECTIVITY_INTERNAL); + return hasPermission(app, CONNECTIVITY_INTERNAL) + || hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS); } private int[] toIntArray(List list) { @@ -181,8 +183,8 @@ public class PermissionMonitor { } private void update(Set users, Map apps, boolean add) { - List network = new ArrayList(); - List system = new ArrayList(); + List network = new ArrayList<>(); + List system = new ArrayList<>(); for (Entry app : apps.entrySet()) { List list = app.getValue() ? system : network; for (int user : users) { @@ -209,7 +211,7 @@ public class PermissionMonitor { } mUsers.add(user); - Set users = new HashSet(); + Set users = new HashSet<>(); users.add(user); update(users, mApps, true); } @@ -221,7 +223,7 @@ public class PermissionMonitor { } mUsers.remove(user); - Set users = new HashSet(); + Set users = new HashSet<>(); users.add(user); update(users, mApps, false); } @@ -234,9 +236,9 @@ public class PermissionMonitor { try { final PackageInfo app = mPackageManager.getPackageInfo(name, GET_PERMISSIONS); final boolean isNetwork = hasNetworkPermission(app); - final boolean isSystem = hasSystemPermission(app); - if (isNetwork || isSystem) { - currentPermission = isSystem; + final boolean hasRestrictedPermission = hasRestrictedNetworkPermission(app); + if (isNetwork || hasRestrictedPermission) { + currentPermission = hasRestrictedPermission; } } catch (NameNotFoundException e) { // App not found. @@ -257,7 +259,7 @@ public class PermissionMonitor { if (permission != mApps.get(appUid)) { mApps.put(appUid, permission); - Map apps = new HashMap(); + Map apps = new HashMap<>(); apps.put(appUid, permission); update(mUsers, apps, true); } @@ -268,7 +270,7 @@ public class PermissionMonitor { loge("Invalid app in onAppRemoved: " + appUid); return; } - Map apps = new HashMap(); + Map apps = new HashMap<>(); Boolean permission = null; String[] packages = mPackageManager.getPackagesForUid(appUid);