2023-08-21 16:49:51 -04:00
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
|
From: Dmitry Muhomor <muhomor.dmitry@gmail.com>
|
|
|
|
Date: Mon, 27 Mar 2023 16:00:00 +0300
|
2023-08-21 17:56:38 -04:00
|
|
|
Subject: [PATCH] add hooks for modifying PackageManagerService behavior
|
2023-08-21 16:49:51 -04:00
|
|
|
|
|
|
|
---
|
|
|
|
.../server/ext/PackageManagerHooks.java | 90 +++++++++++++++++++
|
|
|
|
.../com/android/server/pm/AppsFilterBase.java | 6 ++
|
|
|
|
.../java/com/android/server/pm/Settings.java | 8 +-
|
|
|
|
.../PermissionManagerServiceImpl.java | 13 +++
|
|
|
|
.../pm/pkg/parsing/ParsingPackageUtils.java | 3 +
|
|
|
|
5 files changed, 118 insertions(+), 2 deletions(-)
|
|
|
|
create mode 100644 services/core/java/com/android/server/ext/PackageManagerHooks.java
|
|
|
|
|
|
|
|
diff --git a/services/core/java/com/android/server/ext/PackageManagerHooks.java b/services/core/java/com/android/server/ext/PackageManagerHooks.java
|
|
|
|
new file mode 100644
|
|
|
|
index 000000000000..007b65349e55
|
|
|
|
--- /dev/null
|
|
|
|
+++ b/services/core/java/com/android/server/ext/PackageManagerHooks.java
|
|
|
|
@@ -0,0 +1,90 @@
|
|
|
|
+package com.android.server.ext;
|
|
|
|
+
|
|
|
|
+import android.Manifest;
|
|
|
|
+import android.annotation.Nullable;
|
|
|
|
+import android.annotation.UserIdInt;
|
|
|
|
+import android.content.pm.PackageManager;
|
|
|
|
+import android.content.pm.PackageManagerInternal;
|
|
|
|
+import android.os.Build;
|
|
|
|
+import android.os.UserHandle;
|
|
|
|
+import android.util.ArraySet;
|
|
|
|
+
|
|
|
|
+import com.android.server.pm.parsing.pkg.AndroidPackage;
|
|
|
|
+import com.android.server.pm.permission.Permission;
|
|
|
|
+import com.android.server.pm.pkg.PackageStateInternal;
|
|
|
|
+import com.android.server.pm.pkg.parsing.ParsingPackage;
|
|
|
|
+
|
|
|
|
+public class PackageManagerHooks {
|
|
|
|
+
|
|
|
|
+ // Called when package enabled setting is deserialized from storage
|
|
|
|
+ @Nullable
|
|
|
|
+ public static Integer maybeOverridePackageEnabledSetting(String pkgName, @UserIdInt int userId) {
|
|
|
|
+ switch (pkgName) {
|
|
|
|
+ default:
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Called when package parsing is completed
|
|
|
|
+ public static void amendParsedPackage(ParsingPackage pkg) {
|
|
|
|
+ String pkgName = pkg.getPackageName();
|
|
|
|
+
|
|
|
|
+ switch (pkgName) {
|
|
|
|
+ default:
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public static void removeUsesPermissions(ParsingPackage pkg, String... perms) {
|
|
|
|
+ var set = new ArraySet<>(perms);
|
|
|
|
+ pkg.getRequestedPermissions().removeAll(set);
|
|
|
|
+ pkg.getUsesPermissions().removeIf(p -> set.contains(p.getName()));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public static boolean shouldBlockGrantRuntimePermission(
|
|
|
|
+ PackageManagerInternal pm, String permName, String packageName, int userId)
|
|
|
|
+ {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public static boolean shouldForciblyGrantPermission(AndroidPackage pkg, Permission perm) {
|
|
|
|
+ if (!Build.IS_DEBUGGABLE) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ String permName = perm.getName();
|
|
|
|
+
|
|
|
|
+ switch (pkg.getPackageName()) {
|
|
|
|
+ default:
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Called when AppsFilter decides whether to restrict package visibility
|
|
|
|
+ public static boolean shouldFilterAccess(@Nullable PackageStateInternal callingPkgSetting,
|
|
|
|
+ ArraySet<PackageStateInternal> callingSharedPkgSettings,
|
|
|
|
+ PackageStateInternal targetPkgSetting) {
|
|
|
|
+ if (callingPkgSetting != null && restrictedVisibilityPackages.contains(callingPkgSetting.getPackageName())) {
|
|
|
|
+ if (!targetPkgSetting.isSystem()) {
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (restrictedVisibilityPackages.contains(targetPkgSetting.getPackageName())) {
|
|
|
|
+ if (callingPkgSetting != null) {
|
|
|
|
+ return !callingPkgSetting.isSystem();
|
|
|
|
+ } else {
|
|
|
|
+ for (int i = callingSharedPkgSettings.size() - 1; i >= 0; i--) {
|
|
|
|
+ if (!callingSharedPkgSettings.valueAt(i).isSystem()) {
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Packages in this array are restricted from interacting with and being interacted by non-system apps
|
|
|
|
+ private static final ArraySet<String> restrictedVisibilityPackages = new ArraySet<>(new String[] {
|
|
|
|
+ });
|
|
|
|
+}
|
|
|
|
diff --git a/services/core/java/com/android/server/pm/AppsFilterBase.java b/services/core/java/com/android/server/pm/AppsFilterBase.java
|
|
|
|
index 07746236320e..e2d413419d6a 100644
|
|
|
|
--- a/services/core/java/com/android/server/pm/AppsFilterBase.java
|
|
|
|
+++ b/services/core/java/com/android/server/pm/AppsFilterBase.java
|
|
|
|
@@ -39,6 +39,7 @@ import android.util.SparseArray;
|
|
|
|
import com.android.internal.annotations.VisibleForTesting;
|
|
|
|
import com.android.internal.util.ArrayUtils;
|
|
|
|
import com.android.internal.util.function.QuadFunction;
|
|
|
|
+import com.android.server.ext.PackageManagerHooks;
|
|
|
|
import com.android.server.om.OverlayReferenceMapper;
|
|
|
|
import com.android.server.pm.parsing.pkg.AndroidPackage;
|
|
|
|
import com.android.server.pm.pkg.PackageStateInternal;
|
|
|
|
@@ -414,6 +415,11 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot {
|
|
|
|
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
|
|
|
|
}
|
|
|
|
|
|
|
|
+ if (PackageManagerHooks.shouldFilterAccess(callingPkgSetting, callingSharedPkgSettings,
|
|
|
|
+ targetPkgSetting)) {
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
if (callingPkgSetting != null) {
|
|
|
|
if (callingPkgSetting.getPkg() != null
|
|
|
|
&& !mFeatureConfig.packageIsEnabled(callingPkgSetting.getPkg())) {
|
|
|
|
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
|
|
|
|
index a9b624653b92..9cac3e75a698 100644
|
|
|
|
--- a/services/core/java/com/android/server/pm/Settings.java
|
|
|
|
+++ b/services/core/java/com/android/server/pm/Settings.java
|
|
|
|
@@ -100,6 +100,7 @@ import com.android.permission.persistence.RuntimePermissionsPersistence;
|
|
|
|
import com.android.permission.persistence.RuntimePermissionsState;
|
|
|
|
import com.android.server.LocalServices;
|
|
|
|
import com.android.server.backup.PreferredActivityBackupHelper;
|
|
|
|
+import com.android.server.ext.PackageManagerHooks;
|
|
|
|
import com.android.server.pm.Installer.InstallerException;
|
|
|
|
import com.android.server.pm.parsing.PackageInfoUtils;
|
|
|
|
import com.android.server.pm.parsing.pkg.AndroidPackage;
|
|
|
|
@@ -1810,8 +1811,11 @@ public final class Settings implements Watchable, Snappable {
|
|
|
|
parser.getAttributeBoolean(null, ATTR_INSTANT_APP, false);
|
|
|
|
final boolean virtualPreload =
|
|
|
|
parser.getAttributeBoolean(null, ATTR_VIRTUAL_PRELOAD, false);
|
|
|
|
- final int enabled = parser.getAttributeInt(null, ATTR_ENABLED,
|
|
|
|
- COMPONENT_ENABLED_STATE_DEFAULT);
|
|
|
|
+ final Integer enabledOverride =
|
|
|
|
+ PackageManagerHooks.maybeOverridePackageEnabledSetting(name, userId);
|
|
|
|
+ final int enabled = (enabledOverride != null) ?
|
|
|
|
+ enabledOverride.intValue() :
|
|
|
|
+ parser.getAttributeInt(null, ATTR_ENABLED, COMPONENT_ENABLED_STATE_DEFAULT);
|
|
|
|
final String enabledCaller = parser.getAttributeValue(null,
|
|
|
|
ATTR_ENABLED_CALLER);
|
|
|
|
final String harmfulAppWarning =
|
|
|
|
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
|
2024-06-13 18:29:22 -04:00
|
|
|
index 556443b40c3d..ac5aadd45467 100644
|
2023-08-21 16:49:51 -04:00
|
|
|
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
|
|
|
|
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
|
|
|
|
@@ -127,6 +127,7 @@ import com.android.server.LocalServices;
|
|
|
|
import com.android.server.ServiceThread;
|
|
|
|
import com.android.server.SystemConfig;
|
|
|
|
import com.android.server.Watchdog;
|
|
|
|
+import com.android.server.ext.PackageManagerHooks;
|
|
|
|
import com.android.server.pm.ApexManager;
|
|
|
|
import com.android.server.pm.KnownPackages;
|
|
|
|
import com.android.server.pm.UserManagerInternal;
|
2024-06-13 18:29:22 -04:00
|
|
|
@@ -1364,6 +1365,13 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
|
2023-08-21 16:49:51 -04:00
|
|
|
isRolePermission = permission.isRole();
|
|
|
|
isSoftRestrictedPermission = permission.isSoftRestricted();
|
|
|
|
}
|
|
|
|
+
|
|
|
|
+ if (PackageManagerHooks.shouldBlockGrantRuntimePermission(mPackageManagerInt, permName, packageName, userId)) {
|
|
|
|
+ // this method is called from within system_server and from critical system processes,
|
|
|
|
+ // do not throw an exception, just return
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
final boolean mayGrantRolePermission = isRolePermission
|
|
|
|
&& mayManageRolePermission(callingUid);
|
|
|
|
final boolean mayGrantSoftRestrictedPermission = isSoftRestrictedPermission
|
2024-06-13 18:29:22 -04:00
|
|
|
@@ -2983,6 +2991,11 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
|
2023-08-21 16:49:51 -04:00
|
|
|
Slog.wtf(LOG_TAG, "Unknown permission protection " + bp.getProtection()
|
|
|
|
+ " for permission " + bp.getName());
|
|
|
|
}
|
|
|
|
+
|
|
|
|
+ if (Build.IS_DEBUGGABLE && PackageManagerHooks.shouldForciblyGrantPermission(pkg, bp)) {
|
|
|
|
+ uidState.grantPermission(bp);
|
|
|
|
+ Slog.d(TAG, "forcibly granted " + bp.getName() + " to " + pkg.getPackageName());
|
|
|
|
+ }
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((changedInstallPermission || replace)
|
|
|
|
diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
|
|
|
|
index 17ac255e60f6..8fd1e6058133 100644
|
|
|
|
--- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
|
|
|
|
+++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
|
|
|
|
@@ -91,6 +91,7 @@ import com.android.internal.R;
|
|
|
|
import com.android.internal.os.ClassLoaderFactory;
|
|
|
|
import com.android.internal.util.ArrayUtils;
|
|
|
|
import com.android.internal.util.XmlUtils;
|
|
|
|
+import com.android.server.ext.PackageManagerHooks;
|
|
|
|
import com.android.server.pm.SharedUidMigration;
|
|
|
|
import com.android.server.pm.permission.CompatibilityPermissionInfo;
|
|
|
|
import com.android.server.pm.pkg.component.ComponentMutateUtils;
|
|
|
|
@@ -2203,6 +2204,8 @@ public class ParsingPackageUtils {
|
|
|
|
pkg.addActivity(a.getResult());
|
|
|
|
}
|
|
|
|
|
|
|
|
+ PackageManagerHooks.amendParsedPackage(pkg);
|
|
|
|
+
|
|
|
|
if (hasActivityOrder) {
|
|
|
|
pkg.sortActivities();
|
|
|
|
}
|