From 849682f5a0e357688804f2ba8b92f3426fdcd08a Mon Sep 17 00:00:00 2001 From: Hugo Benichi Date: Tue, 19 Jul 2016 15:59:27 +0900 Subject: [PATCH] DO NOT MERGE ANYWHERE Add CONNECTIVITY_USE_RESTRICTED_NETWORKS permission This patch creates a new permission used by ConnectivityService to give access to restricted networks without the NET_CAPABILITY_NOT_RESTRICTED capability bit on. Bug: 24497316 Change-Id: I5b6c8a9ef14395b2f1ab26cb17b24d7876ec79f1 --- .../android/server/ConnectivityService.java | 12 ++++++- .../connectivity/PermissionMonitor.java | 36 ++++++++++--------- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 327fb8a7ef..2d7e6b0b95 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -1462,6 +1462,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"); } @@ -3694,7 +3704,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 debda1483d..94e9f70220 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); } @@ -235,16 +237,16 @@ public class PermissionMonitor { try { PackageInfo app = mPackageManager.getPackageInfo(appName, GET_PERMISSIONS); boolean isNetwork = hasNetworkPermission(app); - boolean isSystem = hasSystemPermission(app); - if (isNetwork || isSystem) { + boolean hasRestrictedPermission = hasRestrictedNetworkPermission(app); + if (isNetwork || hasRestrictedPermission) { Boolean permission = mApps.get(appUid); // 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(appUid, isSystem); + mApps.put(appUid, hasRestrictedPermission); - Map apps = new HashMap(); - apps.put(appUid, isSystem); + Map apps = new HashMap<>(); + apps.put(appUid, hasRestrictedPermission); update(mUsers, apps, true); } } @@ -260,7 +262,7 @@ public class PermissionMonitor { } mApps.remove(appUid); - Map apps = new HashMap(); + Map apps = new HashMap<>(); apps.put(appUid, NETWORK); // doesn't matter which permission we pick here update(mUsers, apps, false); }