summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/content/pm/PackageManager.java12
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java167
-rw-r--r--services/core/java/com/android/server/pm/Settings.java55
3 files changed, 155 insertions, 79 deletions
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 49386f9..62c2e8c 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -4627,12 +4627,12 @@ public abstract class PackageManager {
/** {@hide} */
public static String permissionFlagToString(int flag) {
switch (flag) {
- case FLAG_PERMISSION_GRANTED_BY_DEFAULT: return "FLAG_PERMISSION_GRANTED_BY_DEFAULT";
- case FLAG_PERMISSION_POLICY_FIXED: return "FLAG_PERMISSION_POLICY_FIXED";
- case FLAG_PERMISSION_SYSTEM_FIXED: return "FLAG_PERMISSION_SYSTEM_FIXED";
- case FLAG_PERMISSION_USER_SET: return "FLAG_PERMISSION_USER_SET";
- case FLAG_PERMISSION_REVOKE_ON_UPGRADE: return "FLAG_PERMISSION_REVOKE_ON_UPGRADE";
- case FLAG_PERMISSION_USER_FIXED: return "FLAG_PERMISSION_USER_FIXED";
+ case FLAG_PERMISSION_GRANTED_BY_DEFAULT: return "GRANTED_BY_DEFAULT";
+ case FLAG_PERMISSION_POLICY_FIXED: return "POLICY_FIXED";
+ case FLAG_PERMISSION_SYSTEM_FIXED: return "SYSTEM_FIXED";
+ case FLAG_PERMISSION_USER_SET: return "USER_SET";
+ case FLAG_PERMISSION_REVOKE_ON_UPGRADE: return "REVOKE_ON_UPGRADE";
+ case FLAG_PERMISSION_USER_FIXED: return "USER_FIXED";
default: return Integer.toString(flag);
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 124214c..ed20345 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -25,6 +25,12 @@ import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
import static android.content.pm.PackageManager.INSTALL_EXTERNAL;
import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
@@ -72,6 +78,9 @@ import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
+import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE;
+import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS;
+import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
import android.Manifest;
import android.app.ActivityManager;
@@ -12665,7 +12674,7 @@ public class PackageManagerService extends IPackageManager.Stub {
KILL_APP_REASON_GIDS_CHANGED);
}
});
- break;
+ break;
}
}
}
@@ -12781,8 +12790,14 @@ public class PackageManagerService extends IPackageManager.Stub {
// writer
synchronized (mPackages) {
PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
+
+ // Propagate the permissions state as we do want to drop on the floor
+ // runtime permissions. The update permissions method below will take
+ // care of removing obsolete permissions and grant install permissions.
+ ps.getPermissionsState().copyFrom(disabledPs.getPermissionsState());
updatePermissionsLPw(newPkg.packageName, newPkg,
UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
+
if (applyUserRestrictions) {
if (DEBUG_REMOVE) {
Slog.d(TAG, "Propagating install state across reinstall");
@@ -12943,8 +12958,7 @@ public class PackageManagerService extends IPackageManager.Stub {
if (clearPackagePreferredActivitiesLPw(packageName, removeUser)) {
scheduleWritePackageRestrictionsLocked(removeUser);
}
- revokeRuntimePermissionsAndClearAllFlagsLocked(ps.getPermissionsState(),
- removeUser);
+ resetUserChangesToRuntimePermissionsAndFlagsLocked(ps, removeUser);
}
return true;
}
@@ -13105,8 +13119,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
PackageSetting ps = (PackageSetting) pkg.mExtras;
- PermissionsState permissionsState = ps.getPermissionsState();
- revokeRuntimePermissionsAndClearUserSetFlagsLocked(permissionsState, userId);
+ resetUserChangesToRuntimePermissionsAndFlagsLocked(ps, userId);
}
// Always delete data directories for package, even if we found no other
@@ -13137,66 +13150,118 @@ public class PackageManagerService extends IPackageManager.Stub {
return true;
}
-
/**
- * Revokes granted runtime permissions and clears resettable flags
- * which are flags that can be set by a user interaction.
+ * Reverts user permission state changes (permissions and flags).
*
- * @param permissionsState The permission state to reset.
+ * @param ps The package for which to reset.
* @param userId The device user for which to do a reset.
*/
- private void revokeRuntimePermissionsAndClearUserSetFlagsLocked(
- PermissionsState permissionsState, int userId) {
- final int userSetFlags = PackageManager.FLAG_PERMISSION_USER_SET
- | PackageManager.FLAG_PERMISSION_USER_FIXED
- | PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
+ private void resetUserChangesToRuntimePermissionsAndFlagsLocked(
+ final PackageSetting ps, final int userId) {
+ if (ps.pkg == null) {
+ return;
+ }
- revokeRuntimePermissionsAndClearFlagsLocked(permissionsState, userId, userSetFlags);
- }
+ final int userSettableFlags = FLAG_PERMISSION_USER_SET
+ | FLAG_PERMISSION_USER_FIXED
+ | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
- /**
- * Revokes granted runtime permissions and clears all flags.
- *
- * @param permissionsState The permission state to reset.
- * @param userId The device user for which to do a reset.
- */
- private void revokeRuntimePermissionsAndClearAllFlagsLocked(
- PermissionsState permissionsState, int userId) {
- revokeRuntimePermissionsAndClearFlagsLocked(permissionsState, userId,
- PackageManager.MASK_PERMISSION_FLAGS);
- }
+ final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
+ | FLAG_PERMISSION_POLICY_FIXED;
- /**
- * Revokes granted runtime permissions and clears certain flags.
- *
- * @param permissionsState The permission state to reset.
- * @param userId The device user for which to do a reset.
- * @param flags The flags that is going to be reset.
- */
- private void revokeRuntimePermissionsAndClearFlagsLocked(
- PermissionsState permissionsState, final int userId, int flags) {
- boolean needsWrite = false;
+ boolean writeInstallPermissions = false;
+ boolean writeRuntimePermissions = false;
- for (PermissionState state : permissionsState.getRuntimePermissionStates(userId)) {
- BasePermission bp = mSettings.mPermissions.get(state.getName());
- if (bp != null) {
- permissionsState.revokeRuntimePermission(bp, userId);
- permissionsState.updatePermissionFlags(bp, userId, flags, 0);
- needsWrite = true;
+ final int permissionCount = ps.pkg.requestedPermissions.size();
+ for (int i = 0; i < permissionCount; i++) {
+ String permission = ps.pkg.requestedPermissions.get(i);
+
+ BasePermission bp = mSettings.mPermissions.get(permission);
+ if (bp == null) {
+ continue;
}
- }
- // Ensure default permissions are never cleared.
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mDefaultPermissionPolicy.grantDefaultPermissions(userId);
+ // If shared user we just reset the state to which only this app contributed.
+ if (ps.sharedUser != null) {
+ boolean used = false;
+ final int packageCount = ps.sharedUser.packages.size();
+ for (int j = 0; j < packageCount; j++) {
+ PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
+ if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
+ && pkg.pkg.requestedPermissions.contains(permission)) {
+ used = true;
+ break;
+ }
+ }
+ if (used) {
+ continue;
+ }
}
- });
- if (needsWrite) {
+ PermissionsState permissionsState = ps.getPermissionsState();
+
+ final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId);
+
+ // Always clear the user settable flags.
+ final boolean hasInstallState = permissionsState.getInstallPermissionState(
+ bp.name) != null;
+ if (permissionsState.updatePermissionFlags(bp, userId, userSettableFlags, 0)) {
+ if (hasInstallState) {
+ writeInstallPermissions = true;
+ } else {
+ writeRuntimePermissions = true;
+ }
+ }
+
+ // Below is only runtime permission handling.
+ if (!bp.isRuntime()) {
+ continue;
+ }
+
+ // Never clobber system or policy.
+ if ((oldFlags & policyOrSystemFlags) != 0) {
+ continue;
+ }
+
+ // If this permission was granted by default, make sure it is.
+ if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
+ if (permissionsState.grantRuntimePermission(bp, userId)
+ != PERMISSION_OPERATION_FAILURE) {
+ writeRuntimePermissions = true;
+ }
+ } else {
+ // Otherwise, reset the permission.
+ final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
+ switch (revokeResult) {
+ case PERMISSION_OPERATION_SUCCESS: {
+ writeRuntimePermissions = true;
+ } break;
+
+ case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
+ writeRuntimePermissions = true;
+ // If gids changed for this user, kill all affected packages.
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ // This has to happen with no lock held.
+ killSettingPackagesForUser(ps, userId,
+ KILL_APP_REASON_GIDS_CHANGED);
+ }
+ });
+ } break;
+ }
+ }
+ }
+
+ // Synchronously write as we are taking permissions away.
+ if (writeRuntimePermissions) {
mSettings.writeRuntimePermissionsForUserLPr(userId, true);
}
+
+ // Synchronously write as we are taking permissions away.
+ if (writeInstallPermissions) {
+ mSettings.writeLPr();
+ }
}
/**
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 4e85e39..bdcd714 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -824,14 +824,8 @@ final class Settings {
continue;
}
- // If no user has the permission, nothing to remove.
- if (!sus.getPermissionsState().hasPermission(bp.name, userId)) {
- continue;
- }
-
- boolean used = false;
-
// Check if another package in the shared user needs the permission.
+ boolean used = false;
for (PackageSetting pkg : sus.packages) {
if (pkg.pkg != null
&& !pkg.pkg.packageName.equals(deletedPs.pkg.packageName)
@@ -840,26 +834,43 @@ final class Settings {
break;
}
}
+ if (used) {
+ continue;
+ }
- if (!used) {
- PermissionsState permissionsState = sus.getPermissionsState();
-
- // Try to revoke as an install permission which is for all users.
- // The package is gone - no need to keep flags for applying policy.
- permissionsState.updatePermissionFlags(bp, userId,
- PackageManager.MASK_PERMISSION_FLAGS, 0);
+ PermissionsState permissionsState = sus.getPermissionsState();
+ PackageSetting disabledPs = getDisabledSystemPkgLPr(deletedPs.pkg.packageName);
- if (permissionsState.revokeInstallPermission(bp) ==
- PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED) {
- return UserHandle.USER_ALL;
+ // If the package is shadowing is a disabled system package,
+ // do not drop permissions that the shadowed package requests.
+ if (disabledPs != null) {
+ boolean reqByDisabledSysPkg = false;
+ for (String permission : disabledPs.pkg.requestedPermissions) {
+ if (permission.equals(eachPerm)) {
+ reqByDisabledSysPkg = true;
+ break;
+ }
}
-
- // Try to revoke as an install permission which is per user.
- if (permissionsState.revokeRuntimePermission(bp, userId) ==
- PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED) {
- return userId;
+ if (reqByDisabledSysPkg) {
+ continue;
}
}
+
+ // Try to revoke as an install permission which is for all users.
+ // The package is gone - no need to keep flags for applying policy.
+ permissionsState.updatePermissionFlags(bp, userId,
+ PackageManager.MASK_PERMISSION_FLAGS, 0);
+
+ if (permissionsState.revokeInstallPermission(bp) ==
+ PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED) {
+ return UserHandle.USER_ALL;
+ }
+
+ // Try to revoke as an install permission which is per user.
+ if (permissionsState.revokeRuntimePermission(bp, userId) ==
+ PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED) {
+ return userId;
+ }
}
return UserHandle.USER_NULL;