diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 4e9b59fe6b181..9c0aa35da9a43 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -111,6 +111,7 @@
+
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index a99a2ee22e5f0..891dd9a52294c 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -17509,6 +17509,14 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
throw new IllegalArgumentException(
"Unknown component: " + packageName + "/" + className);
}
+ // Don't allow other apps to disable an active profile owner
+ if (!UserHandle.isSameApp(uid, pkgSetting.appId)) {
+ final DevicePolicyManagerInternal dpmi = LocalServices
+ .getService(DevicePolicyManagerInternal.class);
+ if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
+ throw new SecurityException("Cannot disable a device owner or a profile owner");
+ }
+ }
// Allow root and verify that userId is not being specified by a different user
if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) {
throw new SecurityException(
@@ -17516,6 +17524,25 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
+ Binder.getCallingPid()
+ ", uid=" + uid + ", package uid=" + pkgSetting.appId);
}
+ if (uid == Process.SHELL_UID) {
+ // Shell can only change whole packages between ENABLED and DISABLED_USER states
+ int oldState = pkgSetting.getEnabled(userId);
+ if (className == null
+ &&
+ (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
+ || oldState == COMPONENT_ENABLED_STATE_DEFAULT
+ || oldState == COMPONENT_ENABLED_STATE_ENABLED)
+ &&
+ (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
+ || newState == COMPONENT_ENABLED_STATE_DEFAULT
+ || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
+ // ok
+ } else {
+ throw new SecurityException(
+ "Shell cannot change component state for " + packageName + "/"
+ + className + " to " + newState);
+ }
+ }
if (className == null) {
// We're dealing with an application/package level state change
if (pkgSetting.getEnabled(userId) == newState) {