From ad8499f9cdd0c90815a24c7ae6f6cbd64d3bb164 Mon Sep 17 00:00:00 2001 From: zhangshuxiao Date: Wed, 3 Feb 2016 21:28:25 +0800 Subject: [PATCH] When the applicantion is removed, reset network permission of this uid. Probably not a portal: exception java.net.SocketException: Binding socket to network 102 failed: EPERM (Operation not permitted) If there are SYSTEM permissions, then the original is SYSTEM permissions, do not update. If other app of this uid have network permissions, the same as before do not update, or update permissions. If all app of this uid do not have any network permission to remove permissions. Change-Id: I304d22b37de38d8b182639c0d7d7200adfcf715d Signed-off-by: zhangshuxiao --- .../connectivity/PermissionMonitor.java | 78 +++++++++++++------ 1 file changed, 55 insertions(+), 23 deletions(-) diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java index debda1483d..eb1c77e97c 100644 --- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java +++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java @@ -55,8 +55,8 @@ import java.util.Set; public class PermissionMonitor { private static final String TAG = "PermissionMonitor"; private static final boolean DBG = true; - private static final boolean SYSTEM = true; - private static final boolean NETWORK = false; + private static final Boolean SYSTEM = Boolean.TRUE; + private static final Boolean NETWORK = Boolean.FALSE; private final Context mContext; private final PackageManager mPackageManager; @@ -226,30 +226,40 @@ public class PermissionMonitor { update(users, mApps, false); } + + private Boolean highestPermissionForUid(Boolean currentPermission, String name) { + if (currentPermission == SYSTEM) { + return currentPermission; + } + try { + final PackageInfo app = mPackageManager.getPackageInfo(name, GET_PERMISSIONS); + final boolean isNetwork = hasNetworkPermission(app); + final boolean isSystem = hasSystemPermission(app); + if (isNetwork || isSystem) { + currentPermission = isSystem; + } + } catch (NameNotFoundException e) { + // App not found. + loge("NameNotFoundException " + name); + } + return currentPermission; + } + private synchronized void onAppAdded(String appName, int appUid) { if (TextUtils.isEmpty(appName) || appUid < 0) { loge("Invalid app in onAppAdded: " + appName + " | " + appUid); return; } - try { - PackageInfo app = mPackageManager.getPackageInfo(appName, GET_PERMISSIONS); - boolean isNetwork = hasNetworkPermission(app); - boolean isSystem = hasSystemPermission(app); - if (isNetwork || isSystem) { - 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); + // 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). + final Boolean permission = highestPermissionForUid(mApps.get(appUid), appName); + if (permission != mApps.get(appUid)) { + mApps.put(appUid, permission); - Map apps = new HashMap(); - apps.put(appUid, isSystem); - update(mUsers, apps, true); - } - } - } catch (NameNotFoundException e) { - loge("NameNotFoundException in onAppAdded: " + e); + Map apps = new HashMap(); + apps.put(appUid, permission); + update(mUsers, apps, true); } } @@ -258,11 +268,33 @@ public class PermissionMonitor { loge("Invalid app in onAppRemoved: " + appUid); return; } - mApps.remove(appUid); - Map apps = new HashMap(); - apps.put(appUid, NETWORK); // doesn't matter which permission we pick here - update(mUsers, apps, false); + + Boolean permission = null; + String[] packages = mPackageManager.getPackagesForUid(appUid); + if (packages != null && packages.length > 0) { + for (String name : packages) { + permission = highestPermissionForUid(permission, name); + if (permission == SYSTEM) { + // An app with this UID still has the SYSTEM permission. + // Therefore, this UID must already have the SYSTEM permission. + // Nothing to do. + return; + } + } + } + if (permission == mApps.get(appUid)) { + // The permissions of this UID have not changed. Nothing to do. + return; + } else if (permission != null) { + mApps.put(appUid, permission); + apps.put(appUid, permission); + update(mUsers, apps, true); + } else { + mApps.remove(appUid); + apps.put(appUid, NETWORK); // doesn't matter which permission we pick here + update(mUsers, apps, false); + } } private static void log(String s) {