diff options
author | Svet Ganov <svetoslavganov@google.com> | 2015-03-25 22:57:39 -0700 |
---|---|---|
committer | Svet Ganov <svetoslavganov@google.com> | 2015-03-25 23:48:17 -0700 |
commit | d5752bdc8fd39d4f0a508f9088c538e30e73044a (patch) | |
tree | 3526cfdef1e846671a81778917b9f3cfc71c189d | |
parent | 4976d6b52588772117dff43fb814fe6661bfe598 (diff) | |
download | frameworks_base-d5752bdc8fd39d4f0a508f9088c538e30e73044a.zip frameworks_base-d5752bdc8fd39d4f0a508f9088c538e30e73044a.tar.gz frameworks_base-d5752bdc8fd39d4f0a508f9088c538e30e73044a.tar.bz2 |
Properly handle system app permissions - for real.
System apps targeting SDK greater than Lollipop MR1 get runtime
permissions by default but if the user takes them away we should
not regrant them. To do that we keep track for each package which
user ids were handled in the last permissions update. If a new
user id has appeared we grant runtime permissions for this user
to the sys package. When we start clean (i.e. first boot) the
sys packages were updated for no user so we grant the runtime
perms for the owner. When reading a package from packages.xml
we set the updated user ids to all users ids on the device as
the state in the xml reflects the latest state before a shutdown,
i.e. the last state when permissions were updated.
Change-Id: I93135baa57950405a357b139c59f432cf02f0bc6
5 files changed, 69 insertions, 12 deletions
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 5d3b0f1..4dfb161 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -6967,6 +6967,10 @@ public class PackageManagerService extends IPackageManager.Stub { PermissionsState permissionsState = ps.getPermissionsState(); PermissionsState origPermissions = permissionsState; + final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); + + int[] upgradeUserIds = PermissionsState.USERS_NONE; + boolean changedPermission = false; if (replace) { @@ -7022,16 +7026,32 @@ public class PackageManagerService extends IPackageManager.Stub { // For legacy apps dangerous permissions are install time ones. grant = GRANT_INSTALL; } else if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { - // For modern system apps dangerous permissions are runtime ones. - grant = GRANT_UPGRADE; - } else { + final int[] updatedUserIds = ps.getPermissionsUpdatedForUserIds(); if (origPermissions.hasInstallPermission(bp.name)) { - // For legacy apps that became modern, install becomes runtime. + // If a system app had an install permission, then the app was + // upgraded and we grant the permissions as runtime to all users. + grant = GRANT_UPGRADE; + upgradeUserIds = currentUserIds; + } else if (!Arrays.equals(updatedUserIds, currentUserIds)) { + // If users changed since the last permissions update for a + // system app, we grant the permission as runtime to the new users. grant = GRANT_UPGRADE; - } else if (replace) { - // For upgraded modern apps keep runtime permissions unchanged. + upgradeUserIds = currentUserIds; + for (int userId : updatedUserIds) { + upgradeUserIds = ArrayUtils.removeInt(upgradeUserIds, userId); + } + } else { + // Otherwise, we grant the permission as runtime if the app + // already had it, i.e. we preserve runtime permissions. grant = GRANT_RUNTIME; } + } else if (origPermissions.hasInstallPermission(bp.name)) { + // For legacy apps that became modern, install becomes runtime. + grant = GRANT_UPGRADE; + upgradeUserIds = currentUserIds; + } else if (replace) { + // For upgraded modern apps keep runtime permissions unchanged. + grant = GRANT_RUNTIME; } } break; @@ -7086,7 +7106,7 @@ public class PackageManagerService extends IPackageManager.Stub { case GRANT_UPGRADE: { // Grant runtime permissions for a previously held install permission. permissionsState.revokeInstallPermission(bp); - for (int userId : UserManagerService.getInstance().getUserIds()) { + for (int userId : upgradeUserIds) { if (permissionsState.grantRuntimePermission(bp, userId) != PermissionsState.PERMISSION_OPERATION_FAILURE) { changedPermission = true; @@ -7133,6 +7153,8 @@ public class PackageManagerService extends IPackageManager.Stub { // changed. ps.permissionsFixed = true; } + + ps.setPermissionsUpdatedForUserIds(currentUserIds); } private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) { diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java index 9e8b3df..c40784b 100644 --- a/services/core/java/com/android/server/pm/PackageSettingBase.java +++ b/services/core/java/com/android/server/pm/PackageSettingBase.java @@ -198,6 +198,7 @@ abstract class PackageSettingBase extends SettingBase { * Make a shallow copy of this package settings. */ public void copyFrom(PackageSettingBase base) { + setPermissionsUpdatedForUserIds(base.getPermissionsUpdatedForUserIds()); getPermissionsState().copyFrom(base.getPermissionsState()); primaryCpuAbiString = base.primaryCpuAbiString; secondaryCpuAbiString = base.secondaryCpuAbiString; diff --git a/services/core/java/com/android/server/pm/PermissionsState.java b/services/core/java/com/android/server/pm/PermissionsState.java index 3e0e342..705abf8 100644 --- a/services/core/java/com/android/server/pm/PermissionsState.java +++ b/services/core/java/com/android/server/pm/PermissionsState.java @@ -55,9 +55,9 @@ public final class PermissionsState { /** The permission operation failed. */ public static final int PERMISSION_OPERATION_FAILURE = 3; - private static final int[] USERS_ALL = {UserHandle.USER_ALL}; + public static final int[] USERS_ALL = {UserHandle.USER_ALL}; - private static final int[] USERS_NONE = {}; + public static final int[] USERS_NONE = {}; private static final int[] NO_GIDS = {}; @@ -149,6 +149,9 @@ public final class PermissionsState { * #PERMISSION_OPERATION_FAILURE}. */ public int grantRuntimePermission(BasePermission permission, int userId) { + if (userId == UserHandle.USER_ALL) { + return PERMISSION_OPERATION_FAILURE; + } return grantPermission(permission, userId); } @@ -162,6 +165,9 @@ public final class PermissionsState { * #PERMISSION_OPERATION_FAILURE}. */ public int revokeRuntimePermission(BasePermission permission, int userId) { + if (userId == UserHandle.USER_ALL) { + return PERMISSION_OPERATION_FAILURE; + } return revokePermission(permission, userId); } diff --git a/services/core/java/com/android/server/pm/SettingBase.java b/services/core/java/com/android/server/pm/SettingBase.java index d350c09..3a7b6ee 100644 --- a/services/core/java/com/android/server/pm/SettingBase.java +++ b/services/core/java/com/android/server/pm/SettingBase.java @@ -17,13 +17,15 @@ package com.android.server.pm; import android.content.pm.ApplicationInfo; -import android.util.ArraySet; + +import java.util.Arrays; abstract class SettingBase { int pkgFlags; int pkgPrivateFlags; private final PermissionsState mPermissionsState; + private int[] mPermissionsUpdatedForUserIds = PermissionsState.USERS_NONE; SettingBase(int pkgFlags, int pkgPrivateFlags) { setFlags(pkgFlags); @@ -35,12 +37,29 @@ abstract class SettingBase { pkgFlags = base.pkgFlags; pkgPrivateFlags = base.pkgPrivateFlags; mPermissionsState = new PermissionsState(base.mPermissionsState); + setPermissionsUpdatedForUserIds(base.mPermissionsUpdatedForUserIds); } public PermissionsState getPermissionsState() { return mPermissionsState; } + public int[] getPermissionsUpdatedForUserIds() { + return mPermissionsUpdatedForUserIds; + } + + public void setPermissionsUpdatedForUserIds(int[] userIds) { + if (Arrays.equals(mPermissionsUpdatedForUserIds, userIds)) { + return; + } + + if (userIds == PermissionsState.USERS_NONE || userIds == PermissionsState.USERS_ALL) { + mPermissionsUpdatedForUserIds = userIds; + } else { + mPermissionsUpdatedForUserIds = Arrays.copyOf(userIds, userIds.length); + } + } + void setFlags(int pkgFlags) { this.pkgFlags = pkgFlags & (ApplicationInfo.FLAG_SYSTEM diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 82aa74a..95ee990 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -2253,6 +2253,17 @@ final class Settings { mReadMessages.append("Read completed successfully: " + mPackages.size() + " packages, " + mSharedUsers.size() + " shared uids\n"); + // The persisted state we just read was generated after a permissions + // update for all users, update each package and shared user setting + // with the device users ids to start from were we left off. + final int[] userIds = UserManagerService.getInstance().getUserIds(); + for (PackageSetting ps : mPackages.values()) { + ps.setPermissionsUpdatedForUserIds(userIds); + } + for (SharedUserSetting sus : mSharedUsers.values()) { + sus.setPermissionsUpdatedForUserIds(userIds); + } + return true; } @@ -3010,8 +3021,6 @@ final class Settings { XmlUtils.skipCurrentTag(parser); } } - - } else { XmlUtils.skipCurrentTag(parser); } |