Mitigate the races during installation

When handling post-install during the installation process, some
tasks are posted to PackageHandler and be executed after notifying
the install observer (install initiator). The task includes force-
stopping the package. If the install observer starts the app right
after being notified, the ongoing force-stop will kill the process.
The race happens. To mitigate the potential race, We should defer
the notification until these tasks are done.

Bug: 165012101
Test: atest -p services/core/java/com/android/server/pm
Change-Id: Ia6b32f72f3d75b8a40c42e11d21f21c459db5299
Merged-In: Ia6b32f72f3d75b8a40c42e11d21f21c459db5299
(cherry picked from commit bad03aa3c9)
This commit is contained in:
Jackal Guo
2022-01-21 15:51:00 +08:00
parent 038fd80ce8
commit 65067cb36d
5 changed files with 44 additions and 9 deletions

View File

@@ -656,6 +656,11 @@ public abstract class PackageManagerInternal {
*/ */
public abstract void notifyPackageUse(String packageName, int reason); public abstract void notifyPackageUse(String packageName, int reason);
/**
* Notify the package is force stopped.
*/
public abstract void onPackageProcessKilledForUninstall(String packageName);
/** /**
* Returns a package object for the given package name. * Returns a package object for the given package name.
*/ */

View File

@@ -13596,6 +13596,8 @@ public class ActivityManagerService extends IActivityManager.Stub
intent.getIntExtra(Intent.EXTRA_UID, -1)), intent.getIntExtra(Intent.EXTRA_UID, -1)),
false, true, true, false, fullUninstall, userId, false, true, true, false, fullUninstall, userId,
removed ? "pkg removed" : "pkg changed"); removed ? "pkg removed" : "pkg changed");
getPackageManagerInternal()
.onPackageProcessKilledForUninstall(ssp);
} else { } else {
// Kill any app zygotes always, since they can't fork new // Kill any app zygotes always, since they can't fork new
// processes with references to the old code // processes with references to the old code

View File

@@ -2889,9 +2889,13 @@ final class InstallPackageHelper {
} }
} }
final boolean deferInstallObserver = succeeded && update && !killApp; final boolean deferInstallObserver = succeeded && update;
if (deferInstallObserver) { if (deferInstallObserver) {
mPm.scheduleDeferredNoKillInstallObserver(res, installObserver); if (killApp) {
mPm.scheduleDeferredPendingKillInstallObserver(res, installObserver);
} else {
mPm.scheduleDeferredNoKillInstallObserver(res, installObserver);
}
} else { } else {
mPm.notifyInstallObserver(res, installObserver); mPm.notifyInstallObserver(res, installObserver);
} }

View File

