Loading services/core/java/com/android/server/connectivity/PermissionMonitor.java +89 −73 Original line number Diff line number Diff line Loading @@ -21,23 +21,14 @@ import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS; import static android.Manifest.permission.INTERNET; import static android.Manifest.permission.NETWORK_STACK; import static android.Manifest.permission.UPDATE_DEVICE_STATS; import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED; import static android.content.pm.PackageManager.GET_PERMISSIONS; import static android.content.pm.PackageManager.MATCH_ANY_USER; import static android.net.INetd.PERMISSION_INTERNET; import static android.net.INetd.PERMISSION_NETWORK; import static android.net.INetd.PERMISSION_NONE; import static android.net.INetd.PERMISSION_SYSTEM; import static android.net.INetd.PERMISSION_UNINSTALLED; import static android.net.INetd.PERMISSION_UPDATE_DEVICE_STATS; import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK; import static android.os.Process.INVALID_UID; import static android.os.Process.SYSTEM_UID; import static com.android.internal.util.ArrayUtils.convertToIntArray; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; Loading @@ -60,6 +51,7 @@ import android.util.SparseIntArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import com.android.internal.util.IndentingPrintWriter; import com.android.server.LocalServices; import com.android.server.SystemConfig; Loading @@ -73,6 +65,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; /** * A utility class to inform Netd of UID permisisons. * Does a mass update at boot and then monitors for app install/remove. Loading Loading @@ -121,13 +114,6 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse public int getDeviceFirstSdkInt() { return Build.VERSION.FIRST_SDK_INT; } /** * Check whether given uid has specific permission. */ public int uidPermission(@NonNull final String permission, final int uid) { return ActivityManager.checkUidPermission(permission, uid); } } public PermissionMonitor(@NonNull final Context context, @NonNull final INetd netd) { Loading Loading @@ -170,9 +156,8 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse } mAllApps.add(UserHandle.getAppId(uid)); final boolean isNetwork = hasPermission(CHANGE_NETWORK_STATE, uid); final boolean hasRestrictedPermission = hasRestrictedNetworkPermission(app.applicationInfo); boolean isNetwork = hasNetworkPermission(app); boolean hasRestrictedPermission = hasRestrictedNetworkPermission(app); if (isNetwork || hasRestrictedPermission) { Boolean permission = mApps.get(uid); Loading @@ -184,7 +169,8 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse } //TODO: unify the management of the permissions into one codepath. final int otherNetdPerms = getNetdPermissionMask(uid); int otherNetdPerms = getNetdPermissionMask(app.requestedPermissions, app.requestedPermissionsFlags); netdPermsUids.put(uid, netdPermsUids.get(uid) | otherNetdPerms); } Loading @@ -204,8 +190,9 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse // Get the uids of native services that have UPDATE_DEVICE_STATS or INTERNET permission. if (perms != null) { netdPermission |= perms.contains(UPDATE_DEVICE_STATS) ? PERMISSION_UPDATE_DEVICE_STATS : 0; netdPermission |= perms.contains(INTERNET) ? PERMISSION_INTERNET : 0; ? INetd.PERMISSION_UPDATE_DEVICE_STATS : 0; netdPermission |= perms.contains(INTERNET) ? INetd.PERMISSION_INTERNET : 0; } netdPermsUids.put(uid, netdPermsUids.get(uid) | netdPermission); } Loading @@ -220,33 +207,48 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse } @VisibleForTesting boolean hasPermission(@NonNull final String permission, final int uid) { return mDeps.uidPermission(permission, uid) == PackageManager.PERMISSION_GRANTED; boolean hasPermission(@NonNull final PackageInfo app, @NonNull final String permission) { if (app.requestedPermissions == null || app.requestedPermissionsFlags == null) { return false; } final int index = ArrayUtils.indexOf(app.requestedPermissions, permission); if (index < 0 || index >= app.requestedPermissionsFlags.length) return false; return (app.requestedPermissionsFlags[index] & REQUESTED_PERMISSION_GRANTED) != 0; } @VisibleForTesting boolean hasNetworkPermission(@NonNull final PackageInfo app) { return hasPermission(app, CHANGE_NETWORK_STATE); } @VisibleForTesting boolean hasRestrictedNetworkPermission(@Nullable final ApplicationInfo appInfo) { if (appInfo == null) return false; // TODO : remove this check in the future(b/162295056). All apps should just boolean hasRestrictedNetworkPermission(@NonNull final PackageInfo app) { // TODO : remove this check in the future(b/31479477). All apps should just // request the appropriate permission for their use case since android Q. if ((appInfo.targetSdkVersion < VERSION_Q && isVendorApp(appInfo)) if (app.applicationInfo != null) { // Backward compatibility for b/114245686, on devices that launched before Q daemons // and apps running as the system UID are exempted from this check. || (appInfo.uid == SYSTEM_UID && mDeps.getDeviceFirstSdkInt() < VERSION_Q)) { if (app.applicationInfo.uid == SYSTEM_UID && mDeps.getDeviceFirstSdkInt() < VERSION_Q) { return true; } return hasPermission(PERMISSION_MAINLINE_NETWORK_STACK, appInfo.uid) || hasPermission(NETWORK_STACK, appInfo.uid) || hasPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, appInfo.uid); if (app.applicationInfo.targetSdkVersion < VERSION_Q && isVendorApp(app.applicationInfo)) { return true; } } return hasPermission(app, PERMISSION_MAINLINE_NETWORK_STACK) || hasPermission(app, NETWORK_STACK) || hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS); } /** Returns whether the given uid has using background network permission. */ public synchronized boolean hasUseBackgroundNetworksPermission(final int uid) { // Apps with any of the CHANGE_NETWORK_STATE, NETWORK_STACK, CONNECTIVITY_INTERNAL or // CONNECTIVITY_USE_RESTRICTED_NETWORKS permission has the permission to use background // networks. mApps contains the result of checks for both CHANGE_NETWORK_STATE permission // and hasRestrictedNetworkPermission. If uid is in the mApps list that means uid has one of // networks. mApps contains the result of checks for both hasNetworkPermission and // hasRestrictedNetworkPermission. If uid is in the mApps list that means uid has one of // permissions at least. return mApps.containsKey(uid); } Loading @@ -271,11 +273,11 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse } try { if (add) { mNetd.networkSetPermissionForUser(PERMISSION_NETWORK, convertToIntArray(network)); mNetd.networkSetPermissionForUser(PERMISSION_SYSTEM, convertToIntArray(system)); mNetd.networkSetPermissionForUser(INetd.PERMISSION_NETWORK, toIntArray(network)); mNetd.networkSetPermissionForUser(INetd.PERMISSION_SYSTEM, toIntArray(system)); } else { mNetd.networkClearPermissionForUser(convertToIntArray(network)); mNetd.networkClearPermissionForUser(convertToIntArray(system)); mNetd.networkClearPermissionForUser(toIntArray(network)); mNetd.networkClearPermissionForUser(toIntArray(system)); } } catch (RemoteException e) { loge("Exception when updating permissions: " + e); Loading Loading @@ -321,15 +323,14 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse } @VisibleForTesting protected Boolean highestPermissionForUid(Boolean currentPermission, String name, int uid) { protected Boolean highestPermissionForUid(Boolean currentPermission, String name) { if (currentPermission == SYSTEM) { return currentPermission; } try { final PackageInfo app = mPackageManager.getPackageInfo(name, GET_PERMISSIONS); final boolean isNetwork = hasPermission(CHANGE_NETWORK_STATE, uid); final boolean hasRestrictedPermission = hasRestrictedNetworkPermission(app.applicationInfo); final boolean isNetwork = hasNetworkPermission(app); final boolean hasRestrictedPermission = hasRestrictedNetworkPermission(app); if (isNetwork || hasRestrictedPermission) { currentPermission = hasRestrictedPermission; } Loading @@ -341,14 +342,23 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse } private int getPermissionForUid(final int uid) { int permission = INetd.PERMISSION_NONE; // Check all the packages for this UID. The UID has the permission if any of the // packages in it has the permission. final String[] packages = mPackageManager.getPackagesForUid(uid); if (packages == null || packages.length <= 0) { if (packages != null && packages.length > 0) { for (String name : packages) { final PackageInfo app = getPackageInfo(name); if (app != null && app.requestedPermissions != null) { permission |= getNetdPermissionMask(app.requestedPermissions, app.requestedPermissionsFlags); } } } else { // The last package of this uid is removed from device. Clean the package up. return PERMISSION_UNINSTALLED; permission = INetd.PERMISSION_UNINSTALLED; } return getNetdPermissionMask(uid); return permission; } /** Loading @@ -365,7 +375,7 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse // 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(uid), packageName, uid); final Boolean permission = highestPermissionForUid(mApps.get(uid), packageName); if (permission != mApps.get(uid)) { mApps.put(uid, permission); Loading Loading @@ -421,7 +431,7 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse String[] packages = mPackageManager.getPackagesForUid(uid); if (packages != null && packages.length > 0) { for (String name : packages) { permission = highestPermissionForUid(permission, name, uid); 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. Loading Loading @@ -457,13 +467,19 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse sendPackagePermissionsForUid(uid, getPermissionForUid(uid)); } private int getNetdPermissionMask(final int uid) { int permissions = PERMISSION_NONE; if (hasPermission(INTERNET, uid)) { permissions |= PERMISSION_INTERNET; private static int getNetdPermissionMask(String[] requestedPermissions, int[] requestedPermissionsFlags) { int permissions = 0; if (requestedPermissions == null || requestedPermissionsFlags == null) return permissions; for (int i = 0; i < requestedPermissions.length; i++) { if (requestedPermissions[i].equals(INTERNET) && ((requestedPermissionsFlags[i] & REQUESTED_PERMISSION_GRANTED) != 0)) { permissions |= INetd.PERMISSION_INTERNET; } if (requestedPermissions[i].equals(UPDATE_DEVICE_STATS) && ((requestedPermissionsFlags[i] & REQUESTED_PERMISSION_GRANTED) != 0)) { permissions |= INetd.PERMISSION_UPDATE_DEVICE_STATS; } if (hasPermission(UPDATE_DEVICE_STATS, uid)) { permissions |= PERMISSION_UPDATE_DEVICE_STATS; } return permissions; } Loading Loading @@ -632,19 +648,19 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse for (int i = 0; i < netdPermissionsAppIds.size(); i++) { int permissions = netdPermissionsAppIds.valueAt(i); switch(permissions) { case (PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS): case (INetd.PERMISSION_INTERNET | INetd.PERMISSION_UPDATE_DEVICE_STATS): allPermissionAppIds.add(netdPermissionsAppIds.keyAt(i)); break; case PERMISSION_INTERNET: case INetd.PERMISSION_INTERNET: internetPermissionAppIds.add(netdPermissionsAppIds.keyAt(i)); break; case PERMISSION_UPDATE_DEVICE_STATS: case INetd.PERMISSION_UPDATE_DEVICE_STATS: updateStatsPermissionAppIds.add(netdPermissionsAppIds.keyAt(i)); break; case PERMISSION_NONE: case INetd.PERMISSION_NONE: noPermissionAppIds.add(netdPermissionsAppIds.keyAt(i)); break; case PERMISSION_UNINSTALLED: case INetd.PERMISSION_UNINSTALLED: uninstalledAppIds.add(netdPermissionsAppIds.keyAt(i)); default: Log.e(TAG, "unknown permission type: " + permissions + "for uid: " Loading @@ -655,24 +671,24 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse // TODO: add a lock inside netd to protect IPC trafficSetNetPermForUids() if (allPermissionAppIds.size() != 0) { mNetd.trafficSetNetPermForUids( PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS, convertToIntArray(allPermissionAppIds)); INetd.PERMISSION_INTERNET | INetd.PERMISSION_UPDATE_DEVICE_STATS, ArrayUtils.convertToIntArray(allPermissionAppIds)); } if (internetPermissionAppIds.size() != 0) { mNetd.trafficSetNetPermForUids(PERMISSION_INTERNET, convertToIntArray(internetPermissionAppIds)); mNetd.trafficSetNetPermForUids(INetd.PERMISSION_INTERNET, ArrayUtils.convertToIntArray(internetPermissionAppIds)); } if (updateStatsPermissionAppIds.size() != 0) { mNetd.trafficSetNetPermForUids(PERMISSION_UPDATE_DEVICE_STATS, convertToIntArray(updateStatsPermissionAppIds)); mNetd.trafficSetNetPermForUids(INetd.PERMISSION_UPDATE_DEVICE_STATS, ArrayUtils.convertToIntArray(updateStatsPermissionAppIds)); } if (noPermissionAppIds.size() != 0) { mNetd.trafficSetNetPermForUids(PERMISSION_NONE, convertToIntArray(noPermissionAppIds)); mNetd.trafficSetNetPermForUids(INetd.PERMISSION_NONE, ArrayUtils.convertToIntArray(noPermissionAppIds)); } if (uninstalledAppIds.size() != 0) { mNetd.trafficSetNetPermForUids(PERMISSION_UNINSTALLED, convertToIntArray(uninstalledAppIds)); mNetd.trafficSetNetPermForUids(INetd.PERMISSION_UNINSTALLED, ArrayUtils.convertToIntArray(uninstalledAppIds)); } } catch (RemoteException e) { Log.e(TAG, "Pass appId list of special permission failed." + e); Loading tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java +122 −86 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
services/core/java/com/android/server/connectivity/PermissionMonitor.java +89 −73 Original line number Diff line number Diff line Loading @@ -21,23 +21,14 @@ import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS; import static android.Manifest.permission.INTERNET; import static android.Manifest.permission.NETWORK_STACK; import static android.Manifest.permission.UPDATE_DEVICE_STATS; import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED; import static android.content.pm.PackageManager.GET_PERMISSIONS; import static android.content.pm.PackageManager.MATCH_ANY_USER; import static android.net.INetd.PERMISSION_INTERNET; import static android.net.INetd.PERMISSION_NETWORK; import static android.net.INetd.PERMISSION_NONE; import static android.net.INetd.PERMISSION_SYSTEM; import static android.net.INetd.PERMISSION_UNINSTALLED; import static android.net.INetd.PERMISSION_UPDATE_DEVICE_STATS; import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK; import static android.os.Process.INVALID_UID; import static android.os.Process.SYSTEM_UID; import static com.android.internal.util.ArrayUtils.convertToIntArray; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; Loading @@ -60,6 +51,7 @@ import android.util.SparseIntArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import com.android.internal.util.IndentingPrintWriter; import com.android.server.LocalServices; import com.android.server.SystemConfig; Loading @@ -73,6 +65,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; /** * A utility class to inform Netd of UID permisisons. * Does a mass update at boot and then monitors for app install/remove. Loading Loading @@ -121,13 +114,6 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse public int getDeviceFirstSdkInt() { return Build.VERSION.FIRST_SDK_INT; } /** * Check whether given uid has specific permission. */ public int uidPermission(@NonNull final String permission, final int uid) { return ActivityManager.checkUidPermission(permission, uid); } } public PermissionMonitor(@NonNull final Context context, @NonNull final INetd netd) { Loading Loading @@ -170,9 +156,8 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse } mAllApps.add(UserHandle.getAppId(uid)); final boolean isNetwork = hasPermission(CHANGE_NETWORK_STATE, uid); final boolean hasRestrictedPermission = hasRestrictedNetworkPermission(app.applicationInfo); boolean isNetwork = hasNetworkPermission(app); boolean hasRestrictedPermission = hasRestrictedNetworkPermission(app); if (isNetwork || hasRestrictedPermission) { Boolean permission = mApps.get(uid); Loading @@ -184,7 +169,8 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse } //TODO: unify the management of the permissions into one codepath. final int otherNetdPerms = getNetdPermissionMask(uid); int otherNetdPerms = getNetdPermissionMask(app.requestedPermissions, app.requestedPermissionsFlags); netdPermsUids.put(uid, netdPermsUids.get(uid) | otherNetdPerms); } Loading @@ -204,8 +190,9 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse // Get the uids of native services that have UPDATE_DEVICE_STATS or INTERNET permission. if (perms != null) { netdPermission |= perms.contains(UPDATE_DEVICE_STATS) ? PERMISSION_UPDATE_DEVICE_STATS : 0; netdPermission |= perms.contains(INTERNET) ? PERMISSION_INTERNET : 0; ? INetd.PERMISSION_UPDATE_DEVICE_STATS : 0; netdPermission |= perms.contains(INTERNET) ? INetd.PERMISSION_INTERNET : 0; } netdPermsUids.put(uid, netdPermsUids.get(uid) | netdPermission); } Loading @@ -220,33 +207,48 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse } @VisibleForTesting boolean hasPermission(@NonNull final String permission, final int uid) { return mDeps.uidPermission(permission, uid) == PackageManager.PERMISSION_GRANTED; boolean hasPermission(@NonNull final PackageInfo app, @NonNull final String permission) { if (app.requestedPermissions == null || app.requestedPermissionsFlags == null) { return false; } final int index = ArrayUtils.indexOf(app.requestedPermissions, permission); if (index < 0 || index >= app.requestedPermissionsFlags.length) return false; return (app.requestedPermissionsFlags[index] & REQUESTED_PERMISSION_GRANTED) != 0; } @VisibleForTesting boolean hasNetworkPermission(@NonNull final PackageInfo app) { return hasPermission(app, CHANGE_NETWORK_STATE); } @VisibleForTesting boolean hasRestrictedNetworkPermission(@Nullable final ApplicationInfo appInfo) { if (appInfo == null) return false; // TODO : remove this check in the future(b/162295056). All apps should just boolean hasRestrictedNetworkPermission(@NonNull final PackageInfo app) { // TODO : remove this check in the future(b/31479477). All apps should just // request the appropriate permission for their use case since android Q. if ((appInfo.targetSdkVersion < VERSION_Q && isVendorApp(appInfo)) if (app.applicationInfo != null) { // Backward compatibility for b/114245686, on devices that launched before Q daemons // and apps running as the system UID are exempted from this check. || (appInfo.uid == SYSTEM_UID && mDeps.getDeviceFirstSdkInt() < VERSION_Q)) { if (app.applicationInfo.uid == SYSTEM_UID && mDeps.getDeviceFirstSdkInt() < VERSION_Q) { return true; } return hasPermission(PERMISSION_MAINLINE_NETWORK_STACK, appInfo.uid) || hasPermission(NETWORK_STACK, appInfo.uid) || hasPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, appInfo.uid); if (app.applicationInfo.targetSdkVersion < VERSION_Q && isVendorApp(app.applicationInfo)) { return true; } } return hasPermission(app, PERMISSION_MAINLINE_NETWORK_STACK) || hasPermission(app, NETWORK_STACK) || hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS); } /** Returns whether the given uid has using background network permission. */ public synchronized boolean hasUseBackgroundNetworksPermission(final int uid) { // Apps with any of the CHANGE_NETWORK_STATE, NETWORK_STACK, CONNECTIVITY_INTERNAL or // CONNECTIVITY_USE_RESTRICTED_NETWORKS permission has the permission to use background // networks. mApps contains the result of checks for both CHANGE_NETWORK_STATE permission // and hasRestrictedNetworkPermission. If uid is in the mApps list that means uid has one of // networks. mApps contains the result of checks for both hasNetworkPermission and // hasRestrictedNetworkPermission. If uid is in the mApps list that means uid has one of // permissions at least. return mApps.containsKey(uid); } Loading @@ -271,11 +273,11 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse } try { if (add) { mNetd.networkSetPermissionForUser(PERMISSION_NETWORK, convertToIntArray(network)); mNetd.networkSetPermissionForUser(PERMISSION_SYSTEM, convertToIntArray(system)); mNetd.networkSetPermissionForUser(INetd.PERMISSION_NETWORK, toIntArray(network)); mNetd.networkSetPermissionForUser(INetd.PERMISSION_SYSTEM, toIntArray(system)); } else { mNetd.networkClearPermissionForUser(convertToIntArray(network)); mNetd.networkClearPermissionForUser(convertToIntArray(system)); mNetd.networkClearPermissionForUser(toIntArray(network)); mNetd.networkClearPermissionForUser(toIntArray(system)); } } catch (RemoteException e) { loge("Exception when updating permissions: " + e); Loading Loading @@ -321,15 +323,14 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse } @VisibleForTesting protected Boolean highestPermissionForUid(Boolean currentPermission, String name, int uid) { protected Boolean highestPermissionForUid(Boolean currentPermission, String name) { if (currentPermission == SYSTEM) { return currentPermission; } try { final PackageInfo app = mPackageManager.getPackageInfo(name, GET_PERMISSIONS); final boolean isNetwork = hasPermission(CHANGE_NETWORK_STATE, uid); final boolean hasRestrictedPermission = hasRestrictedNetworkPermission(app.applicationInfo); final boolean isNetwork = hasNetworkPermission(app); final boolean hasRestrictedPermission = hasRestrictedNetworkPermission(app); if (isNetwork || hasRestrictedPermission) { currentPermission = hasRestrictedPermission; } Loading @@ -341,14 +342,23 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse } private int getPermissionForUid(final int uid) { int permission = INetd.PERMISSION_NONE; // Check all the packages for this UID. The UID has the permission if any of the // packages in it has the permission. final String[] packages = mPackageManager.getPackagesForUid(uid); if (packages == null || packages.length <= 0) { if (packages != null && packages.length > 0) { for (String name : packages) { final PackageInfo app = getPackageInfo(name); if (app != null && app.requestedPermissions != null) { permission |= getNetdPermissionMask(app.requestedPermissions, app.requestedPermissionsFlags); } } } else { // The last package of this uid is removed from device. Clean the package up. return PERMISSION_UNINSTALLED; permission = INetd.PERMISSION_UNINSTALLED; } return getNetdPermissionMask(uid); return permission; } /** Loading @@ -365,7 +375,7 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse // 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(uid), packageName, uid); final Boolean permission = highestPermissionForUid(mApps.get(uid), packageName); if (permission != mApps.get(uid)) { mApps.put(uid, permission); Loading Loading @@ -421,7 +431,7 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse String[] packages = mPackageManager.getPackagesForUid(uid); if (packages != null && packages.length > 0) { for (String name : packages) { permission = highestPermissionForUid(permission, name, uid); 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. Loading Loading @@ -457,13 +467,19 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse sendPackagePermissionsForUid(uid, getPermissionForUid(uid)); } private int getNetdPermissionMask(final int uid) { int permissions = PERMISSION_NONE; if (hasPermission(INTERNET, uid)) { permissions |= PERMISSION_INTERNET; private static int getNetdPermissionMask(String[] requestedPermissions, int[] requestedPermissionsFlags) { int permissions = 0; if (requestedPermissions == null || requestedPermissionsFlags == null) return permissions; for (int i = 0; i < requestedPermissions.length; i++) { if (requestedPermissions[i].equals(INTERNET) && ((requestedPermissionsFlags[i] & REQUESTED_PERMISSION_GRANTED) != 0)) { permissions |= INetd.PERMISSION_INTERNET; } if (requestedPermissions[i].equals(UPDATE_DEVICE_STATS) && ((requestedPermissionsFlags[i] & REQUESTED_PERMISSION_GRANTED) != 0)) { permissions |= INetd.PERMISSION_UPDATE_DEVICE_STATS; } if (hasPermission(UPDATE_DEVICE_STATS, uid)) { permissions |= PERMISSION_UPDATE_DEVICE_STATS; } return permissions; } Loading Loading @@ -632,19 +648,19 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse for (int i = 0; i < netdPermissionsAppIds.size(); i++) { int permissions = netdPermissionsAppIds.valueAt(i); switch(permissions) { case (PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS): case (INetd.PERMISSION_INTERNET | INetd.PERMISSION_UPDATE_DEVICE_STATS): allPermissionAppIds.add(netdPermissionsAppIds.keyAt(i)); break; case PERMISSION_INTERNET: case INetd.PERMISSION_INTERNET: internetPermissionAppIds.add(netdPermissionsAppIds.keyAt(i)); break; case PERMISSION_UPDATE_DEVICE_STATS: case INetd.PERMISSION_UPDATE_DEVICE_STATS: updateStatsPermissionAppIds.add(netdPermissionsAppIds.keyAt(i)); break; case PERMISSION_NONE: case INetd.PERMISSION_NONE: noPermissionAppIds.add(netdPermissionsAppIds.keyAt(i)); break; case PERMISSION_UNINSTALLED: case INetd.PERMISSION_UNINSTALLED: uninstalledAppIds.add(netdPermissionsAppIds.keyAt(i)); default: Log.e(TAG, "unknown permission type: " + permissions + "for uid: " Loading @@ -655,24 +671,24 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse // TODO: add a lock inside netd to protect IPC trafficSetNetPermForUids() if (allPermissionAppIds.size() != 0) { mNetd.trafficSetNetPermForUids( PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS, convertToIntArray(allPermissionAppIds)); INetd.PERMISSION_INTERNET | INetd.PERMISSION_UPDATE_DEVICE_STATS, ArrayUtils.convertToIntArray(allPermissionAppIds)); } if (internetPermissionAppIds.size() != 0) { mNetd.trafficSetNetPermForUids(PERMISSION_INTERNET, convertToIntArray(internetPermissionAppIds)); mNetd.trafficSetNetPermForUids(INetd.PERMISSION_INTERNET, ArrayUtils.convertToIntArray(internetPermissionAppIds)); } if (updateStatsPermissionAppIds.size() != 0) { mNetd.trafficSetNetPermForUids(PERMISSION_UPDATE_DEVICE_STATS, convertToIntArray(updateStatsPermissionAppIds)); mNetd.trafficSetNetPermForUids(INetd.PERMISSION_UPDATE_DEVICE_STATS, ArrayUtils.convertToIntArray(updateStatsPermissionAppIds)); } if (noPermissionAppIds.size() != 0) { mNetd.trafficSetNetPermForUids(PERMISSION_NONE, convertToIntArray(noPermissionAppIds)); mNetd.trafficSetNetPermForUids(INetd.PERMISSION_NONE, ArrayUtils.convertToIntArray(noPermissionAppIds)); } if (uninstalledAppIds.size() != 0) { mNetd.trafficSetNetPermForUids(PERMISSION_UNINSTALLED, convertToIntArray(uninstalledAppIds)); mNetd.trafficSetNetPermForUids(INetd.PERMISSION_UNINSTALLED, ArrayUtils.convertToIntArray(uninstalledAppIds)); } } catch (RemoteException e) { Log.e(TAG, "Pass appId list of special permission failed." + e); Loading
tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java +122 −86 File changed.Preview size limit exceeded, changes collapsed. Show changes