@@ -24,6 +24,7 @@ import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
import static com.android.server.pm.PackageManagerService.DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD; import static com.android.server.pm.PackageManagerService.DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD;
import static com.android.server.pm.PackageManagerService.DEFERRED_NO_KILL_INSTALL_OBSERVER; import static com.android.server.pm.PackageManagerService.DEFERRED_NO_KILL_INSTALL_OBSERVER;
import static com.android.server.pm.PackageManagerService.DEFERRED_NO_KILL_POST_DELETE; import static com.android.server.pm.PackageManagerService.DEFERRED_NO_KILL_POST_DELETE;
import static com.android.server.pm.PackageManagerService.DEFERRED_PENDING_KILL_INSTALL_OBSERVER;
import static com.android.server.pm.PackageManagerService.DOMAIN_VERIFICATION; import static com.android.server.pm.PackageManagerService.DOMAIN_VERIFICATION;
import static com.android.server.pm.PackageManagerService.ENABLE_ROLLBACK_STATUS; import static com.android.server.pm.PackageManagerService.ENABLE_ROLLBACK_STATUS;
import static com.android.server.pm.PackageManagerService.ENABLE_ROLLBACK_TIMEOUT; import static com.android.server.pm.PackageManagerService.ENABLE_ROLLBACK_TIMEOUT;
@@ -126,10 +127,12 @@ final class PackageHandler extends Handler {
} }
} }
} break; } break;
case DEFERRED_NO_KILL_INSTALL_OBSERVER: { case DEFERRED_NO_KILL_INSTALL_OBSERVER:
String packageName = (String) msg.obj; case DEFERRED_PENDING_KILL_INSTALL_OBSERVER: {
final String packageName = (String) msg.obj;
if (packageName != null) { if (packageName != null) {
mPm.notifyInstallObserver(packageName); final boolean killApp = msg.what == DEFERRED_PENDING_KILL_INSTALL_OBSERVER;
mPm.notifyInstallObserver(packageName, killApp);
} }
} break; } break;
case WRITE_SETTINGS: { case WRITE_SETTINGS: {

View File

@@ -840,6 +840,9 @@ public class PackageManagerService extends IPackageManager.Stub
private final Map<String, Pair<PackageInstalledInfo, IPackageInstallObserver2>> private final Map<String, Pair<PackageInstalledInfo, IPackageInstallObserver2>>
mNoKillInstallObservers = Collections.synchronizedMap(new HashMap<>()); mNoKillInstallObservers = Collections.synchronizedMap(new HashMap<>());
private final Map<String, Pair<PackageInstalledInfo, IPackageInstallObserver2>>
mPendingKillInstallObservers = Collections.synchronizedMap(new HashMap<>());
// Internal interface for permission manager // Internal interface for permission manager
final PermissionManagerServiceInternal mPermissionManager; final PermissionManagerServiceInternal mPermissionManager;
@@ -887,9 +890,11 @@ public class PackageManagerService extends IPackageManager.Stub
static final int CHECK_PENDING_INTEGRITY_VERIFICATION = 26; static final int CHECK_PENDING_INTEGRITY_VERIFICATION = 26;
static final int DOMAIN_VERIFICATION = 27; static final int DOMAIN_VERIFICATION = 27;
static final int PRUNE_UNUSED_STATIC_SHARED_LIBRARIES = 28; static final int PRUNE_UNUSED_STATIC_SHARED_LIBRARIES = 28;
static final int DEFERRED_PENDING_KILL_INSTALL_OBSERVER = 29;
static final int DEFERRED_NO_KILL_POST_DELETE_DELAY_MS = 3 * 1000; static final int DEFERRED_NO_KILL_POST_DELETE_DELAY_MS = 3 * 1000;
private static final int DEFERRED_NO_KILL_INSTALL_OBSERVER_DELAY_MS = 500; private static final int DEFERRED_NO_KILL_INSTALL_OBSERVER_DELAY_MS = 500;
private static final int DEFERRED_PENDING_KILL_INSTALL_OBSERVER_DELAY_MS = 1000;
static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds
@@ -1166,13 +1171,14 @@ public class PackageManagerService extends IPackageManager.Stub
Computer computer = snapshotComputer(); Computer computer = snapshotComputer();
ArraySet<String> packagesToNotify = computer.getNotifyPackagesForReplacedReceived(packages); ArraySet<String> packagesToNotify = computer.getNotifyPackagesForReplacedReceived(packages);
for (int index = 0; index < packagesToNotify.size(); index++) { for (int index = 0; index < packagesToNotify.size(); index++) {
notifyInstallObserver(packagesToNotify.valueAt(index)); notifyInstallObserver(packagesToNotify.valueAt(index), false /* killApp */);
} }
} }
void notifyInstallObserver(String packageName) { void notifyInstallObserver(String packageName, boolean killApp) {
Pair<PackageInstalledInfo, IPackageInstallObserver2> pair = final Pair<PackageInstalledInfo, IPackageInstallObserver2> pair =
mNoKillInstallObservers.remove(packageName); killApp ? mPendingKillInstallObservers.remove(packageName)
: mNoKillInstallObservers.remove(packageName);
if (pair != null) { if (pair != null) {
notifyInstallObserver(pair.first, pair.second); notifyInstallObserver(pair.first, pair.second);
@@ -1211,6 +1217,15 @@ public class PackageManagerService extends IPackageManager.Stub
delay ? getPruneUnusedSharedLibrariesDelay() : 0); delay ? getPruneUnusedSharedLibrariesDelay() : 0);
} }
void scheduleDeferredPendingKillInstallObserver(PackageInstalledInfo info,
IPackageInstallObserver2 observer) {
final String packageName = info.mPkg.getPackageName();
mPendingKillInstallObservers.put(packageName, Pair.create(info, observer));
final Message message = mHandler.obtainMessage(DEFERRED_PENDING_KILL_INSTALL_OBSERVER,
packageName);
mHandler.sendMessageDelayed(message, DEFERRED_PENDING_KILL_INSTALL_OBSERVER_DELAY_MS);
}
private static long getPruneUnusedSharedLibrariesDelay() { private static long getPruneUnusedSharedLibrariesDelay() {
return SystemProperties.getLong("debug.pm.prune_unused_shared_libraries_delay", return SystemProperties.getLong("debug.pm.prune_unused_shared_libraries_delay",
PRUNE_UNUSED_SHARED_LIBRARIES_DELAY); PRUNE_UNUSED_SHARED_LIBRARIES_DELAY);
@@ -7392,6 +7407,12 @@ public class PackageManagerService extends IPackageManager.Stub
} }
} }
@Override
public void onPackageProcessKilledForUninstall(String packageName) {
mHandler.post(() -> PackageManagerService.this.notifyInstallObserver(packageName,
true /* killApp */));
}
@Override @Override
public SparseArray<String> getAppsWithSharedUserIds() { public SparseArray<String> getAppsWithSharedUserIds() {
return mComputer.getAppsWithSharedUserIds(); return mComputer.getAppsWithSharedUserIds();