1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.pm; 18 19 import static android.content.pm.Flags.disallowSdkLibsToBeApps; 20 import static android.content.pm.PackageManager.APP_METADATA_SOURCE_APK; 21 import static android.content.pm.PackageManager.APP_METADATA_SOURCE_INSTALLER; 22 import static android.content.pm.PackageManager.APP_METADATA_SOURCE_UNKNOWN; 23 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 24 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED; 25 import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 26 import static android.content.pm.PackageManager.INSTALL_FAILED_BAD_PERMISSION_GROUP; 27 import static android.content.pm.PackageManager.INSTALL_FAILED_DEPRECATED_SDK_VERSION; 28 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; 29 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION; 30 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION_GROUP; 31 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK; 32 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 33 import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED; 34 import static android.content.pm.PackageManager.INSTALL_FAILED_SESSION_INVALID; 35 import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY; 36 import static android.content.pm.PackageManager.INSTALL_FAILED_UID_CHANGED; 37 import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE; 38 import static android.content.pm.PackageManager.INSTALL_STAGED; 39 import static android.content.pm.PackageManager.INSTALL_SUCCEEDED; 40 import static android.content.pm.PackageManager.PROPERTY_ANDROID_SAFETY_LABEL; 41 import static android.content.pm.PackageManager.UNINSTALL_REASON_UNKNOWN; 42 import static android.content.pm.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V4; 43 import static android.content.pm.parsing.ApkLiteParseUtils.isApkFile; 44 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; 45 import static android.os.incremental.IncrementalManager.isIncrementalPath; 46 import static android.os.storage.StorageManager.FLAG_STORAGE_CE; 47 import static android.os.storage.StorageManager.FLAG_STORAGE_DE; 48 import static android.os.storage.StorageManager.FLAG_STORAGE_EXTERNAL; 49 50 import static com.android.server.pm.InstructionSets.getAppDexInstructionSets; 51 import static com.android.server.pm.PackageManagerException.INTERNAL_ERROR_ARCHIVE_NO_INSTALLER_TITLE; 52 import static com.android.server.pm.PackageManagerService.APP_METADATA_FILE_NAME; 53 import static com.android.server.pm.PackageManagerService.DEBUG_COMPRESSION; 54 import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL; 55 import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING; 56 import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE; 57 import static com.android.server.pm.PackageManagerService.DEBUG_UPGRADE; 58 import static com.android.server.pm.PackageManagerService.DEBUG_VERIFY; 59 import static com.android.server.pm.PackageManagerService.MIN_INSTALLABLE_TARGET_SDK; 60 import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME; 61 import static com.android.server.pm.PackageManagerService.POST_INSTALL; 62 import static com.android.server.pm.PackageManagerService.SCAN_AS_APEX; 63 import static com.android.server.pm.PackageManagerService.SCAN_AS_APK_IN_APEX; 64 import static com.android.server.pm.PackageManagerService.SCAN_AS_FACTORY; 65 import static com.android.server.pm.PackageManagerService.SCAN_AS_FULL_APP; 66 import static com.android.server.pm.PackageManagerService.SCAN_AS_INSTANT_APP; 67 import static com.android.server.pm.PackageManagerService.SCAN_AS_ODM; 68 import static com.android.server.pm.PackageManagerService.SCAN_AS_OEM; 69 import static com.android.server.pm.PackageManagerService.SCAN_AS_PRIVILEGED; 70 import static com.android.server.pm.PackageManagerService.SCAN_AS_PRODUCT; 71 import static com.android.server.pm.PackageManagerService.SCAN_AS_STOPPED_SYSTEM_APP; 72 import static com.android.server.pm.PackageManagerService.SCAN_AS_SYSTEM; 73 import static com.android.server.pm.PackageManagerService.SCAN_AS_SYSTEM_EXT; 74 import static com.android.server.pm.PackageManagerService.SCAN_AS_VENDOR; 75 import static com.android.server.pm.PackageManagerService.SCAN_AS_VIRTUAL_PRELOAD; 76 import static com.android.server.pm.PackageManagerService.SCAN_BOOTING; 77 import static com.android.server.pm.PackageManagerService.SCAN_DONT_KILL_APP; 78 import static com.android.server.pm.PackageManagerService.SCAN_DROP_CACHE; 79 import static com.android.server.pm.PackageManagerService.SCAN_FIRST_BOOT_OR_UPGRADE; 80 import static com.android.server.pm.PackageManagerService.SCAN_IGNORE_FROZEN; 81 import static com.android.server.pm.PackageManagerService.SCAN_INITIAL; 82 import static com.android.server.pm.PackageManagerService.SCAN_MOVE; 83 import static com.android.server.pm.PackageManagerService.SCAN_NEW_INSTALL; 84 import static com.android.server.pm.PackageManagerService.SCAN_NO_DEX; 85 import static com.android.server.pm.PackageManagerService.SCAN_REQUIRE_KNOWN; 86 import static com.android.server.pm.PackageManagerService.SCAN_UPDATE_SIGNATURE; 87 import static com.android.server.pm.PackageManagerService.TAG; 88 import static com.android.server.pm.PackageManagerService.WATCHDOG_TIMEOUT; 89 import static com.android.server.pm.PackageManagerServiceUtils.comparePackageSignatures; 90 import static com.android.server.pm.PackageManagerServiceUtils.compareSignatures; 91 import static com.android.server.pm.PackageManagerServiceUtils.compressedFileExists; 92 import static com.android.server.pm.PackageManagerServiceUtils.deriveAbiOverride; 93 import static com.android.server.pm.PackageManagerServiceUtils.extractAppMetadataFromApk; 94 import static com.android.server.pm.PackageManagerServiceUtils.isInstalledByAdb; 95 import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo; 96 import static com.android.server.pm.PackageManagerServiceUtils.makeDirRecursive; 97 import static com.android.server.pm.SharedUidMigration.BEST_EFFORT; 98 99 import android.annotation.NonNull; 100 import android.annotation.Nullable; 101 import android.annotation.UserIdInt; 102 import android.apex.ApexInfo; 103 import android.app.AppOpsManager; 104 import android.app.ApplicationExitInfo; 105 import android.app.ApplicationPackageManager; 106 import android.app.BroadcastOptions; 107 import android.app.admin.DevicePolicyManagerInternal; 108 import android.app.backup.IBackupManager; 109 import android.content.ContentResolver; 110 import android.content.Context; 111 import android.content.Intent; 112 import android.content.IntentFilter; 113 import android.content.IntentSender; 114 import android.content.pm.ApplicationInfo; 115 import android.content.pm.ArchivedPackageParcel; 116 import android.content.pm.DataLoaderType; 117 import android.content.pm.Flags; 118 import android.content.pm.PackageInfo; 119 import android.content.pm.PackageInfoLite; 120 import android.content.pm.PackageInstaller; 121 import android.content.pm.PackageManager; 122 import android.content.pm.PermissionGroupInfo; 123 import android.content.pm.PermissionInfo; 124 import android.content.pm.SharedLibraryInfo; 125 import android.content.pm.Signature; 126 import android.content.pm.SigningDetails; 127 import android.content.pm.VerifierInfo; 128 import android.content.pm.parsing.result.ParseResult; 129 import android.content.pm.parsing.result.ParseTypeImpl; 130 import android.net.Uri; 131 import android.os.Binder; 132 import android.os.Build; 133 import android.os.Environment; 134 import android.os.FileUtils; 135 import android.os.Message; 136 import android.os.PowerManager; 137 import android.os.Process; 138 import android.os.RemoteException; 139 import android.os.SELinux; 140 import android.os.SystemClock; 141 import android.os.Trace; 142 import android.os.UserHandle; 143 import android.os.UserManager; 144 import android.os.incremental.IncrementalManager; 145 import android.os.incremental.IncrementalStorage; 146 import android.system.ErrnoException; 147 import android.system.Os; 148 import android.text.TextUtils; 149 import android.util.ArrayMap; 150 import android.util.ArraySet; 151 import android.util.EventLog; 152 import android.util.ExceptionUtils; 153 import android.util.IntArray; 154 import android.util.Log; 155 import android.util.Pair; 156 import android.util.Slog; 157 import android.util.SparseArray; 158 import android.util.SparseIntArray; 159 160 import com.android.internal.annotations.GuardedBy; 161 import com.android.internal.content.F2fsUtils; 162 import com.android.internal.pm.parsing.PackageParser2; 163 import com.android.internal.pm.parsing.PackageParserException; 164 import com.android.internal.pm.parsing.pkg.AndroidPackageLegacyUtils; 165 import com.android.internal.pm.parsing.pkg.ParsedPackage; 166 import com.android.internal.pm.pkg.component.ComponentMutateUtils; 167 import com.android.internal.pm.pkg.component.ParsedActivity; 168 import com.android.internal.pm.pkg.component.ParsedInstrumentation; 169 import com.android.internal.pm.pkg.component.ParsedIntentInfo; 170 import com.android.internal.pm.pkg.component.ParsedPermission; 171 import com.android.internal.pm.pkg.component.ParsedPermissionGroup; 172 import com.android.internal.pm.pkg.parsing.ParsingPackageUtils; 173 import com.android.internal.util.ArrayUtils; 174 import com.android.internal.util.CollectionUtils; 175 import com.android.server.EventLogTags; 176 import com.android.server.SystemConfig; 177 import com.android.server.criticalevents.CriticalEventLog; 178 import com.android.server.pm.dex.DexManager; 179 import com.android.server.pm.parsing.PackageCacher; 180 import com.android.server.pm.parsing.pkg.AndroidPackageUtils; 181 import com.android.server.pm.permission.Permission; 182 import com.android.server.pm.permission.PermissionManagerServiceInternal; 183 import com.android.server.pm.pkg.AndroidPackage; 184 import com.android.server.pm.pkg.PackageStateInternal; 185 import com.android.server.pm.pkg.SharedLibraryWrapper; 186 import com.android.server.rollback.RollbackManagerInternal; 187 import com.android.server.utils.WatchedArrayMap; 188 import com.android.server.utils.WatchedLongSparseArray; 189 190 import dalvik.system.VMRuntime; 191 192 import java.io.File; 193 import java.io.FileInputStream; 194 import java.io.IOException; 195 import java.security.DigestInputStream; 196 import java.security.MessageDigest; 197 import java.security.NoSuchAlgorithmException; 198 import java.security.PublicKey; 199 import java.security.cert.CertificateException; 200 import java.util.ArrayList; 201 import java.util.Arrays; 202 import java.util.Collections; 203 import java.util.HashSet; 204 import java.util.List; 205 import java.util.Map; 206 import java.util.Set; 207 import java.util.concurrent.CompletableFuture; 208 import java.util.concurrent.ExecutorService; 209 210 211 final class InstallPackageHelper { 212 // One minute over PM WATCHDOG_TIMEOUT 213 private static final long WAKELOCK_TIMEOUT_MS = WATCHDOG_TIMEOUT + 1000 * 60; 214 private static final String INSTALLER_WAKE_LOCK_TAG = "installer:packages"; 215 216 private final PackageManagerService mPm; 217 private final AppDataHelper mAppDataHelper; 218 private final BroadcastHelper mBroadcastHelper; 219 private final RemovePackageHelper mRemovePackageHelper; 220 private final DeletePackageHelper mDeletePackageHelper; 221 private final IncrementalManager mIncrementalManager; 222 private final ApexManager mApexManager; 223 private final DexManager mDexManager; 224 private final Context mContext; 225 private final PackageAbiHelper mPackageAbiHelper; 226 private final SharedLibrariesImpl mSharedLibraries; 227 private final PackageManagerServiceInjector mInjector; 228 private final UpdateOwnershipHelper mUpdateOwnershipHelper; 229 230 private final Object mInternalLock = new Object(); 231 @GuardedBy("mInternalLock") 232 private PowerManager.WakeLock mInstallingWakeLock; 233 234 // TODO(b/198166813): remove PMS dependency InstallPackageHelper(PackageManagerService pm, AppDataHelper appDataHelper, RemovePackageHelper removePackageHelper, DeletePackageHelper deletePackageHelper, BroadcastHelper broadcastHelper)235 InstallPackageHelper(PackageManagerService pm, 236 AppDataHelper appDataHelper, 237 RemovePackageHelper removePackageHelper, 238 DeletePackageHelper deletePackageHelper, 239 BroadcastHelper broadcastHelper) { 240 mPm = pm; 241 mInjector = pm.mInjector; 242 mAppDataHelper = appDataHelper; 243 mBroadcastHelper = broadcastHelper; 244 mRemovePackageHelper = removePackageHelper; 245 mDeletePackageHelper = deletePackageHelper; 246 mIncrementalManager = pm.mInjector.getIncrementalManager(); 247 mApexManager = pm.mInjector.getApexManager(); 248 mDexManager = pm.mInjector.getDexManager(); 249 mContext = pm.mInjector.getContext(); 250 mPackageAbiHelper = pm.mInjector.getAbiHelper(); 251 mSharedLibraries = pm.mInjector.getSharedLibrariesImpl(); 252 mUpdateOwnershipHelper = pm.mInjector.getUpdateOwnershipHelper(); 253 } 254 255 /** 256 * Commits the package scan and modifies system state. 257 * <p><em>WARNING:</em> The method may throw an exception in the middle 258 * of committing the package, leaving the system in an inconsistent state. 259 * This needs to be fixed so, once we get to this point, no errors are 260 * possible and the system is not left in an inconsistent state. 261 */ 262 @GuardedBy("mPm.mLock") commitReconciledScanResultLocked( @onNull ReconciledPackage reconciledPkg, int[] allUsers)263 private AndroidPackage commitReconciledScanResultLocked( 264 @NonNull ReconciledPackage reconciledPkg, int[] allUsers) { 265 final InstallRequest request = reconciledPkg.mInstallRequest; 266 // TODO(b/135203078): Move this even further away 267 ParsedPackage parsedPackage = request.getParsedPackage(); 268 if (parsedPackage != null && "android".equals(parsedPackage.getPackageName())) { 269 // TODO(b/135203078): Move this to initial parse 270 parsedPackage.setVersionCode(mPm.getSdkVersion()) 271 .setVersionCodeMajor(0); 272 } 273 274 final @PackageManagerService.ScanFlags int scanFlags = request.getScanFlags(); 275 final PackageSetting oldPkgSetting = request.getScanRequestOldPackageSetting(); 276 final PackageSetting originalPkgSetting = request.getScanRequestOriginalPackageSetting(); 277 final String realPkgName = request.getRealPackageName(); 278 final PackageSetting pkgSetting; 279 if (request.getScanRequestPackageSetting() != null) { 280 SharedUserSetting requestSharedUserSetting = mPm.mSettings.getSharedUserSettingLPr( 281 request.getScanRequestPackageSetting()); 282 SharedUserSetting resultSharedUserSetting = mPm.mSettings.getSharedUserSettingLPr( 283 request.getScannedPackageSetting()); 284 if (requestSharedUserSetting != null 285 && requestSharedUserSetting != resultSharedUserSetting) { 286 // shared user changed, remove from old shared user 287 requestSharedUserSetting.removePackage(request.getScanRequestPackageSetting()); 288 // Prune unused SharedUserSetting 289 if (mPm.mSettings.checkAndPruneSharedUserLPw(requestSharedUserSetting, false)) { 290 // Set the app ID in removed info for UID_REMOVED broadcasts 291 request.setRemovedAppId(requestSharedUserSetting.mAppId); 292 } 293 } 294 } 295 if (request.isExistingSettingCopied()) { 296 pkgSetting = request.getScanRequestPackageSetting(); 297 pkgSetting.updateFrom(request.getScannedPackageSetting()); 298 } else { 299 pkgSetting = request.getScannedPackageSetting(); 300 if (originalPkgSetting != null) { 301 mPm.mSettings.addRenamedPackageLPw( 302 AndroidPackageUtils.getRealPackageOrNull(parsedPackage, 303 pkgSetting.isSystem()), 304 originalPkgSetting.getPackageName()); 305 mPm.mTransferredPackages.add(originalPkgSetting.getPackageName()); 306 } else { 307 mPm.mSettings.removeRenamedPackageLPw(parsedPackage.getPackageName()); 308 } 309 } 310 SharedUserSetting sharedUserSetting = mPm.mSettings.getSharedUserSettingLPr(pkgSetting); 311 if (sharedUserSetting != null) { 312 sharedUserSetting.addPackage(pkgSetting); 313 if (parsedPackage.isLeavingSharedUser() 314 && SharedUidMigration.applyStrategy(BEST_EFFORT) 315 && sharedUserSetting.isSingleUser()) { 316 // Attempt the transparent shared UID migration 317 mPm.mSettings.convertSharedUserSettingsLPw(sharedUserSetting); 318 } 319 } 320 if (request.isForceQueryableOverride()) { 321 pkgSetting.setForceQueryableOverride(true); 322 } 323 324 InstallSource installSource = request.getInstallSource(); 325 final boolean isApex = (scanFlags & SCAN_AS_APEX) != 0; 326 final boolean pkgAlreadyExists = oldPkgSetting != null; 327 final String oldUpdateOwner = 328 pkgAlreadyExists ? oldPkgSetting.getInstallSource().mUpdateOwnerPackageName : null; 329 final String updateOwnerFromSysconfig = isApex || !pkgSetting.isSystem() ? null 330 : mPm.mInjector.getSystemConfig().getSystemAppUpdateOwnerPackageName( 331 parsedPackage.getPackageName()); 332 final boolean isUpdateOwnershipDenylisted = 333 mUpdateOwnershipHelper.isUpdateOwnershipDenylisted(parsedPackage.getPackageName()); 334 final boolean isUpdateOwnershipEnabled = oldUpdateOwner != null; 335 336 // For standard install (install via session), the installSource isn't null. 337 if (installSource != null) { 338 // If this is part of a standard install, set the initiating package name, else rely on 339 // previous device state. 340 if (!isInstalledByAdb(installSource.mInitiatingPackageName)) { 341 final PackageSetting ips = mPm.mSettings.getPackageLPr( 342 installSource.mInitiatingPackageName); 343 if (ips != null) { 344 installSource = installSource.setInitiatingPackageSignatures( 345 ips.getSignatures()); 346 } 347 } 348 349 // Handle the update ownership enforcement for APK 350 if (!isApex) { 351 // User installer UID as "current" userId if present; otherwise, use the userId 352 // from InstallRequest. 353 final int userId = installSource.mInstallerPackageUid != Process.INVALID_UID 354 ? UserHandle.getUserId(installSource.mInstallerPackageUid) 355 : request.getUserId(); 356 // Whether the parsedPackage is installed on the userId 357 // If the oldPkgSetting doesn't exist, this package isn't installed for all users. 358 final boolean isUpdate = pkgAlreadyExists && (userId >= UserHandle.USER_SYSTEM 359 // If userID >= 0, we could check via oldPkgSetting.getInstalled(userId). 360 ? oldPkgSetting.getInstalled(userId) 361 // When userId is -1 (USER_ALL) and it's not installed for any user, 362 // treat it as not installed. 363 : oldPkgSetting.getNotInstalledUserIds().length 364 <= (UserManager.isHeadlessSystemUserMode() ? 1 : 0)); 365 final boolean isRequestUpdateOwnership = (request.getInstallFlags() 366 & PackageManager.INSTALL_REQUEST_UPDATE_OWNERSHIP) != 0; 367 final boolean isSameUpdateOwner = 368 TextUtils.equals(oldUpdateOwner, installSource.mInstallerPackageName); 369 final boolean isInstallerUpdateOwnerDenylistProvider = 370 mUpdateOwnershipHelper.isUpdateOwnershipDenyListProvider( 371 installSource.mUpdateOwnerPackageName); 372 373 // Here we handle the update owner for the package, and the rules are: 374 // -. Only enabling update ownership enforcement on initial installation if the 375 // installer has requested. 376 // -. Once the installer changes and users agree to proceed, clear the update 377 // owner (package state in other users are taken into account as well). 378 if (!isUpdate) { 379 if (!isRequestUpdateOwnership 380 || isUpdateOwnershipDenylisted 381 || isInstallerUpdateOwnerDenylistProvider) { 382 installSource = installSource.setUpdateOwnerPackageName(null); 383 } else if ((!isUpdateOwnershipEnabled && pkgAlreadyExists) 384 || (isUpdateOwnershipEnabled && !isSameUpdateOwner)) { 385 installSource = installSource.setUpdateOwnerPackageName(null); 386 } 387 } else if (!isSameUpdateOwner 388 || !isUpdateOwnershipEnabled) { 389 installSource = installSource.setUpdateOwnerPackageName(null); 390 } 391 } 392 393 pkgSetting.setInstallSource(installSource); 394 // For non-standard install (addForInit), installSource is null. 395 } else if (pkgSetting.isSystem()) { 396 // We still honor the manifest attr if the system app wants to opt-out of it. 397 final boolean isSameUpdateOwner = isUpdateOwnershipEnabled 398 && TextUtils.equals(oldUpdateOwner, updateOwnerFromSysconfig); 399 400 // Here we handle the update owner for the system package, and the rules are: 401 // -. We use the update owner from sysconfig as the initial value. 402 // -. Once an app becomes to system app later via OTA, only retains the update 403 // owner if it's consistence with sysconfig. 404 // -. Clear the update owner when update owner changes from sysconfig. 405 if (!pkgAlreadyExists || isSameUpdateOwner) { 406 pkgSetting.setUpdateOwnerPackage(updateOwnerFromSysconfig); 407 } else { 408 pkgSetting.setUpdateOwnerPackage(null); 409 } 410 } 411 412 if ((scanFlags & SCAN_AS_APK_IN_APEX) != 0) { 413 boolean isFactory = (scanFlags & SCAN_AS_FACTORY) != 0; 414 pkgSetting.getPkgState().setApkInUpdatedApex(!isFactory); 415 } 416 417 pkgSetting.getPkgState().setApexModuleName(request.getApexModuleName()); 418 419 // TODO(toddke): Consider a method specifically for modifying the Package object 420 // post scan; or, moving this stuff out of the Package object since it has nothing 421 // to do with the package on disk. 422 // We need to have this here because addUserToSettingLPw() is sometimes responsible 423 // for creating the application ID. If we did this earlier, we would be saving the 424 // correct ID. 425 parsedPackage.setUid(pkgSetting.getAppId()); 426 final AndroidPackage pkg = parsedPackage.hideAsFinal(); 427 428 mPm.mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting); 429 430 if (realPkgName != null) { 431 mPm.mTransferredPackages.add(pkg.getPackageName()); 432 } 433 434 if (reconciledPkg.mCollectedSharedLibraryInfos != null 435 || (oldPkgSetting != null 436 && !oldPkgSetting.getSharedLibraryDependencies().isEmpty())) { 437 // Reconcile if the new package or the old package uses shared libraries. 438 // It is possible that the old package uses shared libraries but the new one doesn't. 439 mSharedLibraries.executeSharedLibrariesUpdate(pkg, pkgSetting, null, null, 440 reconciledPkg.mCollectedSharedLibraryInfos, allUsers); 441 } 442 443 final KeySetManagerService ksms = mPm.mSettings.getKeySetManagerService(); 444 if (reconciledPkg.mRemoveAppKeySetData) { 445 ksms.removeAppKeySetDataLPw(pkg.getPackageName()); 446 } 447 if (reconciledPkg.mSharedUserSignaturesChanged) { 448 sharedUserSetting.signaturesChanged = Boolean.TRUE; 449 sharedUserSetting.signatures.mSigningDetails = reconciledPkg.mSigningDetails; 450 } 451 pkgSetting.setSigningDetails(reconciledPkg.mSigningDetails); 452 453 final int userId = request.getUserId(); 454 // Modify state for the given package setting 455 commitPackageSettings(pkg, pkgSetting, oldPkgSetting, reconciledPkg); 456 if (pkgSetting.getInstantApp(userId)) { 457 mPm.mInstantAppRegistry.addInstantApp(userId, pkgSetting.getAppId()); 458 } 459 460 if (!IncrementalManager.isIncrementalPath(pkgSetting.getPathString())) { 461 pkgSetting.setLoadingProgress(1f); 462 } 463 464 // TODO: passes the package name as an argument in a message to the handler for V+ 465 // so we don't need to rely on creating lambda objects so frequently. 466 if (UpdateOwnershipHelper.hasValidOwnershipDenyList(pkgSetting)) { 467 mPm.mHandler.post(() -> handleUpdateOwnerDenyList(pkgSetting)); 468 } 469 return pkg; 470 } 471 handleUpdateOwnerDenyList(PackageSetting pkgSetting)472 private void handleUpdateOwnerDenyList(PackageSetting pkgSetting) { 473 ArraySet<String> listItems = mUpdateOwnershipHelper.readUpdateOwnerDenyList(pkgSetting); 474 if (listItems != null && !listItems.isEmpty()) { 475 mUpdateOwnershipHelper.addToUpdateOwnerDenyList(pkgSetting.getPackageName(), 476 listItems); 477 SystemConfig config = SystemConfig.getInstance(); 478 synchronized (mPm.mLock) { 479 for (String unownedPackage : listItems) { 480 PackageSetting unownedSetting = mPm.mSettings.getPackageLPr(unownedPackage); 481 if (unownedSetting != null 482 && config.getSystemAppUpdateOwnerPackageName(unownedPackage) == null) { 483 unownedSetting.setUpdateOwnerPackage(null); 484 } 485 } 486 } 487 } 488 } 489 490 /** 491 * Adds a scanned package to the system. When this method is finished, the package will 492 * be available for query, resolution, etc... 493 */ commitPackageSettings(@onNull AndroidPackage pkg, @NonNull PackageSetting pkgSetting, @Nullable PackageSetting oldPkgSetting, ReconciledPackage reconciledPkg)494 private void commitPackageSettings(@NonNull AndroidPackage pkg, 495 @NonNull PackageSetting pkgSetting, @Nullable PackageSetting oldPkgSetting, 496 ReconciledPackage reconciledPkg) { 497 final String pkgName = pkg.getPackageName(); 498 final InstallRequest request = reconciledPkg.mInstallRequest; 499 final AndroidPackage oldPkg = request.getScanRequestOldPackage(); 500 final int scanFlags = request.getScanFlags(); 501 final boolean chatty = (request.getParseFlags() & ParsingPackageUtils.PARSE_CHATTY) != 0; 502 if (mPm.mCustomResolverComponentName != null 503 && mPm.mCustomResolverComponentName.getPackageName().equals(pkg.getPackageName())) { 504 mPm.setUpCustomResolverActivity(pkg, pkgSetting); 505 } 506 507 // When upgrading a package, clear the app metadata file path for the new package. 508 if (oldPkgSetting != null 509 && oldPkgSetting.getLastUpdateTime() < pkgSetting.getLastUpdateTime()) { 510 pkgSetting.setAppMetadataFilePath(null); 511 pkgSetting.setAppMetadataSource(APP_METADATA_SOURCE_UNKNOWN); 512 } 513 // If the app metadata file path is not null then this is a system app with a preloaded app 514 // metadata file on the system image. Do not reset the path and source if this is the 515 // case. 516 if (pkgSetting.getAppMetadataFilePath() == null) { 517 String dir = pkg.getPath(); 518 if (pkgSetting.isSystem()) { 519 dir = Environment.getDataDirectoryPath() + "/app-metadata/" + pkg.getPackageName(); 520 } 521 String appMetadataFilePath = dir + "/" + APP_METADATA_FILE_NAME; 522 if (request.hasAppMetadataFile()) { 523 pkgSetting.setAppMetadataFilePath(appMetadataFilePath); 524 if (Flags.aslInApkAppMetadataSource()) { 525 pkgSetting.setAppMetadataSource(APP_METADATA_SOURCE_INSTALLER); 526 } 527 } else if (Flags.aslInApkAppMetadataSource()) { 528 Map<String, PackageManager.Property> properties = pkg.getProperties(); 529 if (properties.containsKey(PROPERTY_ANDROID_SAFETY_LABEL)) { 530 // ASL file extraction is done in post-install 531 pkgSetting.setAppMetadataFilePath(appMetadataFilePath); 532 pkgSetting.setAppMetadataSource(APP_METADATA_SOURCE_APK); 533 } 534 } 535 } 536 537 if (pkg.getPackageName().equals("android")) { 538 mPm.setPlatformPackage(pkg, pkgSetting); 539 } 540 541 // writer 542 ArrayList<AndroidPackage> clientLibPkgs = 543 mSharedLibraries.commitSharedLibraryChanges(pkg, pkgSetting, 544 reconciledPkg.mAllowedSharedLibraryInfos, 545 reconciledPkg.getCombinedAvailablePackages(), scanFlags); 546 547 request.setLibraryConsumers(clientLibPkgs); 548 549 if ((scanFlags & SCAN_BOOTING) != 0) { 550 // No apps can run during boot scan, so they don't need to be frozen 551 } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) { 552 // Caller asked to not kill app, so it's probably not frozen 553 } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) { 554 // Caller asked us to ignore frozen check for some reason; they 555 // probably didn't know the package name 556 } else { 557 // We're doing major surgery on this package, so it better be frozen 558 // right now to keep it from launching 559 mPm.snapshotComputer().checkPackageFrozen(pkgName); 560 } 561 562 final boolean isReplace = request.isInstallReplace(); 563 // Also need to kill any apps that are dependent on the library, except the case of 564 // installation of new version static shared library. 565 if (clientLibPkgs != null) { 566 if (pkg.getStaticSharedLibraryName() == null || isReplace) { 567 for (int i = 0; i < clientLibPkgs.size(); i++) { 568 AndroidPackage clientPkg = clientLibPkgs.get(i); 569 String packageName = clientPkg.getPackageName(); 570 mPm.killApplication(packageName, 571 clientPkg.getUid(), "update lib", 572 ApplicationExitInfo.REASON_DEPENDENCY_DIED); 573 } 574 } 575 } 576 577 // writer 578 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 579 580 synchronized (mPm.mLock) { 581 // We don't expect installation to fail beyond this point 582 // Add the new setting to mSettings 583 mPm.mSettings.insertPackageSettingLPw(pkgSetting, pkg); 584 // Add the new setting to mPackages 585 mPm.mPackages.put(pkg.getPackageName(), pkg); 586 if ((scanFlags & SCAN_AS_APK_IN_APEX) != 0) { 587 mApexManager.registerApkInApex(pkg); 588 } 589 590 if ((mPm.isDeviceUpgrading() && pkgSetting.isSystem()) || isReplace) { 591 for (int userId : mPm.mUserManager.getUserIds()) { 592 pkgSetting.restoreComponentSettings(userId); 593 } 594 } 595 596 // Don't add keysets for APEX as their package settings are not persisted and will 597 // result in orphaned keysets. 598 if ((scanFlags & SCAN_AS_APEX) == 0) { 599 // Add the package's KeySets to the global KeySetManagerService 600 KeySetManagerService ksms = mPm.mSettings.getKeySetManagerService(); 601 ksms.addScannedPackageLPw(pkg); 602 } 603 604 final Computer snapshot = mPm.snapshotComputer(); 605 mPm.mComponentResolver.addAllComponents(pkg, chatty, mPm.mSetupWizardPackage, snapshot); 606 mPm.mAppsFilter.addPackage(snapshot, pkgSetting, isReplace, 607 (scanFlags & SCAN_DONT_KILL_APP) != 0 /* retainImplicitGrantOnReplace */); 608 mPm.addAllPackageProperties(pkg); 609 610 // Only verify app links for non-archival installations, otherwise there won't be any 611 // declared app links. 612 if (!request.isArchived()) { 613 if (oldPkgSetting == null || oldPkgSetting.getPkg() == null) { 614 mPm.mDomainVerificationManager.addPackage(pkgSetting, 615 request.getPreVerifiedDomains()); 616 } else { 617 mPm.mDomainVerificationManager.migrateState(oldPkgSetting, pkgSetting, 618 request.getPreVerifiedDomains()); 619 } 620 } 621 622 int collectionSize = ArrayUtils.size(pkg.getInstrumentations()); 623 StringBuilder r = null; 624 int i; 625 for (i = 0; i < collectionSize; i++) { 626 ParsedInstrumentation a = pkg.getInstrumentations().get(i); 627 ComponentMutateUtils.setPackageName(a, pkg.getPackageName()); 628 mPm.addInstrumentation(a.getComponentName(), a); 629 if (chatty) { 630 if (r == null) { 631 r = new StringBuilder(256); 632 } else { 633 r.append(' '); 634 } 635 r.append(a.getName()); 636 } 637 } 638 if (r != null) { 639 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r); 640 } 641 642 final List<String> protectedBroadcasts = pkg.getProtectedBroadcasts(); 643 if (!protectedBroadcasts.isEmpty()) { 644 synchronized (mPm.mProtectedBroadcasts) { 645 mPm.mProtectedBroadcasts.addAll(protectedBroadcasts); 646 } 647 } 648 649 mPm.mPermissionManager.onPackageAdded(pkgSetting, 650 (scanFlags & SCAN_AS_INSTANT_APP) != 0, oldPkg); 651 } 652 653 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 654 } 655 installExistingPackageAsUser(@ullable String packageName, @UserIdInt int userId, @PackageManager.InstallFlags int installFlags, @PackageManager.InstallReason int installReason, @Nullable List<String> allowlistedRestrictedPermissions, @Nullable IntentSender intentSender)656 public Pair<Integer, IntentSender> installExistingPackageAsUser(@Nullable String packageName, 657 @UserIdInt int userId, @PackageManager.InstallFlags int installFlags, 658 @PackageManager.InstallReason int installReason, 659 @Nullable List<String> allowlistedRestrictedPermissions, 660 @Nullable IntentSender intentSender) { 661 if (DEBUG_INSTALL) { 662 Log.v(TAG, "installExistingPackageAsUser package=" + packageName + " userId=" + userId 663 + " installFlags=" + installFlags + " installReason=" + installReason 664 + " allowlistedRestrictedPermissions=" + allowlistedRestrictedPermissions); 665 } 666 667 final int callingUid = Binder.getCallingUid(); 668 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES) 669 != PackageManager.PERMISSION_GRANTED 670 && mContext.checkCallingOrSelfPermission( 671 android.Manifest.permission.INSTALL_EXISTING_PACKAGES) 672 != PackageManager.PERMISSION_GRANTED) { 673 throw new SecurityException("Neither user " + callingUid + " nor current process has " 674 + android.Manifest.permission.INSTALL_PACKAGES + "."); 675 } 676 PackageSetting pkgSetting; 677 final Computer preLockSnapshot = mPm.snapshotComputer(); 678 preLockSnapshot.enforceCrossUserPermission(callingUid, userId, 679 true /* requireFullPermission */, true /* checkShell */, 680 "installExistingPackage for user " + userId); 681 if (mPm.isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 682 return Pair.create(PackageManager.INSTALL_FAILED_USER_RESTRICTED, intentSender); 683 } 684 685 final long callingId = Binder.clearCallingIdentity(); 686 try { 687 boolean installed = false; 688 final boolean instantApp = 689 (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0; 690 final boolean fullApp = 691 (installFlags & PackageManager.INSTALL_FULL_APP) != 0; 692 final boolean isPackageDeviceAdmin = mPm.isPackageDeviceAdmin(packageName, userId); 693 final boolean isProtectedPackage = mPm.mProtectedPackages != null 694 && mPm.mProtectedPackages.isPackageStateProtected(userId, packageName); 695 696 // writer 697 synchronized (mPm.mLock) { 698 final Computer snapshot = mPm.snapshotComputer(); 699 pkgSetting = mPm.mSettings.getPackageLPr(packageName); 700 if (pkgSetting == null || pkgSetting.getPkg() == null) { 701 return Pair.create(PackageManager.INSTALL_FAILED_INVALID_URI, intentSender); 702 } 703 if (instantApp && (pkgSetting.isSystem() || pkgSetting.isUpdatedSystemApp() 704 || isPackageDeviceAdmin || isProtectedPackage)) { 705 return Pair.create(PackageManager.INSTALL_FAILED_INVALID_URI, intentSender); 706 } 707 if (!snapshot.canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) { 708 // only allow the existing package to be used if it's installed as a full 709 // application for at least one user 710 boolean installAllowed = false; 711 for (int checkUserId : mPm.mUserManager.getUserIds()) { 712 installAllowed = !pkgSetting.getInstantApp(checkUserId); 713 if (installAllowed) { 714 break; 715 } 716 } 717 if (!installAllowed) { 718 return Pair.create(PackageManager.INSTALL_FAILED_INVALID_URI, intentSender); 719 } 720 } 721 if (!pkgSetting.getInstalled(userId)) { 722 pkgSetting.setInstalled(true, userId); 723 pkgSetting.setHidden(false, userId); 724 pkgSetting.setInstallReason(installReason, userId); 725 pkgSetting.setUninstallReason(PackageManager.UNINSTALL_REASON_UNKNOWN, userId); 726 pkgSetting.setFirstInstallTime(System.currentTimeMillis(), userId); 727 // Clear any existing archive state. 728 mPm.mInstallerService.mPackageArchiver.clearArchiveState(pkgSetting, userId); 729 mPm.mSettings.writePackageRestrictionsLPr(userId); 730 mPm.mSettings.writeKernelMappingLPr(pkgSetting); 731 installed = true; 732 } else if (fullApp && pkgSetting.getInstantApp(userId)) { 733 // upgrade app from instant to full; we don't allow app downgrade 734 installed = true; 735 } 736 ScanPackageUtils.setInstantAppForUser(mPm.mInjector, pkgSetting, userId, instantApp, 737 fullApp); 738 } 739 740 if (installed) { 741 final String updateOwner = pkgSetting.getInstallSource().mUpdateOwnerPackageName; 742 final var dpmi = mInjector.getLocalService(DevicePolicyManagerInternal.class); 743 final boolean isFromManagedUserOrProfile = 744 dpmi != null && dpmi.isUserOrganizationManaged(userId); 745 // Here we handle the update owner when install existing package, and the rules are: 746 // -. Retain the update owner when enable a system app in managed user or profile. 747 // -. Retain the update owner if the installer is the same. 748 // -. Clear the update owner when update owner changes. 749 if (!preLockSnapshot.isCallerSameApp(updateOwner, callingUid) 750 && (!pkgSetting.isSystem() || !isFromManagedUserOrProfile)) { 751 pkgSetting.setUpdateOwnerPackage(null); 752 } 753 if (pkgSetting.getPkg() != null) { 754 final PermissionManagerServiceInternal.PackageInstalledParams.Builder 755 permissionParamsBuilder = 756 new PermissionManagerServiceInternal.PackageInstalledParams.Builder(); 757 if ((installFlags & PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS) 758 != 0) { 759 permissionParamsBuilder.setAllowlistedRestrictedPermissions( 760 new ArrayList<>(pkgSetting.getPkg().getRequestedPermissions())); 761 } 762 mPm.mPermissionManager.onPackageInstalled(pkgSetting.getPkg(), 763 Process.INVALID_UID /* previousAppId */, 764 permissionParamsBuilder.build(), userId); 765 766 try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) { 767 // We don't need to freeze for a brand new install 768 mAppDataHelper.prepareAppDataPostCommitLIF( 769 pkgSetting, /* previousAppId= */0, new int[] { userId }); 770 } 771 } 772 // TODO(b/278553670) Store archive state for the user. 773 boolean isArchived = (pkgSetting.getPkg() == null); 774 mBroadcastHelper.sendPackageAddedForUser(mPm.snapshotComputer(), packageName, 775 pkgSetting, userId, isArchived, DataLoaderType.NONE, 776 mPm.mAppPredictionServicePackage); 777 synchronized (mPm.mLock) { 778 mPm.updateSequenceNumberLP(pkgSetting, new int[]{ userId }); 779 } 780 // start async restore with no post-install since we finish install here 781 782 final IntentSender onCompleteSender = intentSender; 783 intentSender = null; 784 785 InstallRequest request = new InstallRequest(userId, 786 PackageManager.INSTALL_SUCCEEDED, pkgSetting.getPkg(), new int[]{ userId }, 787 () -> { 788 mPm.restorePermissionsAndUpdateRolesForNewUserInstall(packageName, 789 userId); 790 if (onCompleteSender != null) { 791 onInstallComplete(PackageManager.INSTALL_SUCCEEDED, mContext, 792 onCompleteSender); 793 } 794 }, pkgSetting.getAppId(), callingUid, pkgSetting.isSystem()); 795 restoreAndPostInstall(request); 796 } 797 } finally { 798 Binder.restoreCallingIdentity(callingId); 799 } 800 801 return Pair.create(PackageManager.INSTALL_SUCCEEDED, intentSender); 802 } 803 onInstallComplete(int returnCode, Context context, IntentSender target)804 static void onInstallComplete(int returnCode, Context context, IntentSender target) { 805 Intent fillIn = new Intent(); 806 fillIn.putExtra(PackageInstaller.EXTRA_STATUS, 807 PackageManager.installStatusToPublicStatus(returnCode)); 808 try { 809 final BroadcastOptions options = BroadcastOptions.makeBasic(); 810 options.setPendingIntentBackgroundActivityLaunchAllowed(false); 811 target.sendIntent(context, 0, fillIn, 812 null /* requiredPermission */, options.toBundle(), 813 null /* executor */, null /* onFinished*/); 814 } catch (IntentSender.SendIntentException ignored) { 815 } 816 } 817 restoreAndPostInstall(InstallRequest request)818 public void restoreAndPostInstall(InstallRequest request) { 819 final int userId = request.getUserId(); 820 if (DEBUG_INSTALL) { 821 Log.v(TAG, 822 "restoreAndPostInstall userId=" + userId + " package=" + request.getPkg()); 823 } 824 825 PackageSetting packageSetting = null; 826 827 final boolean update = request.isUpdate(); 828 boolean doRestore = false; 829 if (request.getPkg() != null && !request.isArchived()) { 830 // A restore should be requested at this point: 831 // if the install succeeded and it's not an archived install 832 if (!update) { 833 // AND the operation is not an update, 834 doRestore = true; 835 } else { 836 // OR the package has never been restored. 837 String packageName = request.getPkg().getPackageName(); 838 synchronized (mPm.mLock) { 839 packageSetting = mPm.mSettings.getPackageLPr(packageName); 840 if (packageSetting != null && packageSetting.isPendingRestore()) { 841 doRestore = true; 842 } 843 } 844 } 845 } 846 847 // Set up the post-install work request bookkeeping. This will be used 848 // and cleaned up by the post-install event handling regardless of whether 849 // there's a restore pass performed. Token values are >= 1. 850 int token; 851 if (mPm.mNextInstallToken < 0) mPm.mNextInstallToken = 1; 852 token = mPm.mNextInstallToken++; 853 synchronized (mPm.mRunningInstalls) { 854 mPm.mRunningInstalls.put(token, request); 855 } 856 857 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token); 858 859 final boolean succeeded = request.getReturnCode() == PackageManager.INSTALL_SUCCEEDED; 860 if (succeeded) { 861 request.onRestoreStarted(); 862 if (doRestore) { 863 // Pass responsibility to the Backup Manager. It will perform a 864 // restore if appropriate, then pass responsibility back to the 865 // Package Manager to run the post-install observer callbacks 866 // and broadcasts. 867 // Note: MUST close freezer before backup/restore, otherwise test 868 // of CtsBackupHostTestCases will fail. 869 request.closeFreezer(); 870 doRestore = performBackupManagerRestore(userId, token, request); 871 } 872 873 // If this is an update to a package that might be potentially downgraded, then we 874 // need to check with the rollback manager whether there's any userdata that might 875 // need to be snapshotted or restored for the package. 876 // 877 // TODO(narayan): Get this working for cases where userId == UserHandle.USER_ALL. 878 if (!doRestore && update) { 879 doRestore = performRollbackManagerRestore(userId, token, request); 880 } 881 882 if (doRestore && !request.hasPostInstallRunnable()) { 883 boolean hasNeverBeenRestored = 884 packageSetting != null && packageSetting.isPendingRestore(); 885 request.setPostInstallRunnable(() -> { 886 // Permissions should be restored on each user that has the app installed for 887 // the first time, unless it's an unarchive install for an archived app, in 888 // which case the permissions should be restored on each user that has the 889 // app updated. 890 int[] userIdsToRestorePermissions = hasNeverBeenRestored 891 ? request.getUpdateBroadcastUserIds() 892 : request.getFirstTimeBroadcastUserIds(); 893 for (int restorePermissionUserId : userIdsToRestorePermissions) { 894 mPm.restorePermissionsAndUpdateRolesForNewUserInstall(request.getName(), 895 restorePermissionUserId); 896 } 897 }); 898 } 899 } 900 901 if (doRestore) { 902 if (packageSetting != null) { 903 synchronized (mPm.mLock) { 904 packageSetting.setPendingRestore(false); 905 } 906 } 907 } else { 908 // No restore possible, or the Backup Manager was mysteriously not available. 909 // we don't need to wait for restore to complete before closing the freezer, 910 // so we can close the freezer right away. 911 // Also just fire the post-install work request directly. 912 request.closeFreezer(); 913 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token); 914 915 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token); 916 917 Message msg = mPm.mHandler.obtainMessage(POST_INSTALL, token, 0); 918 mPm.mHandler.sendMessage(msg); 919 } 920 } 921 922 /** 923 * Perform Backup Manager restore for a given {@link InstallRequest}. 924 * Returns whether the restore successfully completed. 925 */ performBackupManagerRestore(int userId, int token, InstallRequest request)926 private boolean performBackupManagerRestore(int userId, int token, InstallRequest request) { 927 if (request.getPkg() == null) { 928 return false; 929 } 930 IBackupManager iBackupManager = mInjector.getIBackupManager(); 931 if (iBackupManager != null) { 932 // For backwards compatibility as USER_ALL previously routed directly to USER_SYSTEM 933 // in the BackupManager. USER_ALL is used in compatibility tests. 934 if (userId == UserHandle.USER_ALL) { 935 userId = UserHandle.USER_SYSTEM; 936 } 937 if (DEBUG_INSTALL) { 938 Log.v(TAG, "token " + token + " to BM for possible restore for user " + userId); 939 } 940 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 941 try { 942 if (iBackupManager.isUserReadyForBackup(userId)) { 943 iBackupManager.restoreAtInstallForUser( 944 userId, request.getPkg().getPackageName(), token); 945 } else { 946 Slog.w(TAG, "User " + userId + " is not ready. Restore at install " 947 + "didn't take place."); 948 return false; 949 } 950 } catch (RemoteException e) { 951 // can't happen; the backup manager is local 952 } catch (Exception e) { 953 Slog.e(TAG, "Exception trying to enqueue restore", e); 954 return false; 955 } 956 } else { 957 Slog.e(TAG, "Backup Manager not found!"); 958 return false; 959 } 960 return true; 961 } 962 963 /** 964 * Perform Rollback Manager restore for a given {@link InstallRequest}. 965 * Returns whether the restore successfully completed. 966 */ performRollbackManagerRestore(int userId, int token, InstallRequest request)967 private boolean performRollbackManagerRestore(int userId, int token, InstallRequest request) { 968 if (request.getPkg() == null) { 969 return false; 970 } 971 final String packageName = request.getPkg().getPackageName(); 972 final int[] allUsers = mPm.mUserManager.getUserIds(); 973 final int[] installedUsers; 974 975 final PackageSetting ps; 976 int appId = -1; 977 long ceDataInode = -1; 978 synchronized (mPm.mLock) { 979 ps = mPm.mSettings.getPackageLPr(packageName); 980 if (ps != null) { 981 appId = ps.getAppId(); 982 ceDataInode = ps.getCeDataInode(userId); 983 // NOTE: We ignore the user specified in the InstallParam because we know this is 984 // an update, and hence need to restore data for all installed users. 985 installedUsers = ps.queryInstalledUsers(allUsers, true); 986 } else { 987 installedUsers = new int[0]; 988 } 989 } 990 991 final int installFlags = request.getInstallFlags(); 992 boolean doSnapshotOrRestore = ((installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0 993 || (installFlags & PackageManager.INSTALL_REQUEST_DOWNGRADE) != 0); 994 995 if (ps != null && doSnapshotOrRestore) { 996 final String seInfo = ps.getSeInfo(); 997 final RollbackManagerInternal rollbackManager = 998 mInjector.getLocalService(RollbackManagerInternal.class); 999 rollbackManager.snapshotAndRestoreUserData(packageName, 1000 UserHandle.toUserHandles(installedUsers), appId, ceDataInode, seInfo, token); 1001 return true; 1002 } 1003 return false; 1004 } 1005 1006 /** 1007 * Installs one or more packages atomically. This operation is broken up into four phases: 1008 * <ul> 1009 * <li><b>Prepare</b> 1010 * <br/>Analyzes any current install state, parses the package and does initial 1011 * validation on it.</li> 1012 * <li><b>Scan</b> 1013 * <br/>Interrogates the parsed packages given the context collected in prepare.</li> 1014 * <li><b>Reconcile</b> 1015 * <br/>Validates scanned packages in the context of each other and the current system 1016 * state to ensure that the install will be successful. 1017 * <li><b>Commit</b> 1018 * <br/>Commits all scanned packages and updates system state. This is the only place 1019 * that system state may be modified in the install flow and all predictable errors 1020 * must be determined before this phase.</li> 1021 * </ul> 1022 * 1023 * Failure at any phase will result in a full failure to install all packages. 1024 */ installPackagesTraced(List<InstallRequest> requests, MoveInfo moveInfo)1025 void installPackagesTraced(List<InstallRequest> requests, MoveInfo moveInfo) { 1026 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackages"); 1027 boolean pendingForDexopt = false; 1028 boolean success = false; 1029 final Map<String, Boolean> createdAppId = new ArrayMap<>(requests.size()); 1030 final Map<String, Settings.VersionInfo> versionInfos = new ArrayMap<>(requests.size()); 1031 final long acquireTime = acquireWakeLock(requests.size()); 1032 try { 1033 CriticalEventLog.getInstance().logInstallPackagesStarted(); 1034 if (prepareInstallPackages(requests) 1035 && scanInstallPackages(requests, createdAppId, versionInfos)) { 1036 List<ReconciledPackage> reconciledPackages = 1037 reconcileInstallPackages(requests, versionInfos); 1038 if (reconciledPackages == null) { 1039 return; 1040 } 1041 1042 if (renameAndUpdatePaths(requests)) { 1043 // rename before dexopt because art will encoded the path in the odex/vdex file 1044 if (Flags.improveInstallFreeze()) { 1045 pendingForDexopt = true; 1046 final Runnable actionsAfterDexopt = () -> 1047 doPostDexopt(reconciledPackages, requests, 1048 createdAppId, moveInfo, acquireTime); 1049 prepPerformDexoptIfNeeded(reconciledPackages, actionsAfterDexopt); 1050 } else { 1051 if (commitInstallPackages(reconciledPackages)) { 1052 success = true; 1053 } 1054 } 1055 } 1056 } 1057 } finally { 1058 if (!pendingForDexopt) { 1059 completeInstallProcess(requests, createdAppId, success); 1060 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 1061 doPostInstall(requests, moveInfo); 1062 releaseWakeLock(acquireTime, requests.size()); 1063 } 1064 } 1065 } 1066 doPostDexopt(List<ReconciledPackage> reconciledPackages, List<InstallRequest> requests, Map<String, Boolean> createdAppId, MoveInfo moveInfo, long acquireTime)1067 void doPostDexopt(List<ReconciledPackage> reconciledPackages, 1068 List<InstallRequest> requests, Map<String, Boolean> createdAppId, 1069 MoveInfo moveInfo, long acquireTime) { 1070 for (InstallRequest request : requests) { 1071 request.onWaitDexoptFinished(); 1072 } 1073 boolean success = false; 1074 try { 1075 if (commitInstallPackages(reconciledPackages)) { 1076 success = true; 1077 } 1078 } finally { 1079 completeInstallProcess(requests, createdAppId, success); 1080 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 1081 doPostInstall(requests, moveInfo); 1082 releaseWakeLock(acquireTime, requests.size()); 1083 } 1084 } 1085 doPostInstall(List<InstallRequest> requests, MoveInfo moveInfo)1086 private void doPostInstall(List<InstallRequest> requests, MoveInfo moveInfo) { 1087 for (InstallRequest request : requests) { 1088 doPostInstallCleanUp(request, moveInfo); 1089 } 1090 1091 for (InstallRequest request : requests) { 1092 restoreAndPostInstall(request); 1093 } 1094 } 1095 doPostInstallCleanUp(InstallRequest request, MoveInfo moveInfo)1096 private void doPostInstallCleanUp(InstallRequest request, MoveInfo moveInfo) { 1097 if (moveInfo != null) { 1098 if (request.getReturnCode() == PackageManager.INSTALL_SUCCEEDED) { 1099 mRemovePackageHelper.cleanUpForMoveInstall(moveInfo.mFromUuid, 1100 moveInfo.mPackageName, moveInfo.mFromCodePath); 1101 } else { 1102 mRemovePackageHelper.cleanUpForMoveInstall(moveInfo.mToUuid, 1103 moveInfo.mPackageName, moveInfo.mFromCodePath); 1104 } 1105 } else { 1106 if (request.getReturnCode() != PackageManager.INSTALL_SUCCEEDED) { 1107 mRemovePackageHelper.removeCodePath(request.getCodeFile()); 1108 } 1109 } 1110 } 1111 acquireWakeLock(int count)1112 private long acquireWakeLock(int count) { 1113 if (!mPm.isSystemReady()) { 1114 return -1; 1115 } 1116 synchronized (mInternalLock) { 1117 if (mInstallingWakeLock == null) { 1118 PowerManager pwm = mContext.getSystemService(PowerManager.class); 1119 if (pwm != null) { 1120 mInstallingWakeLock = pwm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, 1121 INSTALLER_WAKE_LOCK_TAG); 1122 } else { 1123 Slog.w(TAG, "Unable to obtain power manager while obtaining wake lock"); 1124 return -1; 1125 } 1126 } 1127 1128 mInstallingWakeLock.acquire(WAKELOCK_TIMEOUT_MS * count); 1129 return SystemClock.elapsedRealtime(); 1130 } 1131 } 1132 releaseWakeLock(final long acquireTime, int count)1133 private void releaseWakeLock(final long acquireTime, int count) { 1134 if (acquireTime < 0) { 1135 return; 1136 } 1137 synchronized (mInternalLock) { 1138 try { 1139 if (mInstallingWakeLock == null) { 1140 return; 1141 } 1142 if (mInstallingWakeLock.isHeld()) { 1143 mInstallingWakeLock.release(); 1144 } 1145 } catch (RuntimeException e) { 1146 Slog.wtf(TAG, "Error while releasing installer lock", e); 1147 } 1148 } 1149 } 1150 getNewUsers(InstallRequest installRequest, int[] allUsers)1151 private int[] getNewUsers(InstallRequest installRequest, int[] allUsers) 1152 throws PackageManagerException { 1153 final int userId = installRequest.getUserId(); 1154 if (userId != UserHandle.USER_ALL && userId != UserHandle.USER_CURRENT 1155 && !ArrayUtils.contains(allUsers, userId)) { 1156 throw new PackageManagerException(PackageManagerException.INTERNAL_ERROR_MISSING_USER, 1157 "User " + userId + " doesn't exist or has been removed"); 1158 } 1159 1160 final IntArray newUserIds = new IntArray(); 1161 if (userId != UserHandle.USER_ALL) { 1162 newUserIds.add(userId); 1163 } else if (allUsers != null) { 1164 final int[] installedForUsers = installRequest.getOriginUsers(); 1165 for (int currentUserId : allUsers) { 1166 final boolean installedForCurrentUser = ArrayUtils.contains( 1167 installedForUsers, currentUserId); 1168 final boolean restrictedByPolicy = 1169 mPm.isUserRestricted(currentUserId, 1170 UserManager.DISALLOW_INSTALL_APPS) 1171 || mPm.isUserRestricted(currentUserId, 1172 UserManager.DISALLOW_DEBUGGING_FEATURES); 1173 if (installedForCurrentUser || !restrictedByPolicy) { 1174 newUserIds.add(currentUserId); 1175 } 1176 } 1177 } 1178 1179 if (newUserIds.size() == 0) { 1180 throw new PackageManagerException(PackageManagerException.INTERNAL_ERROR_MISSING_USER, 1181 "User " + userId + " doesn't exist or has been removed"); 1182 } else { 1183 return newUserIds.toArray(); 1184 } 1185 } 1186 prepPerformDexoptIfNeeded(List<ReconciledPackage> reconciledPackages, Runnable actionsAfterDexopt)1187 private void prepPerformDexoptIfNeeded(List<ReconciledPackage> reconciledPackages, 1188 Runnable actionsAfterDexopt) { 1189 List<CompletableFuture<Void>> completableFutures = new ArrayList<>(); 1190 for (ReconciledPackage reconciledPkg : reconciledPackages) { 1191 final InstallRequest request = reconciledPkg.mInstallRequest; 1192 // prepare profiles 1193 final PackageSetting ps = request.getScannedPackageSetting(); 1194 final PackageSetting oldPkgSetting = request.getScanRequestOldPackageSetting(); 1195 final int[] allUsers = mPm.mUserManager.getUserIds(); 1196 if (reconciledPkg.mCollectedSharedLibraryInfos != null 1197 || (oldPkgSetting != null 1198 && !oldPkgSetting.getSharedLibraryDependencies().isEmpty())) { 1199 // Reconcile if the new package or the old package uses shared libraries. 1200 // It is possible that the old package uses shared libraries but the new 1201 // one doesn't. 1202 mSharedLibraries.executeSharedLibrariesUpdate(request.getParsedPackage(), ps, 1203 null, null, reconciledPkg.mCollectedSharedLibraryInfos, allUsers); 1204 } 1205 1206 try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) { 1207 final int[] newUsers = getNewUsers(request, allUsers); 1208 // Hardcode previousAppId to 0 to disable any data migration (http://b/221088088) 1209 mAppDataHelper.prepareAppDataPostCommitLIF(ps, 0, newUsers); 1210 if (request.isClearCodeCache()) { 1211 mAppDataHelper.clearAppDataLIF(ps.getPkg(), UserHandle.USER_ALL, 1212 FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL 1213 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 1214 } 1215 } catch (PackageManagerException e) { 1216 request.setError(e.error, e.getMessage()); 1217 break; 1218 } 1219 request.setKeepArtProfile(true); 1220 1221 CompletableFuture<Void> future = 1222 DexOptHelper.performDexoptIfNeededAsync(request, mDexManager); 1223 completableFutures.add(future); 1224 request.onWaitDexoptStarted(); 1225 } 1226 1227 if (!completableFutures.isEmpty()) { 1228 CompletableFuture<Void> allFutures = 1229 CompletableFuture.allOf( 1230 completableFutures.toArray(CompletableFuture[]::new)); 1231 var unused = allFutures.thenRun(() -> mPm.mHandler.post(actionsAfterDexopt)); 1232 } else { 1233 actionsAfterDexopt.run(); 1234 } 1235 } 1236 renameAndUpdatePaths(List<InstallRequest> requests)1237 private boolean renameAndUpdatePaths(List<InstallRequest> requests) { 1238 try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) { 1239 for (InstallRequest request : requests) { 1240 ParsedPackage parsedPackage = request.getParsedPackage(); 1241 final boolean isApex = (request.getScanFlags() & SCAN_AS_APEX) != 0; 1242 if (isApex) { 1243 continue; 1244 } 1245 try { 1246 doRenameLI(request, parsedPackage); 1247 } catch (PrepareFailure e) { 1248 request.setError(e); 1249 return false; 1250 } 1251 1252 // update paths that are set before renaming 1253 PackageSetting scannedPackageSetting = request.getScannedPackageSetting(); 1254 scannedPackageSetting.setPath(new File(parsedPackage.getPath())); 1255 scannedPackageSetting.setLegacyNativeLibraryPath( 1256 parsedPackage.getNativeLibraryRootDir()); 1257 } 1258 return true; 1259 } 1260 } 1261 prepareInstallPackages(List<InstallRequest> requests)1262 private boolean prepareInstallPackages(List<InstallRequest> requests) { 1263 for (InstallRequest request : requests) { 1264 try { 1265 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "preparePackage"); 1266 request.onPrepareStarted(); 1267 preparePackage(request); 1268 } catch (PrepareFailure prepareFailure) { 1269 request.setError(prepareFailure.error, 1270 prepareFailure.getMessage()); 1271 request.setOriginPackage(prepareFailure.mConflictingPackage); 1272 request.setOriginPermission(prepareFailure.mConflictingPermission); 1273 return false; 1274 } finally { 1275 request.onPrepareFinished(); 1276 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 1277 } 1278 } 1279 return true; 1280 } 1281 scanInstallPackages(List<InstallRequest> requests, Map<String, Boolean> createdAppId, Map<String, Settings.VersionInfo> versionInfos)1282 private boolean scanInstallPackages(List<InstallRequest> requests, 1283 Map<String, Boolean> createdAppId, Map<String, Settings.VersionInfo> versionInfos) { 1284 final Set<String> scannedPackages = new ArraySet<>(requests.size()); 1285 for (InstallRequest request : requests) { 1286 final ParsedPackage packageToScan = request.getParsedPackage(); 1287 if (packageToScan == null) { 1288 request.setError(INSTALL_FAILED_SESSION_INVALID, 1289 "Failed to obtain package to scan"); 1290 return false; 1291 } 1292 request.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 1293 final String packageName = packageToScan.getPackageName(); 1294 try { 1295 request.onScanStarted(); 1296 final ScanResult scanResult = scanPackageTraced(request.getParsedPackage(), 1297 request.getParseFlags(), request.getScanFlags(), 1298 System.currentTimeMillis(), request.getUser(), 1299 request.getAbiOverride()); 1300 request.setScanResult(scanResult); 1301 request.onScanFinished(); 1302 if (!scannedPackages.add(packageName)) { 1303 request.setError( 1304 PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE, 1305 "Duplicate package " 1306 + packageName 1307 + " in multi-package install request."); 1308 return false; 1309 } 1310 if (!checkNoAppStorageIsConsistent( 1311 request.getScanRequestOldPackage(), packageToScan)) { 1312 // TODO: INSTALL_FAILED_UPDATE_INCOMPATIBLE is about incomptabible 1313 // signatures. Is there a better error code? 1314 request.setError( 1315 INSTALL_FAILED_UPDATE_INCOMPATIBLE, 1316 "Update attempted to change value of " 1317 + PackageManager.PROPERTY_NO_APP_DATA_STORAGE); 1318 return false; 1319 } 1320 final boolean isApex = (request.getScanFlags() & SCAN_AS_APEX) != 0; 1321 final boolean isSdkLibrary = packageToScan.isSdkLibrary(); 1322 if (isApex || (isSdkLibrary && disallowSdkLibsToBeApps())) { 1323 request.getScannedPackageSetting().setAppId(Process.INVALID_UID); 1324 } else { 1325 createdAppId.put(packageName, optimisticallyRegisterAppId(request)); 1326 } 1327 versionInfos.put(packageName, 1328 mPm.getSettingsVersionForPackage(packageToScan)); 1329 } catch (PackageManagerException e) { 1330 request.setError("Scanning Failed.", e); 1331 return false; 1332 } 1333 if (request.isArchived()) { 1334 final SparseArray<String> responsibleInstallerTitles = 1335 PackageArchiver.getResponsibleInstallerTitles(mContext, 1336 mPm.snapshotComputer(), request.getInstallSource(), 1337 request.getUserId(), mPm.mUserManager.getUserIds()); 1338 if (responsibleInstallerTitles == null 1339 || responsibleInstallerTitles.size() == 0) { 1340 request.setError(PackageManagerException.ofInternalError( 1341 "Failed to obtain the responsible installer info", 1342 INTERNAL_ERROR_ARCHIVE_NO_INSTALLER_TITLE)); 1343 return false; 1344 } 1345 request.setResponsibleInstallerTitles(responsibleInstallerTitles); 1346 } 1347 } 1348 return true; 1349 } 1350 reconcileInstallPackages(List<InstallRequest> requests, Map<String, Settings.VersionInfo> versionInfos)1351 private List<ReconciledPackage> reconcileInstallPackages(List<InstallRequest> requests, 1352 Map<String, Settings.VersionInfo> versionInfos) { 1353 try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) { 1354 synchronized (mPm.mLock) { 1355 try { 1356 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "reconcilePackages"); 1357 return ReconcilePackageUtils.reconcilePackages( 1358 requests, Collections.unmodifiableMap(mPm.mPackages), 1359 versionInfos, mSharedLibraries, mPm.mSettings.getKeySetManagerService(), 1360 mPm.mSettings, mPm.mInjector.getSystemConfig()); 1361 } catch (ReconcileFailure e) { 1362 for (InstallRequest request : requests) { 1363 request.setError("Reconciliation failed...", e); 1364 } 1365 return null; 1366 } finally { 1367 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 1368 } 1369 } 1370 } 1371 } 1372 1373 commitInstallPackages(List<ReconciledPackage> reconciledPackages)1374 private boolean commitInstallPackages(List<ReconciledPackage> reconciledPackages) { 1375 try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) { 1376 if (Flags.improveInstallFreeze()) { 1377 // Postpone freezer until after reconcile 1378 for (ReconciledPackage reconciledPkg : reconciledPackages) { 1379 InstallRequest installRequest = reconciledPkg.mInstallRequest; 1380 String packageName = installRequest.getParsedPackage().getPackageName(); 1381 PackageFreezer freezer = freezePackageForInstall(packageName, 1382 UserHandle.USER_ALL, installRequest.getInstallFlags(), 1383 "installPackageLI", ApplicationExitInfo.REASON_PACKAGE_UPDATED, 1384 installRequest); 1385 installRequest.setFreezer(freezer); 1386 } 1387 } 1388 synchronized (mPm.mLock) { 1389 try { 1390 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "commitPackages"); 1391 commitPackagesLocked(reconciledPackages, mPm.mUserManager.getUserIds()); 1392 } finally { 1393 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 1394 } 1395 } 1396 executePostCommitStepsLIF(reconciledPackages); 1397 } 1398 return true; 1399 } 1400 completeInstallProcess(List<InstallRequest> requests, Map<String, Boolean> createdAppId, boolean success)1401 private void completeInstallProcess(List<InstallRequest> requests, 1402 Map<String, Boolean> createdAppId, boolean success) { 1403 if (success) { 1404 for (InstallRequest request : requests) { 1405 mInjector.getAppOpsManagerInternal().onPackageAdded( 1406 request.getName(), request.getAppId()); 1407 if (request.getDataLoaderType() != DataLoaderType.INCREMENTAL) { 1408 continue; 1409 } 1410 if (request.getSignatureSchemeVersion() != SIGNING_BLOCK_V4) { 1411 continue; 1412 } 1413 // For incremental installs, we bypass the verifier prior to install. Now 1414 // that we know the package is valid, send a notice to the verifier with 1415 // the root hash of the base.apk. 1416 final String baseCodePath = request.getPkg().getBaseApkPath(); 1417 final String[] splitCodePaths = request.getPkg().getSplitCodePaths(); 1418 final Uri originUri = request.getOriginUri(); 1419 final int verificationId = mPm.mPendingVerificationToken++; 1420 final String rootHashString = PackageManagerServiceUtils 1421 .buildVerificationRootHashString(baseCodePath, splitCodePaths); 1422 VerificationUtils.broadcastPackageVerified(verificationId, originUri, 1423 PackageManager.VERIFICATION_ALLOW, rootHashString, 1424 request.getDataLoaderType(), request.getUser(), mContext); 1425 } 1426 } else { 1427 for (InstallRequest installRequest : requests) { 1428 if (installRequest.getParsedPackage() != null && createdAppId.getOrDefault( 1429 installRequest.getParsedPackage().getPackageName(), false)) { 1430 cleanUpAppIdCreation(installRequest); 1431 } 1432 } 1433 // TODO(b/194319951): create a more descriptive reason than unknown 1434 // mark all non-failure installs as UNKNOWN so we do not treat them as success 1435 for (InstallRequest request : requests) { 1436 request.closeFreezer(); 1437 if (request.getReturnCode() == PackageManager.INSTALL_SUCCEEDED) { 1438 request.setReturnCode(PackageManager.INSTALL_UNKNOWN); 1439 } 1440 } 1441 } 1442 } 1443 checkNoAppStorageIsConsistent(AndroidPackage oldPkg, AndroidPackage newPkg)1444 private boolean checkNoAppStorageIsConsistent(AndroidPackage oldPkg, AndroidPackage newPkg) { 1445 if (oldPkg == null) { 1446 // New install, nothing to check against. 1447 return true; 1448 } 1449 final PackageManager.Property curProp = 1450 oldPkg.getProperties().get(PackageManager.PROPERTY_NO_APP_DATA_STORAGE); 1451 final PackageManager.Property newProp = 1452 newPkg.getProperties().get(PackageManager.PROPERTY_NO_APP_DATA_STORAGE); 1453 if (curProp == null || !curProp.getBoolean()) { 1454 return newProp == null || !newProp.getBoolean(); 1455 } 1456 return newProp != null && newProp.getBoolean(); 1457 } 1458 preparePackage(InstallRequest request)1459 private void preparePackage(InstallRequest request) throws PrepareFailure { 1460 final int[] allUsers = mPm.mUserManager.getUserIds(); 1461 final int installFlags = request.getInstallFlags(); 1462 final boolean onExternal = request.getVolumeUuid() != null; 1463 final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0); 1464 final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0); 1465 final boolean virtualPreload = 1466 ((installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0); 1467 final boolean isApex = ((installFlags & PackageManager.INSTALL_APEX) != 0); 1468 final boolean isRollback = 1469 request.getInstallReason() == PackageManager.INSTALL_REASON_ROLLBACK; 1470 @PackageManagerService.ScanFlags int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE; 1471 if (request.isInstallMove()) { 1472 // moving a complete application; perform an initial scan on the new install location 1473 scanFlags |= SCAN_INITIAL; 1474 } 1475 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) { 1476 scanFlags |= SCAN_DONT_KILL_APP; 1477 } 1478 if (instantApp) { 1479 scanFlags |= SCAN_AS_INSTANT_APP; 1480 } 1481 if (fullApp) { 1482 scanFlags |= SCAN_AS_FULL_APP; 1483 } 1484 if (virtualPreload) { 1485 scanFlags |= SCAN_AS_VIRTUAL_PRELOAD; 1486 } 1487 if (isApex) { 1488 scanFlags |= SCAN_AS_APEX; 1489 } 1490 1491 final File tmpPackageFile = new File( 1492 isApex ? request.getApexInfo().modulePath : request.getCodePath()); 1493 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile); 1494 1495 // Validity check 1496 if (instantApp && onExternal) { 1497 Slog.i(TAG, "Incompatible ephemeral install; external=" + onExternal); 1498 throw new PrepareFailure(PackageManager.INSTALL_FAILED_SESSION_INVALID); 1499 } 1500 1501 // Retrieve PackageSettings and parse package 1502 @ParsingPackageUtils.ParseFlags final int parseFlags = 1503 mPm.getDefParseFlags() | ParsingPackageUtils.PARSE_CHATTY 1504 | ParsingPackageUtils.PARSE_ENFORCE_CODE 1505 | (onExternal ? ParsingPackageUtils.PARSE_EXTERNAL_STORAGE : 0); 1506 1507 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage"); 1508 final ParsedPackage parsedPackage; 1509 final ArchivedPackageParcel archivedPackage; 1510 try (PackageParser2 pp = mPm.mInjector.getPreparingPackageParser()) { 1511 if (request.getPackageLite() == null || !request.isArchived()) { 1512 // TODO: pass packageLite from install request instead of reparsing the package 1513 parsedPackage = pp.parsePackage(tmpPackageFile, parseFlags, false); 1514 AndroidPackageUtils.validatePackageDexMetadata(parsedPackage); 1515 archivedPackage = null; 1516 } else { 1517 // Archived install mode, no APK. 1518 parsedPackage = pp.parsePackageFromPackageLite(request.getPackageLite(), 1519 parseFlags); 1520 archivedPackage = request.getPackageLite().getArchivedPackage(); 1521 } 1522 } catch (PackageParserException e) { 1523 throw new PrepareFailure(e.error, 1524 ExceptionUtils.getCompleteMessage("Failed parse during installPackageLI", e)); 1525 } finally { 1526 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 1527 } 1528 1529 // Block the install of apps using a lower target SDK version than required. 1530 // This helps improve security and privacy as malware can target older SDK versions 1531 // to avoid enforcement of new API behavior. 1532 boolean bypassLowTargetSdkBlock = 1533 ((installFlags & PackageManager.INSTALL_BYPASS_LOW_TARGET_SDK_BLOCK) != 0); 1534 1535 // Skip enforcement when the testOnly flag is set 1536 if (!bypassLowTargetSdkBlock && parsedPackage.isTestOnly()) { 1537 bypassLowTargetSdkBlock = true; 1538 } 1539 1540 // Enforce the low target sdk install block except when 1541 // the --bypass-low-target-sdk-block is set for the install 1542 if (!bypassLowTargetSdkBlock 1543 && parsedPackage.getTargetSdkVersion() < MIN_INSTALLABLE_TARGET_SDK) { 1544 Slog.w(TAG, "App " + parsedPackage.getPackageName() 1545 + " targets deprecated sdk version"); 1546 throw new PrepareFailure(INSTALL_FAILED_DEPRECATED_SDK_VERSION, 1547 "App package must target at least SDK version " 1548 + MIN_INSTALLABLE_TARGET_SDK + ", but found " 1549 + parsedPackage.getTargetSdkVersion()); 1550 } 1551 1552 // Instant apps have several additional install-time checks. 1553 if (instantApp) { 1554 if (parsedPackage.getTargetSdkVersion() < Build.VERSION_CODES.O) { 1555 Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName() 1556 + " does not target at least O"); 1557 throw new PrepareFailure(INSTALL_FAILED_SESSION_INVALID, 1558 "Instant app package must target at least O"); 1559 } 1560 if (parsedPackage.getSharedUserId() != null) { 1561 Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName() 1562 + " may not declare sharedUserId."); 1563 throw new PrepareFailure(INSTALL_FAILED_SESSION_INVALID, 1564 "Instant app package may not declare a sharedUserId"); 1565 } 1566 } 1567 1568 if (parsedPackage.isStaticSharedLibrary()) { 1569 // Static shared libraries have synthetic package names 1570 PackageManagerService.renameStaticSharedLibraryPackage(parsedPackage); 1571 1572 // No static shared libs on external storage 1573 if (onExternal) { 1574 Slog.i(TAG, "Static shared libs can only be installed on internal storage."); 1575 throw new PrepareFailure(INSTALL_FAILED_INVALID_INSTALL_LOCATION, 1576 "Static shared libs can only be installed on internal storage."); 1577 } 1578 } 1579 1580 String pkgName = parsedPackage.getPackageName(); 1581 request.setName(pkgName); 1582 if (parsedPackage.isTestOnly()) { 1583 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) { 1584 throw new PrepareFailure(INSTALL_FAILED_TEST_ONLY, 1585 "Failed to install test-only apk. Did you forget to add -t?"); 1586 } 1587 } 1588 1589 // either use what we've been given or parse directly from the APK 1590 if (request.getSigningDetails() != SigningDetails.UNKNOWN) { 1591 parsedPackage.setSigningDetails(request.getSigningDetails()); 1592 } else { 1593 final ParseTypeImpl input = ParseTypeImpl.forDefaultParsing(); 1594 final ParseResult<SigningDetails> result = ParsingPackageUtils.getSigningDetails( 1595 input, parsedPackage, false /*skipVerify*/); 1596 if (result.isError()) { 1597 throw new PrepareFailure("Failed collect during installPackageLI", 1598 result.getException()); 1599 } 1600 parsedPackage.setSigningDetails(result.getResult()); 1601 } 1602 1603 if (instantApp && parsedPackage.getSigningDetails().getSignatureSchemeVersion() 1604 < SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V2) { 1605 Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName() 1606 + " is not signed with at least APK Signature Scheme v2"); 1607 throw new PrepareFailure(INSTALL_FAILED_SESSION_INVALID, 1608 "Instant app package must be signed with APK Signature Scheme v2 or greater"); 1609 } 1610 1611 boolean systemApp = false; 1612 boolean replace = false; 1613 synchronized (mPm.mLock) { 1614 PackageSetting ps = mPm.mSettings.getPackageLPr(pkgName); 1615 // Check if installing already existing package 1616 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 1617 String oldName = mPm.mSettings.getRenamedPackageLPr(pkgName); 1618 if (parsedPackage.getOriginalPackages().contains(oldName) 1619 && mPm.mPackages.containsKey(oldName)) { 1620 // This package is derived from an original package, 1621 // and this device has been updating from that original 1622 // name. We must continue using the original name, so 1623 // rename the new package here. 1624 parsedPackage.setPackageName(oldName); 1625 pkgName = oldName; 1626 ps = mPm.mSettings.getPackageLPr(oldName); 1627 if (DEBUG_INSTALL) { 1628 Slog.d(TAG, "Replacing existing renamed package: oldName=" 1629 + oldName + " pkgName=" + pkgName); 1630 } 1631 } 1632 if (ps != null) { 1633 // This package, under its official name or its old name, already exists 1634 // on the device; we should replace it. 1635 replace = true; 1636 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing package: " + pkgName); 1637 } 1638 if (replace) { 1639 // Prevent apps opting out from runtime permissions 1640 final int oldTargetSdk = ps.getTargetSdkVersion(); 1641 final int newTargetSdk = parsedPackage.getTargetSdkVersion(); 1642 if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1 1643 && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) { 1644 throw new PrepareFailure( 1645 PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE, 1646 "Package " + parsedPackage.getPackageName() 1647 + " new target SDK " + newTargetSdk 1648 + " doesn't support runtime permissions but the old" 1649 + " target SDK " + oldTargetSdk + " does."); 1650 } 1651 // Prevent persistent apps from being updated 1652 if (ps.isPersistent() 1653 && ((installFlags & PackageManager.INSTALL_STAGED) == 0)) { 1654 throw new PrepareFailure(PackageManager.INSTALL_FAILED_INVALID_APK, 1655 "Package " + pkgName + " is a persistent app. " 1656 + "Persistent apps are not updateable."); 1657 } 1658 // When updating an sdk library, make sure that the versionMajor is 1659 // changed if the targetSdkVersion and minSdkVersion have changed 1660 if (parsedPackage.isSdkLibrary() && ps.getPkg() != null 1661 && ps.getPkg().isSdkLibrary()) { 1662 final int oldMinSdk = ps.getPkg().getMinSdkVersion(); 1663 final int newMinSdk = parsedPackage.getMinSdkVersion(); 1664 if (oldTargetSdk != newTargetSdk || oldMinSdk != newMinSdk) { 1665 final int oldVersionMajor = ps.getPkg().getSdkLibVersionMajor(); 1666 final int newVersionMajor = parsedPackage.getSdkLibVersionMajor(); 1667 if (oldVersionMajor == newVersionMajor) { 1668 throw new PrepareFailure( 1669 PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE, 1670 "Failure updating " + pkgName + " as it updates" 1671 + " an sdk library <" 1672 + parsedPackage.getSdkLibraryName() + ">" 1673 + " without changing the versionMajor, but the" 1674 + " targetSdkVersion or minSdkVersion has changed:" 1675 + " Old targetSdkVersion: " + oldTargetSdk 1676 + " new targetSdkVersion: " + newTargetSdk 1677 + " Old minSdkVersion: " + oldMinSdk 1678 + " new minSdkVersion: " + newMinSdk 1679 + " versionMajor: " + newVersionMajor 1680 ); 1681 } 1682 } 1683 } 1684 } 1685 1686 } 1687 1688 PackageSetting signatureCheckPs = ps; 1689 1690 // SDK libs can have other major versions with different package names. 1691 if (signatureCheckPs == null && parsedPackage.isSdkLibrary()) { 1692 WatchedLongSparseArray<SharedLibraryInfo> libraryInfos = 1693 mSharedLibraries.getSharedLibraryInfos( 1694 parsedPackage.getSdkLibraryName()); 1695 if (libraryInfos != null && libraryInfos.size() > 0) { 1696 // Any existing version would do. 1697 SharedLibraryInfo libraryInfo = libraryInfos.valueAt(0); 1698 signatureCheckPs = mPm.mSettings.getPackageLPr(libraryInfo.getPackageName()); 1699 } 1700 } 1701 1702 // Static shared libs have same package with different versions where 1703 // we internally use a synthetic package name to allow multiple versions 1704 // of the same package, therefore we need to compare signatures against 1705 // the package setting for the latest library version. 1706 if (parsedPackage.isStaticSharedLibrary()) { 1707 SharedLibraryInfo libraryInfo = 1708 mSharedLibraries.getLatestStaticSharedLibraVersion(parsedPackage); 1709 if (libraryInfo != null) { 1710 signatureCheckPs = mPm.mSettings.getPackageLPr(libraryInfo.getPackageName()); 1711 } 1712 } 1713 1714 if (signatureCheckPs != null) { 1715 if (DEBUG_INSTALL) { 1716 Slog.d(TAG, 1717 "Existing package for signature checking: " + signatureCheckPs); 1718 } 1719 1720 // Quick validity check that we're signed correctly if updating; 1721 // we'll check this again later when scanning, but we want to 1722 // bail early here before tripping over redefined permissions. 1723 final KeySetManagerService ksms = mPm.mSettings.getKeySetManagerService(); 1724 final SharedUserSetting signatureCheckSus = mPm.mSettings.getSharedUserSettingLPr( 1725 signatureCheckPs); 1726 if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, signatureCheckSus, 1727 scanFlags)) { 1728 if (!ksms.checkUpgradeKeySetLocked(signatureCheckPs, parsedPackage)) { 1729 throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 1730 + parsedPackage.getPackageName() + " upgrade keys do not match the " 1731 + "previously installed version"); 1732 } 1733 } else { 1734 try { 1735 final boolean compareCompat = 1736 ReconcilePackageUtils.isCompatSignatureUpdateNeeded( 1737 mPm.getSettingsVersionForPackage(parsedPackage)); 1738 final boolean compareRecover = 1739 ReconcilePackageUtils.isRecoverSignatureUpdateNeeded( 1740 mPm.getSettingsVersionForPackage(parsedPackage)); 1741 // We don't care about disabledPkgSetting on install for now. 1742 final boolean compatMatch = 1743 PackageManagerServiceUtils.verifySignatures(signatureCheckPs, 1744 signatureCheckSus, null, 1745 parsedPackage.getSigningDetails(), compareCompat, compareRecover, 1746 isRollback); 1747 // The new KeySets will be re-added later in the scanning process. 1748 if (compatMatch) { 1749 synchronized (mPm.mLock) { 1750 ksms.removeAppKeySetDataLPw(parsedPackage.getPackageName()); 1751 } 1752 } 1753 } catch (PackageManagerException e) { 1754 throw new PrepareFailure(e.error, e.getMessage()); 1755 } 1756 } 1757 } 1758 1759 if (ps != null) { 1760 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps); 1761 1762 systemApp = ps.isSystem(); 1763 request.setOriginUsers(ps.queryUsersInstalledOrHasData( 1764 allUsers)); 1765 } 1766 1767 final int numGroups = ArrayUtils.size(parsedPackage.getPermissionGroups()); 1768 for (int groupNum = 0; groupNum < numGroups; groupNum++) { 1769 final ParsedPermissionGroup group = 1770 parsedPackage.getPermissionGroups().get(groupNum); 1771 final PermissionGroupInfo sourceGroup = mPm.getPermissionGroupInfo(group.getName(), 1772 0); 1773 1774 if (sourceGroup != null && cannotInstallWithBadPermissionGroups(parsedPackage)) { 1775 final String sourcePackageName = sourceGroup.packageName; 1776 1777 if ((replace || !parsedPackage.getPackageName().equals(sourcePackageName)) 1778 && !doesSignatureMatchForPermissions(sourcePackageName, parsedPackage, 1779 scanFlags)) { 1780 EventLog.writeEvent(0x534e4554, "146211400", -1, 1781 parsedPackage.getPackageName()); 1782 1783 throw new PrepareFailure(INSTALL_FAILED_DUPLICATE_PERMISSION_GROUP, 1784 "Package " 1785 + parsedPackage.getPackageName() 1786 + " attempting to redeclare permission group " 1787 + group.getName() + " already owned by " 1788 + sourcePackageName); 1789 } 1790 } 1791 } 1792 1793 // TODO: Move logic for checking permission compatibility into PermissionManagerService 1794 final int n = ArrayUtils.size(parsedPackage.getPermissions()); 1795 for (int i = n - 1; i >= 0; i--) { 1796 final ParsedPermission perm = parsedPackage.getPermissions().get(i); 1797 final Permission bp = mPm.mPermissionManager.getPermissionTEMP(perm.getName()); 1798 1799 // Don't allow anyone but the system to define ephemeral permissions. 1800 if ((perm.getProtectionLevel() & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0 1801 && !systemApp) { 1802 Slog.w(TAG, "Non-System package " + parsedPackage.getPackageName() 1803 + " attempting to delcare ephemeral permission " 1804 + perm.getName() + "; Removing ephemeral."); 1805 ComponentMutateUtils.setProtectionLevel(perm, 1806 perm.getProtectionLevel() & ~PermissionInfo.PROTECTION_FLAG_INSTANT); 1807 } 1808 1809 // Check whether the newly-scanned package wants to define an already-defined perm 1810 if (bp != null) { 1811 final String sourcePackageName = bp.getPackageName(); 1812 1813 if (!doesSignatureMatchForPermissions(sourcePackageName, parsedPackage, 1814 scanFlags)) { 1815 // If the owning package is the system itself, we log but allow 1816 // install to proceed; we fail the install on all other permission 1817 // redefinitions. 1818 if (!sourcePackageName.equals("android")) { 1819 throw new PrepareFailure(INSTALL_FAILED_DUPLICATE_PERMISSION, 1820 "Package " 1821 + parsedPackage.getPackageName() 1822 + " attempting to redeclare permission " 1823 + perm.getName() + " already owned by " 1824 + sourcePackageName) 1825 .conflictsWithExistingPermission(perm.getName(), 1826 sourcePackageName); 1827 } else { 1828 Slog.w(TAG, "Package " + parsedPackage.getPackageName() 1829 + " attempting to redeclare system permission " 1830 + perm.getName() + "; ignoring new declaration"); 1831 parsedPackage.removePermission(i); 1832 } 1833 } else if (!PLATFORM_PACKAGE_NAME.equals(parsedPackage.getPackageName())) { 1834 // Prevent apps to change protection level to dangerous from any other 1835 // type as this would allow a privilege escalation where an app adds a 1836 // normal/signature permission in other app's group and later redefines 1837 // it as dangerous leading to the group auto-grant. 1838 if ((perm.getProtectionLevel() & PermissionInfo.PROTECTION_MASK_BASE) 1839 == PermissionInfo.PROTECTION_DANGEROUS) { 1840 if (!bp.isRuntime()) { 1841 Slog.w(TAG, "Package " + parsedPackage.getPackageName() 1842 + " trying to change a non-runtime permission " 1843 + perm.getName() 1844 + " to runtime; keeping old protection level"); 1845 ComponentMutateUtils.setProtectionLevel(perm, 1846 bp.getProtectionLevel()); 1847 } 1848 } 1849 } 1850 } 1851 1852 if (perm.getGroup() != null 1853 && cannotInstallWithBadPermissionGroups(parsedPackage)) { 1854 boolean isPermGroupDefinedByPackage = false; 1855 for (int groupNum = 0; groupNum < numGroups; groupNum++) { 1856 if (parsedPackage.getPermissionGroups().get(groupNum).getName() 1857 .equals(perm.getGroup())) { 1858 isPermGroupDefinedByPackage = true; 1859 break; 1860 } 1861 } 1862 1863 if (!isPermGroupDefinedByPackage) { 1864 final PermissionGroupInfo sourceGroup = 1865 mPm.getPermissionGroupInfo(perm.getGroup(), 0); 1866 1867 if (sourceGroup == null) { 1868 EventLog.writeEvent(0x534e4554, "146211400", -1, 1869 parsedPackage.getPackageName()); 1870 1871 throw new PrepareFailure(INSTALL_FAILED_BAD_PERMISSION_GROUP, 1872 "Package " 1873 + parsedPackage.getPackageName() 1874 + " attempting to declare permission " 1875 + perm.getName() + " in non-existing group " 1876 + perm.getGroup()); 1877 } else { 1878 String groupSourcePackageName = sourceGroup.packageName; 1879 1880 if (!PLATFORM_PACKAGE_NAME.equals(groupSourcePackageName) 1881 && !doesSignatureMatchForPermissions(groupSourcePackageName, 1882 parsedPackage, scanFlags)) { 1883 EventLog.writeEvent(0x534e4554, "146211400", -1, 1884 parsedPackage.getPackageName()); 1885 1886 throw new PrepareFailure(INSTALL_FAILED_BAD_PERMISSION_GROUP, 1887 "Package " 1888 + parsedPackage.getPackageName() 1889 + " attempting to declare permission " 1890 + perm.getName() + " in group " 1891 + perm.getGroup() + " owned by package " 1892 + groupSourcePackageName 1893 + " with incompatible certificate"); 1894 } 1895 } 1896 } 1897 } 1898 } 1899 } 1900 1901 if (systemApp) { 1902 if (onExternal) { 1903 // Abort update; system app can't be replaced with app on sdcard 1904 throw new PrepareFailure(INSTALL_FAILED_INVALID_INSTALL_LOCATION, 1905 "Cannot install updates to system apps on sdcard"); 1906 } else if (instantApp) { 1907 // Abort update; system app can't be replaced with an instant app 1908 throw new PrepareFailure(INSTALL_FAILED_SESSION_INVALID, 1909 "Cannot update a system app with an instant app"); 1910 } 1911 } 1912 1913 if (request.isInstallMove()) { 1914 // We did an in-place move, so dex is ready to roll 1915 scanFlags |= SCAN_NO_DEX; 1916 scanFlags |= SCAN_MOVE; 1917 1918 synchronized (mPm.mLock) { 1919 final PackageSetting ps = mPm.mSettings.getPackageLPr(pkgName); 1920 if (ps == null) { 1921 request.setError(PackageManagerException.ofInternalError( 1922 "Missing settings for moved package " + pkgName, 1923 PackageManagerException.INTERNAL_ERROR_MISSING_SETTING_FOR_MOVE)); 1924 } 1925 1926 // We moved the entire application as-is, so bring over the 1927 // previously derived ABI information. 1928 parsedPackage.setPrimaryCpuAbi(ps.getPrimaryCpuAbiLegacy()) 1929 .setSecondaryCpuAbi(ps.getSecondaryCpuAbiLegacy()); 1930 } 1931 1932 } else { 1933 // Enable SCAN_NO_DEX flag to skip dexopt at a later stage 1934 scanFlags |= SCAN_NO_DEX; 1935 // The native libs of Apex is located in apex_payload.img, don't need to parse it from 1936 // the original apex file 1937 if (!isApex) { 1938 try { 1939 PackageSetting pkgSetting; 1940 synchronized (mPm.mLock) { 1941 pkgSetting = mPm.mSettings.getPackageLPr(pkgName); 1942 } 1943 boolean isUpdatedSystemAppFromExistingSetting = pkgSetting != null 1944 && pkgSetting.isUpdatedSystemApp(); 1945 final String abiOverride = deriveAbiOverride(request.getAbiOverride()); 1946 1947 // TODO: Are these system flags actually set properly at this stage? 1948 boolean isUpdatedSystemAppInferred = 1949 pkgSetting != null && pkgSetting.isSystem(); 1950 // derivePackageAbi works OK for archived packages despite logging some errors. 1951 final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths> 1952 derivedAbi = mPackageAbiHelper.derivePackageAbi(parsedPackage, 1953 systemApp, (isUpdatedSystemAppFromExistingSetting 1954 || isUpdatedSystemAppInferred), abiOverride, 1955 ScanPackageUtils.getAppLib32InstallDir()); 1956 derivedAbi.first.applyTo(parsedPackage); 1957 derivedAbi.second.applyTo(parsedPackage); 1958 } catch (PackageManagerException pme) { 1959 Slog.e(TAG, "Error deriving application ABI", pme); 1960 throw PrepareFailure.ofInternalError( 1961 "Error deriving application ABI: " + pme.getMessage(), 1962 PackageManagerException.INTERNAL_ERROR_DERIVING_ABI); 1963 } 1964 } 1965 } 1966 1967 if (isApex) { 1968 // Use the path returned by apexd 1969 parsedPackage.setPath(request.getApexInfo().modulePath); 1970 parsedPackage.setBaseApkPath(request.getApexInfo().modulePath); 1971 } 1972 1973 PackageFreezer freezer = null; 1974 if (!Flags.improveInstallFreeze()) { 1975 freezer = freezePackageForInstall(pkgName, UserHandle.USER_ALL, installFlags, 1976 "installPackageLI", ApplicationExitInfo.REASON_PACKAGE_UPDATED, request); 1977 } 1978 1979 1980 boolean shouldCloseFreezerBeforeReturn = true; 1981 try { 1982 final PackageSetting oldPackageState; 1983 final AndroidPackage oldPackage; 1984 String renamedPackage; 1985 boolean sysPkg = false; 1986 int targetScanFlags = scanFlags; 1987 int targetParseFlags = parseFlags; 1988 final PackageSetting ps; 1989 final PackageSetting disabledPs; 1990 final SharedUserSetting sharedUserSetting; 1991 if (replace) { 1992 final String pkgName11 = parsedPackage.getPackageName(); 1993 synchronized (mPm.mLock) { 1994 oldPackageState = mPm.mSettings.getPackageLPr(pkgName11); 1995 } 1996 oldPackage = oldPackageState.getAndroidPackage(); 1997 if (parsedPackage.isStaticSharedLibrary()) { 1998 // Static libs have a synthetic package name containing the version 1999 // and cannot be updated as an update would get a new package name, 2000 // unless this is installed from adb which is useful for development. 2001 if (oldPackage != null 2002 && (installFlags & PackageManager.INSTALL_FROM_ADB) == 0) { 2003 throw new PrepareFailure(INSTALL_FAILED_DUPLICATE_PACKAGE, 2004 "Packages declaring " 2005 + "static-shared libs cannot be updated"); 2006 } 2007 } 2008 2009 final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0; 2010 2011 final int[] installedUsers; 2012 final int[] uninstalledUsers; 2013 2014 synchronized (mPm.mLock) { 2015 if (DEBUG_INSTALL) { 2016 Slog.d(TAG, 2017 "replacePackageLI: new=" + parsedPackage 2018 + ", old=" + oldPackageState.getName()); 2019 } 2020 2021 ps = mPm.mSettings.getPackageLPr(pkgName11); 2022 disabledPs = mPm.mSettings.getDisabledSystemPkgLPr(ps); 2023 sharedUserSetting = mPm.mSettings.getSharedUserSettingLPr(ps); 2024 2025 // verify signatures are valid 2026 final KeySetManagerService ksms = mPm.mSettings.getKeySetManagerService(); 2027 if (ksms.shouldCheckUpgradeKeySetLocked(ps, sharedUserSetting, scanFlags)) { 2028 if (!ksms.checkUpgradeKeySetLocked(ps, parsedPackage)) { 2029 throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 2030 "New package not signed by keys specified by upgrade-keysets: " 2031 + pkgName11); 2032 } 2033 } else { 2034 SigningDetails parsedPkgSigningDetails = parsedPackage.getSigningDetails(); 2035 SigningDetails oldPkgSigningDetails = oldPackageState.getSigningDetails(); 2036 // default to original signature matching 2037 if (!parsedPkgSigningDetails.checkCapability(oldPkgSigningDetails, 2038 SigningDetails.CertCapabilities.INSTALLED_DATA) 2039 && !oldPkgSigningDetails.checkCapability(parsedPkgSigningDetails, 2040 SigningDetails.CertCapabilities.ROLLBACK)) { 2041 // Allow the update to proceed if this is a rollback and the parsed 2042 // package's current signing key is the current signer or in the lineage 2043 // of the old package; this allows a rollback to a previously installed 2044 // version after an app's signing key has been rotated without requiring 2045 // the rollback capability on the previous signing key. 2046 if (!isRollback || !oldPkgSigningDetails.hasAncestorOrSelf( 2047 parsedPkgSigningDetails)) { 2048 throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 2049 "New package has a different signature: " + pkgName11); 2050 } 2051 } 2052 } 2053 2054 // don't allow a system upgrade unless the upgrade hash matches 2055 if (oldPackageState.getRestrictUpdateHash() != null 2056 && oldPackageState.isSystem()) { 2057 final byte[] digestBytes; 2058 try { 2059 final MessageDigest digest = MessageDigest.getInstance("SHA-512"); 2060 updateDigest(digest, new File(parsedPackage.getBaseApkPath())); 2061 if (!ArrayUtils.isEmpty(parsedPackage.getSplitCodePaths())) { 2062 for (String path : parsedPackage.getSplitCodePaths()) { 2063 updateDigest(digest, new File(path)); 2064 } 2065 } 2066 digestBytes = digest.digest(); 2067 } catch (NoSuchAlgorithmException | IOException e) { 2068 throw new PrepareFailure(INSTALL_FAILED_INVALID_APK, 2069 "Could not compute hash: " + pkgName11); 2070 } 2071 if (!Arrays.equals(oldPackageState.getRestrictUpdateHash(), digestBytes)) { 2072 throw new PrepareFailure(INSTALL_FAILED_INVALID_APK, 2073 "New package fails restrict-update check: " + pkgName11); 2074 } 2075 // retain upgrade restriction 2076 parsedPackage.setRestrictUpdateHash( 2077 oldPackageState.getRestrictUpdateHash()); 2078 } 2079 2080 // APK should not change its sharedUserId declarations 2081 final String oldSharedUid; 2082 if (mPm.mSettings.getSharedUserSettingLPr(oldPackageState) != null) { 2083 oldSharedUid = mPm.mSettings.getSharedUserSettingLPr(oldPackageState).name; 2084 } else { 2085 oldSharedUid = "<nothing>"; 2086 } 2087 String newSharedUid = parsedPackage.getSharedUserId() != null 2088 ? parsedPackage.getSharedUserId() : "<nothing>"; 2089 // If the previously installed app version doesn't have sharedUserSetting, 2090 // check that the new apk either doesn't have sharedUserId or it is leaving one. 2091 // If it contains sharedUserId but it is also leaving it, it's ok to proceed. 2092 if (oldSharedUid.equals("<nothing>")) { 2093 if (parsedPackage.isLeavingSharedUser()) { 2094 newSharedUid = "<nothing>"; 2095 } 2096 } 2097 2098 if (!oldSharedUid.equals(newSharedUid)) { 2099 if (!(oldSharedUid.equals("<nothing>") && ps.getPkg() == null 2100 && ps.isArchivedOnAnyUser(allUsers))) { 2101 // Only allow changing sharedUserId if unarchiving 2102 // TODO(b/361558423): remove this check after pre-archiving installs 2103 // accept a sharedUserId param in the API 2104 throw new PrepareFailure(INSTALL_FAILED_UID_CHANGED, 2105 "Package " + parsedPackage.getPackageName() 2106 + " shared user changed from " 2107 + oldSharedUid + " to " + newSharedUid); 2108 } 2109 } 2110 2111 // APK should not re-join shared UID 2112 if (oldPackageState.isLeavingSharedUser() 2113 && !parsedPackage.isLeavingSharedUser()) { 2114 throw new PrepareFailure(INSTALL_FAILED_UID_CHANGED, 2115 "Package " + parsedPackage.getPackageName() 2116 + " attempting to rejoin " + newSharedUid); 2117 } 2118 2119 // In case of rollback, remember per-user/profile install state 2120 installedUsers = ps.queryInstalledUsers(allUsers, true); 2121 uninstalledUsers = ps.queryInstalledUsers(allUsers, false); 2122 2123 // don't allow an upgrade from full to ephemeral 2124 if (isInstantApp) { 2125 if (request.getUserId() == UserHandle.USER_ALL) { 2126 for (int currentUser : allUsers) { 2127 if (!ps.getInstantApp(currentUser)) { 2128 // can't downgrade from full to instant 2129 Slog.w(TAG, 2130 "Can't replace full app with instant app: " + pkgName11 2131 + " for user: " + currentUser); 2132 throw new PrepareFailure( 2133 PackageManager.INSTALL_FAILED_SESSION_INVALID); 2134 } 2135 } 2136 } else if (!ps.getInstantApp(request.getUserId())) { 2137 // can't downgrade from full to instant 2138 Slog.w(TAG, "Can't replace full app with instant app: " + pkgName11 2139 + " for user: " + request.getUserId()); 2140 throw new PrepareFailure( 2141 PackageManager.INSTALL_FAILED_SESSION_INVALID); 2142 } 2143 } 2144 } 2145 2146 // Update what is removed 2147 PackageRemovedInfo removedInfo = new PackageRemovedInfo(); 2148 removedInfo.mUid = ps.getAppId(); 2149 removedInfo.mRemovedPackage = ps.getPackageName(); 2150 removedInfo.mInstallerPackageName = 2151 ps.getInstallSource().mInstallerPackageName; 2152 removedInfo.mIsStaticSharedLib = 2153 parsedPackage.getStaticSharedLibraryName() != null; 2154 removedInfo.mIsUpdate = true; 2155 removedInfo.mOrigUsers = installedUsers; 2156 removedInfo.mInstallReasons = new SparseIntArray(installedUsers.length); 2157 for (int i = 0; i < installedUsers.length; i++) { 2158 final int userId = installedUsers[i]; 2159 removedInfo.mInstallReasons.put(userId, 2160 ps.getInstallReason(userId)); 2161 } 2162 removedInfo.mUninstallReasons = new SparseIntArray(uninstalledUsers.length); 2163 for (int i = 0; i < uninstalledUsers.length; i++) { 2164 final int userId = uninstalledUsers[i]; 2165 removedInfo.mUninstallReasons.put(userId, 2166 ps.getUninstallReason(userId)); 2167 } 2168 removedInfo.mIsExternal = oldPackageState.isExternalStorage(); 2169 removedInfo.mRemovedPackageVersionCode = oldPackageState.getVersionCode(); 2170 request.setRemovedInfo(removedInfo); 2171 2172 sysPkg = oldPackageState.isSystem(); 2173 if (sysPkg) { 2174 // Set the system/privileged/oem/vendor/product flags as needed 2175 final boolean privileged = oldPackageState.isPrivileged(); 2176 final boolean oem = oldPackageState.isOem(); 2177 final boolean vendor = oldPackageState.isVendor(); 2178 final boolean product = oldPackageState.isProduct(); 2179 final boolean odm = oldPackageState.isOdm(); 2180 final boolean systemExt = oldPackageState.isSystemExt(); 2181 final @ParsingPackageUtils.ParseFlags int systemParseFlags = parseFlags; 2182 final @PackageManagerService.ScanFlags int systemScanFlags = scanFlags 2183 | SCAN_AS_SYSTEM 2184 | (privileged ? SCAN_AS_PRIVILEGED : 0) 2185 | (oem ? SCAN_AS_OEM : 0) 2186 | (vendor ? SCAN_AS_VENDOR : 0) 2187 | (product ? SCAN_AS_PRODUCT : 0) 2188 | (odm ? SCAN_AS_ODM : 0) 2189 | (systemExt ? SCAN_AS_SYSTEM_EXT : 0); 2190 2191 if (DEBUG_INSTALL) { 2192 Slog.d(TAG, "replaceSystemPackageLI: new=" + parsedPackage 2193 + ", old=" + oldPackageState.getName()); 2194 } 2195 request.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 2196 request.setApexModuleName(oldPackageState.getApexModuleName()); 2197 targetParseFlags = systemParseFlags; 2198 targetScanFlags = systemScanFlags; 2199 } else { // non system replace 2200 if (DEBUG_INSTALL) { 2201 Slog.d(TAG, 2202 "replaceNonSystemPackageLI: new=" + parsedPackage + ", old=" 2203 + oldPackageState.getName()); 2204 } 2205 } 2206 } else { // new package install 2207 ps = null; 2208 disabledPs = null; 2209 oldPackageState = null; 2210 // Remember this for later, in case we need to rollback this install 2211 String pkgName1 = parsedPackage.getPackageName(); 2212 2213 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + parsedPackage); 2214 2215 // TODO(b/194319951): MOVE TO RECONCILE 2216 synchronized (mPm.mLock) { 2217 renamedPackage = mPm.mSettings.getRenamedPackageLPr(pkgName1); 2218 if (renamedPackage != null) { 2219 // A package with the same name is already installed, though 2220 // it has been renamed to an older name. The package we 2221 // are trying to install should be installed as an update to 2222 // the existing one, but that has not been requested, so bail. 2223 throw new PrepareFailure(INSTALL_FAILED_ALREADY_EXISTS, 2224 "Attempt to re-install " + pkgName1 2225 + " without first uninstalling package running as " 2226 + renamedPackage); 2227 } 2228 if (mPm.mPackages.containsKey(pkgName1)) { 2229 // Don't allow installation over an existing package with the same name. 2230 throw new PrepareFailure(INSTALL_FAILED_ALREADY_EXISTS, 2231 "Attempt to re-install " + pkgName1 2232 + " without first uninstalling."); 2233 } 2234 } 2235 } 2236 // we're passing the freezer back to be closed in a later phase of install 2237 shouldCloseFreezerBeforeReturn = false; 2238 2239 request.setPrepareResult(replace, targetScanFlags, targetParseFlags, 2240 oldPackageState, parsedPackage, archivedPackage, 2241 replace /* clearCodeCache */, sysPkg, ps, disabledPs); 2242 } finally { 2243 if (freezer != null) { 2244 request.setFreezer(freezer); 2245 if (shouldCloseFreezerBeforeReturn) { 2246 freezer.close(); 2247 } 2248 } 2249 } 2250 } 2251 2252 /** 2253 * Rename package into final resting place. All paths on the given 2254 * scanned package should be updated to reflect the rename. 2255 */ 2256 @GuardedBy("mPm.mInstallLock") doRenameLI(InstallRequest request, ParsedPackage parsedPackage)2257 private void doRenameLI(InstallRequest request, 2258 ParsedPackage parsedPackage) throws PrepareFailure { 2259 final int status = request.getReturnCode(); 2260 final String statusMsg = request.getReturnMsg(); 2261 if (request.isInstallMove()) { 2262 if (status != PackageManager.INSTALL_SUCCEEDED) { 2263 mRemovePackageHelper.cleanUpForMoveInstall(request.getMoveToUuid(), 2264 request.getMovePackageName(), request.getMoveFromCodePath()); 2265 throw new PrepareFailure(status, statusMsg); 2266 } 2267 return; 2268 } 2269 // For file installations 2270 if (status != PackageManager.INSTALL_SUCCEEDED) { 2271 mRemovePackageHelper.removeCodePath(request.getCodeFile()); 2272 throw new PrepareFailure(status, statusMsg); 2273 } 2274 2275 final File targetDir = resolveTargetDir(request.getInstallFlags(), request.getCodeFile()); 2276 final File beforeCodeFile = request.getCodeFile(); 2277 final File afterCodeFile = PackageManagerServiceUtils.getNextCodePath(targetDir, 2278 parsedPackage.getPackageName()); 2279 2280 if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile); 2281 final boolean onIncremental = mPm.mIncrementalManager != null 2282 && isIncrementalPath(beforeCodeFile.getAbsolutePath()); 2283 try { 2284 makeDirRecursive(afterCodeFile.getParentFile(), 0771); 2285 if (onIncremental) { 2286 // Just link files here. The stage dir will be removed when the installation 2287 // session is completed. 2288 mPm.mIncrementalManager.linkCodePath(beforeCodeFile, afterCodeFile); 2289 } else { 2290 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath()); 2291 } 2292 } catch (IOException | ErrnoException e) { 2293 Slog.w(TAG, "Failed to rename", e); 2294 throw new PrepareFailure(PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE, 2295 "Failed to rename"); 2296 } 2297 2298 if (!onIncremental && !SELinux.restoreconRecursive(afterCodeFile)) { 2299 Slog.w(TAG, "Failed to restorecon"); 2300 throw new PrepareFailure(PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE, 2301 "Failed to restorecon"); 2302 } 2303 2304 // Reflect the rename internally 2305 request.setCodeFile(afterCodeFile); 2306 2307 // Reflect the rename in scanned details 2308 try { 2309 String afterCanonicalPath = afterCodeFile.getCanonicalPath(); 2310 String beforeCanonicalPath = beforeCodeFile.getCanonicalPath(); 2311 parsedPackage.setPath(afterCanonicalPath); 2312 2313 parsedPackage.setNativeLibraryDir( 2314 parsedPackage.getNativeLibraryDir() 2315 .replace(beforeCanonicalPath, afterCanonicalPath)); 2316 parsedPackage.setNativeLibraryRootDir( 2317 parsedPackage.getNativeLibraryRootDir() 2318 .replace(beforeCanonicalPath, afterCanonicalPath)); 2319 String secondaryNativeLibraryDir = parsedPackage.getSecondaryNativeLibraryDir(); 2320 if (secondaryNativeLibraryDir != null) { 2321 parsedPackage.setSecondaryNativeLibraryDir( 2322 secondaryNativeLibraryDir.replace(beforeCanonicalPath, afterCanonicalPath)); 2323 } 2324 } catch (IOException e) { 2325 Slog.e(TAG, "Failed to get path: " + afterCodeFile, e); 2326 throw new PrepareFailure(PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE, 2327 "Failed to get path: " + afterCodeFile); 2328 } 2329 parsedPackage.setBaseApkPath(FileUtils.rewriteAfterRename(beforeCodeFile, 2330 afterCodeFile, parsedPackage.getBaseApkPath())); 2331 parsedPackage.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, 2332 afterCodeFile, parsedPackage.getSplitCodePaths())); 2333 request.updateAllCodePaths(AndroidPackageUtils.getAllCodePaths(parsedPackage)); 2334 } 2335 2336 // TODO(b/168126411): Once staged install flow starts using the same folder as non-staged 2337 // flow, we won't need this method anymore. resolveTargetDir(int installFlags, File codeFile)2338 private File resolveTargetDir(int installFlags, File codeFile) { 2339 boolean isStagedInstall = (installFlags & INSTALL_STAGED) != 0; 2340 if (isStagedInstall) { 2341 return Environment.getDataAppDirectory(null); 2342 } else { 2343 return codeFile.getParentFile(); 2344 } 2345 } 2346 2347 /* 2348 * Cannot properly check CANNOT_INSTALL_WITH_BAD_PERMISSION_GROUPS using CompatChanges 2349 * as this only works for packages that are installed 2350 * 2351 * TODO: Move logic for permission group compatibility into PermissionManagerService 2352 */ 2353 @SuppressWarnings("AndroidFrameworkCompatChange") cannotInstallWithBadPermissionGroups(ParsedPackage parsedPackage)2354 private static boolean cannotInstallWithBadPermissionGroups(ParsedPackage parsedPackage) { 2355 return parsedPackage.getTargetSdkVersion() >= Build.VERSION_CODES.S; 2356 } 2357 doesSignatureMatchForPermissions(@onNull String sourcePackageName, @NonNull ParsedPackage parsedPackage, int scanFlags)2358 private boolean doesSignatureMatchForPermissions(@NonNull String sourcePackageName, 2359 @NonNull ParsedPackage parsedPackage, int scanFlags) { 2360 // If the defining package is signed with our cert, it's okay. This 2361 // also includes the "updating the same package" case, of course. 2362 // "updating same package" could also involve key-rotation. 2363 2364 final PackageSetting sourcePackageSetting; 2365 final KeySetManagerService ksms; 2366 final SharedUserSetting sharedUserSetting; 2367 synchronized (mPm.mLock) { 2368 sourcePackageSetting = mPm.mSettings.getPackageLPr(sourcePackageName); 2369 ksms = mPm.mSettings.getKeySetManagerService(); 2370 sharedUserSetting = mPm.mSettings.getSharedUserSettingLPr(sourcePackageSetting); 2371 } 2372 2373 final SigningDetails sourceSigningDetails = (sourcePackageSetting == null 2374 ? SigningDetails.UNKNOWN : sourcePackageSetting.getSigningDetails()); 2375 if (sourcePackageName.equals(parsedPackage.getPackageName()) 2376 && (ksms.shouldCheckUpgradeKeySetLocked( 2377 sourcePackageSetting, sharedUserSetting, scanFlags))) { 2378 return ksms.checkUpgradeKeySetLocked(sourcePackageSetting, parsedPackage); 2379 } else { 2380 2381 // in the event of signing certificate rotation, we need to see if the 2382 // package's certificate has rotated from the current one, or if it is an 2383 // older certificate with which the current is ok with sharing permissions 2384 if (sourceSigningDetails.checkCapability( 2385 parsedPackage.getSigningDetails(), 2386 SigningDetails.CertCapabilities.PERMISSION)) { 2387 return true; 2388 } else if (parsedPackage.getSigningDetails().checkCapability( 2389 sourceSigningDetails, 2390 SigningDetails.CertCapabilities.PERMISSION)) { 2391 // the scanned package checks out, has signing certificate rotation 2392 // history, and is newer; bring it over 2393 synchronized (mPm.mLock) { 2394 sourcePackageSetting.setSigningDetails(parsedPackage.getSigningDetails()); 2395 } 2396 return true; 2397 } else { 2398 return false; 2399 } 2400 } 2401 } 2402 freezePackageForInstall(String packageName, int userId, int installFlags, String killReason, int exitInfoReason, InstallRequest request)2403 private PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags, 2404 String killReason, int exitInfoReason, InstallRequest request) { 2405 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) { 2406 return new PackageFreezer(mPm, request); 2407 } else { 2408 return mPm.freezePackage(packageName, userId, killReason, exitInfoReason, request); 2409 } 2410 } 2411 updateDigest(MessageDigest digest, File file)2412 private static void updateDigest(MessageDigest digest, File file) throws IOException { 2413 try (DigestInputStream digestStream = 2414 new DigestInputStream(new FileInputStream(file), digest)) { 2415 int length, total = 0; 2416 while ((length = digestStream.read()) != -1) { 2417 total += length; 2418 } // just plow through the file 2419 } 2420 } 2421 2422 @GuardedBy("mPm.mLock") commitPackagesLocked(List<ReconciledPackage> reconciledPackages, @NonNull int[] allUsers)2423 private void commitPackagesLocked(List<ReconciledPackage> reconciledPackages, 2424 @NonNull int[] allUsers) { 2425 // TODO: remove any expected failures from this method; this should only be able to fail due 2426 // to unavoidable errors (I/O, etc.) 2427 for (ReconciledPackage reconciledPkg : reconciledPackages) { 2428 final InstallRequest installRequest = reconciledPkg.mInstallRequest; 2429 final ParsedPackage parsedPackage = installRequest.getParsedPackage(); 2430 final String packageName = parsedPackage.getPackageName(); 2431 2432 installRequest.onCommitStarted(); 2433 if (installRequest.isInstallReplace()) { 2434 AndroidPackage oldPackage = mPm.mPackages.get(packageName); 2435 2436 // Set the update and install times 2437 PackageStateInternal deletedPkgSetting = mPm.snapshotComputer() 2438 .getPackageStateInternal(packageName); 2439 // TODO(b/225756739): For rebootless APEX, consider using lastUpdateMillis provided 2440 // by apexd to be more accurate. 2441 installRequest.setScannedPackageSettingFirstInstallTimeFromReplaced( 2442 deletedPkgSetting, allUsers); 2443 long currentTime = System.currentTimeMillis(); 2444 installRequest.setScannedPackageSettingLastUpdateTime(currentTime); 2445 installRequest.setScannedPackageSettingFirstInstallTime(currentTime); 2446 2447 installRequest.getRemovedInfo().mBroadcastAllowList = 2448 mPm.mAppsFilter.getVisibilityAllowList(mPm.snapshotComputer(), 2449 installRequest.getScannedPackageSetting(), 2450 allUsers, mPm.mSettings.getPackagesLocked()); 2451 if (installRequest.isInstallSystem()) { 2452 // Remove existing system package 2453 mRemovePackageHelper.removePackage(oldPackage, true); 2454 if (!disableSystemPackageLPw(oldPackage)) { 2455 // We didn't need to disable the .apk as a current system package, 2456 // which means we are replacing another update that is already 2457 // installed. We need to make sure to delete the older one's .apk. 2458 installRequest.getRemovedInfo().mArgs = new CleanUpArgs( 2459 packageName, 2460 oldPackage.getPath(), 2461 getAppDexInstructionSets( 2462 deletedPkgSetting.getPrimaryCpuAbi(), 2463 deletedPkgSetting.getSecondaryCpuAbi())); 2464 } else { 2465 installRequest.getRemovedInfo().mArgs = null; 2466 } 2467 } else { 2468 try { 2469 // Settings will be written during the call to updateSettingsLI(). 2470 mDeletePackageHelper.executeDeletePackage( 2471 reconciledPkg.mDeletePackageAction, packageName, 2472 true, allUsers, false, installRequest.isKeepArtProfile()); 2473 } catch (SystemDeleteException e) { 2474 if (mPm.mIsEngBuild) { 2475 throw new RuntimeException("Unexpected failure", e); 2476 // ignore; not possible for non-system app 2477 } 2478 } 2479 2480 if (installRequest.getReturnCode() == PackageManager.INSTALL_SUCCEEDED) { 2481 PackageSetting ps2 = mPm.mSettings.getPackageLPr( 2482 parsedPackage.getPackageName()); 2483 if (ps2 != null) { 2484 installRequest.getRemovedInfo().mRemovedForAllUsers = 2485 mPm.mPackages.get(ps2.getPackageName()) == null; 2486 } 2487 } 2488 } 2489 } 2490 2491 AndroidPackage pkg = commitReconciledScanResultLocked(reconciledPkg, allUsers); 2492 updateSettingsLI(pkg, allUsers, installRequest); 2493 2494 final PackageSetting ps = mPm.mSettings.getPackageLPr(packageName); 2495 if (ps != null) { 2496 installRequest.setNewUsers( 2497 ps.queryInstalledUsers(allUsers, true)); 2498 ps.setUpdateAvailable(false /*updateAvailable*/); 2499 } 2500 if (installRequest.getReturnCode() == PackageManager.INSTALL_SUCCEEDED) { 2501 // If this is an archival installation then we'll initialize the archive status, 2502 // while also marking package as not installed. 2503 // Doing this at the very end of the install as we are using ps.getInstalled 2504 // to figure out which users were changed. 2505 mPm.markPackageAsArchivedIfNeeded(ps, 2506 installRequest.getArchivedPackage(), 2507 installRequest.getResponsibleInstallerTitles(), 2508 installRequest.getNewUsers()); 2509 mPm.updateSequenceNumberLP(ps, installRequest.getNewUsers()); 2510 mPm.updateInstantAppInstallerLocked(packageName); 2511 2512 // The installation is success, remove the split info copy stored in package 2513 // setting for the downgrade version check of DELETE_KEEP_DATA and archived app 2514 // cases. 2515 ps.setSplitNames(null); 2516 ps.setSplitRevisionCodes(null); 2517 } 2518 installRequest.onCommitFinished(); 2519 } 2520 ApplicationPackageManager.invalidateGetPackagesForUidCache(); 2521 } 2522 2523 @GuardedBy("mPm.mLock") disableSystemPackageLPw(AndroidPackage oldPkg)2524 private boolean disableSystemPackageLPw(AndroidPackage oldPkg) { 2525 return mPm.mSettings.disableSystemPackageLPw(oldPkg.getPackageName(), true); 2526 } 2527 updateSettingsLI(AndroidPackage newPackage, int[] allUsers, InstallRequest installRequest)2528 private void updateSettingsLI(AndroidPackage newPackage, 2529 int[] allUsers, InstallRequest installRequest) { 2530 updateSettingsInternalLI(newPackage, allUsers, installRequest); 2531 } 2532 updateSettingsInternalLI(AndroidPackage pkg, int[] allUsers, InstallRequest installRequest)2533 private void updateSettingsInternalLI(AndroidPackage pkg, 2534 int[] allUsers, InstallRequest installRequest) { 2535 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettingsInternal"); 2536 2537 final String pkgName = pkg.getPackageName(); 2538 final int[] installedForUsers = installRequest.getOriginUsers(); 2539 final int installReason = installRequest.getInstallReason(); 2540 final String installerPackageName = installRequest.getInstallerPackageName(); 2541 2542 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + pkg.getPath()); 2543 final int userId = installRequest.getUserId(); 2544 if (userId != UserHandle.USER_ALL && userId != UserHandle.USER_CURRENT 2545 && !mPm.mUserManager.exists(userId)) { 2546 installRequest.setError(PackageManagerException.ofInternalError( 2547 "User " + userId + " doesn't exist or has been removed", 2548 PackageManagerException.INTERNAL_ERROR_MISSING_USER)); 2549 return; 2550 } 2551 synchronized (mPm.mLock) { 2552 // For system-bundled packages, we assume that installing an upgraded version 2553 // of the package implies that the user actually wants to run that new code, 2554 // so we enable the package. 2555 final PackageSetting ps = mPm.mSettings.getPackageLPr(pkgName); 2556 if (ps != null) { 2557 if (ps.isSystem()) { 2558 if (DEBUG_INSTALL) { 2559 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName); 2560 } 2561 // Enable system package for requested users 2562 if (installedForUsers != null 2563 && !installRequest.isApplicationEnabledSettingPersistent()) { 2564 for (int origUserId : installedForUsers) { 2565 if (userId == UserHandle.USER_ALL || userId == origUserId) { 2566 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 2567 origUserId, installerPackageName); 2568 } 2569 } 2570 } 2571 // Also convey the prior install/uninstall state 2572 if (allUsers != null && installedForUsers != null) { 2573 for (int currentUserId : allUsers) { 2574 final boolean installed = ArrayUtils.contains( 2575 installedForUsers, currentUserId); 2576 if (DEBUG_INSTALL) { 2577 Slog.d(TAG, " user " + currentUserId + " => " + installed); 2578 } 2579 ps.setInstalled(installed, currentUserId); 2580 } 2581 // these install state changes will be persisted in the 2582 // upcoming call to mSettings.writeLPr(). 2583 } 2584 2585 if (allUsers != null) { 2586 for (int currentUserId : allUsers) { 2587 ps.resetOverrideComponentLabelIcon(currentUserId); 2588 } 2589 } 2590 } 2591 2592 // Retrieve the overlays for shared libraries of the package. 2593 if (!ps.getPkgState().getUsesLibraryInfos().isEmpty()) { 2594 for (SharedLibraryWrapper sharedLib : ps.getPkgState().getUsesLibraryInfos()) { 2595 for (int currentUserId : allUsers) { 2596 if (sharedLib.getType() != SharedLibraryInfo.TYPE_DYNAMIC) { 2597 // TODO(146804378): Support overlaying static shared libraries 2598 continue; 2599 } 2600 final PackageSetting libPs = mPm.mSettings.getPackageLPr( 2601 sharedLib.getPackageName()); 2602 if (libPs == null) { 2603 continue; 2604 } 2605 ps.setOverlayPathsForLibrary(sharedLib.getName(), 2606 libPs.getOverlayPaths(currentUserId), currentUserId); 2607 } 2608 } 2609 } 2610 2611 if (userId != UserHandle.USER_ALL) { 2612 // It's implied that when a user requests installation, they want the app to 2613 // be installed and enabled. The caller, however, can explicitly specify to 2614 // keep the existing enabled state. 2615 ps.setInstalled(true, userId); 2616 if (!installRequest.isApplicationEnabledSettingPersistent()) { 2617 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, 2618 installerPackageName); 2619 } 2620 // Clear any existing archive state. 2621 mPm.mInstallerService.mPackageArchiver.clearArchiveState(ps, userId); 2622 } else if (allUsers != null) { 2623 // The caller explicitly specified INSTALL_ALL_USERS flag. 2624 // Thus, updating the settings to install the app for all users. 2625 for (int currentUserId : allUsers) { 2626 // If the app is already installed for the currentUser, 2627 // keep it as installed as we might be updating the app at this place. 2628 // If not currently installed, check if the currentUser is restricted by 2629 // DISALLOW_INSTALL_APPS or DISALLOW_DEBUGGING_FEATURES device policy. 2630 // Install / update the app if the user isn't restricted. Skip otherwise. 2631 final boolean installedForCurrentUser = ArrayUtils.contains( 2632 installedForUsers, currentUserId); 2633 final boolean restrictedByPolicy = 2634 mPm.isUserRestricted(currentUserId, 2635 UserManager.DISALLOW_INSTALL_APPS) 2636 || mPm.isUserRestricted(currentUserId, 2637 UserManager.DISALLOW_DEBUGGING_FEATURES); 2638 if (installedForCurrentUser || !restrictedByPolicy) { 2639 ps.setInstalled(true, currentUserId); 2640 if (!installRequest.isApplicationEnabledSettingPersistent()) { 2641 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, currentUserId, 2642 installerPackageName); 2643 } 2644 // Clear any existing archive state. 2645 mPm.mInstallerService.mPackageArchiver.clearArchiveState(ps, 2646 currentUserId); 2647 } else { 2648 ps.setInstalled(false, currentUserId); 2649 } 2650 } 2651 } 2652 2653 mPm.mSettings.addInstallerPackageNames(ps.getInstallSource()); 2654 2655 // When replacing an existing package, preserve the original install reason for all 2656 // users that had the package installed before. Similarly for uninstall reasons. 2657 final Set<Integer> previousUserIds = new ArraySet<>(); 2658 if (installRequest.getRemovedInfo() != null 2659 && installRequest.getRemovedInfo().mInstallReasons != null) { 2660 final int installReasonCount = 2661 installRequest.getRemovedInfo().mInstallReasons.size(); 2662 for (int i = 0; i < installReasonCount; i++) { 2663 final int previousUserId = 2664 installRequest.getRemovedInfo().mInstallReasons.keyAt(i); 2665 final int previousInstallReason = 2666 installRequest.getRemovedInfo().mInstallReasons.valueAt(i); 2667 ps.setInstallReason(previousInstallReason, previousUserId); 2668 previousUserIds.add(previousUserId); 2669 } 2670 } 2671 if (installRequest.getRemovedInfo() != null 2672 && installRequest.getRemovedInfo().mUninstallReasons != null) { 2673 for (int i = 0; i < installRequest.getRemovedInfo().mUninstallReasons.size(); 2674 i++) { 2675 final int previousUserId = 2676 installRequest.getRemovedInfo().mUninstallReasons.keyAt(i); 2677 final int previousReason = 2678 installRequest.getRemovedInfo().mUninstallReasons.valueAt(i); 2679 ps.setUninstallReason(previousReason, previousUserId); 2680 } 2681 } 2682 2683 // Set install reason for users that are having the package newly installed. 2684 if (userId == UserHandle.USER_ALL) { 2685 for (int currentUserId : allUsers) { 2686 if (!previousUserIds.contains(currentUserId) 2687 && ps.getInstalled(currentUserId)) { 2688 ps.setInstallReason(installReason, currentUserId); 2689 } 2690 } 2691 } else if (!previousUserIds.contains(userId)) { 2692 ps.setInstallReason(installReason, userId); 2693 } 2694 2695 // TODO(b/169721400): generalize Incremental States and create a Callback object 2696 // that can be used for all the packages. 2697 final String codePath = ps.getPathString(); 2698 if (IncrementalManager.isIncrementalPath(codePath) 2699 && mIncrementalManager != null) { 2700 mIncrementalManager.registerLoadingProgressCallback(codePath, 2701 new IncrementalProgressListener(ps.getPackageName(), mPm)); 2702 } 2703 2704 // Ensure that the uninstall reason is UNKNOWN for users with the package installed. 2705 for (int currentUserId : allUsers) { 2706 if (ps.getInstalled(currentUserId)) { 2707 ps.setUninstallReason(UNINSTALL_REASON_UNKNOWN, currentUserId); 2708 } 2709 } 2710 2711 mPm.mSettings.writeKernelMappingLPr(ps); 2712 2713 final PermissionManagerServiceInternal.PackageInstalledParams.Builder 2714 permissionParamsBuilder = 2715 new PermissionManagerServiceInternal.PackageInstalledParams.Builder(); 2716 final boolean grantRequestedPermissions = (installRequest.getInstallFlags() 2717 & PackageManager.INSTALL_GRANT_ALL_REQUESTED_PERMISSIONS) != 0; 2718 if (grantRequestedPermissions) { 2719 var permissionStates = new ArrayMap<String, Integer>(); 2720 for (var permissionName : pkg.getRequestedPermissions()) { 2721 permissionStates.put(permissionName, 2722 PackageInstaller.SessionParams.PERMISSION_STATE_GRANTED); 2723 } 2724 permissionParamsBuilder.setPermissionStates(permissionStates); 2725 } else { 2726 var permissionStates = installRequest.getPermissionStates(); 2727 if (permissionStates != null) { 2728 permissionParamsBuilder 2729 .setPermissionStates(permissionStates); 2730 } 2731 } 2732 final boolean allowlistAllRestrictedPermissions = 2733 (installRequest.getInstallFlags() 2734 & PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS) != 0; 2735 final List<String> allowlistedRestrictedPermissions = 2736 allowlistAllRestrictedPermissions 2737 ? new ArrayList<>(pkg.getRequestedPermissions()) 2738 : installRequest.getAllowlistedRestrictedPermissions(); 2739 if (allowlistedRestrictedPermissions != null) { 2740 permissionParamsBuilder.setAllowlistedRestrictedPermissions( 2741 allowlistedRestrictedPermissions); 2742 } 2743 final int autoRevokePermissionsMode = installRequest.getAutoRevokePermissionsMode(); 2744 permissionParamsBuilder.setAutoRevokePermissionsMode(autoRevokePermissionsMode); 2745 mPm.mPermissionManager.onPackageInstalled(pkg, installRequest.getPreviousAppId(), 2746 permissionParamsBuilder.build(), userId); 2747 } 2748 installRequest.setName(pkgName); 2749 installRequest.setAppId(pkg.getUid()); 2750 installRequest.setPkg(pkg); 2751 installRequest.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 2752 //to update install status 2753 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 2754 mPm.writeSettingsLPrTEMP(); 2755 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2756 } 2757 2758 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2759 } 2760 setAccessRestrictedSettingsMode(String pkgName, int appId, int userId, int mode)2761 private void setAccessRestrictedSettingsMode(String pkgName, int appId, int userId, int mode) { 2762 final AppOpsManager appOpsManager = mPm.mContext.getSystemService(AppOpsManager.class); 2763 final int uid = UserHandle.getUid(userId, appId); 2764 appOpsManager.setMode(AppOpsManager.OP_ACCESS_RESTRICTED_SETTINGS, 2765 uid, 2766 pkgName, 2767 mode); 2768 } 2769 2770 /** 2771 * On successful install, executes remaining steps after commit completes and the package lock 2772 * is released. These are typically more expensive or require calls to installd, which often 2773 * locks on {@link com.android.server.pm.PackageManagerService.mLock}. 2774 */ 2775 @GuardedBy("mPm.mInstallLock") executePostCommitStepsLIF(List<ReconciledPackage> reconciledPackages)2776 private void executePostCommitStepsLIF(List<ReconciledPackage> reconciledPackages) { 2777 final ArraySet<IncrementalStorage> incrementalStorages = new ArraySet<>(); 2778 for (ReconciledPackage reconciledPkg : reconciledPackages) { 2779 final InstallRequest installRequest = reconciledPkg.mInstallRequest; 2780 final PackageSetting ps = installRequest.getScannedPackageSetting(); 2781 final String packageName = ps.getPackageName(); 2782 final String codePath = ps.getPathString(); 2783 final AndroidPackage pkg = ps.getPkg(); 2784 final boolean onIncremental = mIncrementalManager != null 2785 && isIncrementalPath(codePath); 2786 if (onIncremental) { 2787 IncrementalStorage storage = mIncrementalManager.openStorage(codePath); 2788 if (storage == null) { 2789 throw new IllegalArgumentException( 2790 "Install: null storage for incremental package " + packageName); 2791 } 2792 incrementalStorages.add(storage); 2793 } 2794 2795 if (installRequest.isInstallReplace() && pkg != null) { 2796 mDexManager.notifyPackageUpdated(packageName, 2797 pkg.getBaseApkPath(), pkg.getSplitCodePaths()); 2798 } 2799 if (!Flags.improveInstallFreeze()) { 2800 // Hardcode previousAppId to 0 to disable any data migration (http://b/221088088) 2801 mAppDataHelper.prepareAppDataPostCommitLIF(ps, 0, installRequest.getNewUsers()); 2802 if (installRequest.isClearCodeCache()) { 2803 mAppDataHelper.clearAppDataLIF(ps.getPkg(), UserHandle.USER_ALL, 2804 FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL 2805 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 2806 } 2807 2808 // run synchronous dexopt if the freeze improvement is not supported 2809 DexOptHelper.performDexoptIfNeeded( 2810 installRequest, mDexManager, mPm.mInstallLock.getRawLock()); 2811 } 2812 } 2813 PackageManagerServiceUtils.waitForNativeBinariesExtractionForIncremental( 2814 incrementalStorages); 2815 } 2816 verifyReplacingVersionCode(PackageInfoLite pkgLite, long requiredInstalledVersionCode, int installFlags)2817 Pair<Integer, String> verifyReplacingVersionCode(PackageInfoLite pkgLite, 2818 long requiredInstalledVersionCode, int installFlags) { 2819 if ((installFlags & PackageManager.INSTALL_APEX) != 0) { 2820 return verifyReplacingVersionCodeForApex( 2821 pkgLite, requiredInstalledVersionCode, installFlags); 2822 } 2823 2824 String packageName = pkgLite.packageName; 2825 synchronized (mPm.mLock) { 2826 PackageSetting dataOwnerPs = mPm.mSettings.getPackageLPr(packageName); 2827 if (dataOwnerPs == null) { 2828 if (requiredInstalledVersionCode != PackageManager.VERSION_CODE_HIGHEST) { 2829 String errorMsg = "Required installed version code was " 2830 + requiredInstalledVersionCode 2831 + " but package is not installed"; 2832 Slog.w(TAG, errorMsg); 2833 return Pair.create( 2834 PackageManager.INSTALL_FAILED_WRONG_INSTALLED_VERSION, errorMsg); 2835 } 2836 // The package doesn't exist in the system, don't need to check the version 2837 // replacing. 2838 return Pair.create(PackageManager.INSTALL_SUCCEEDED, null); 2839 } 2840 2841 // Package which currently owns the data that the new package will own if installed. 2842 // If an app is uninstalled while keeping data (e.g. adb uninstall -k), dataOwnerPkg 2843 // will be null whereas dataOwnerPs will contain information about the package 2844 // which was uninstalled while keeping its data. The AndroidPackage object that the 2845 // PackageSetting refers to is the same object that is stored in mPackages. 2846 AndroidPackage dataOwnerPkg = dataOwnerPs.getPkg(); 2847 2848 if (requiredInstalledVersionCode != PackageManager.VERSION_CODE_HIGHEST) { 2849 if (dataOwnerPkg == null) { 2850 String errorMsg = "Required installed version code was " 2851 + requiredInstalledVersionCode 2852 + " but package is not installed"; 2853 Slog.w(TAG, errorMsg); 2854 return Pair.create( 2855 PackageManager.INSTALL_FAILED_WRONG_INSTALLED_VERSION, errorMsg); 2856 } 2857 2858 if (dataOwnerPkg.getLongVersionCode() != requiredInstalledVersionCode) { 2859 String errorMsg = "Required installed version code was " 2860 + requiredInstalledVersionCode 2861 + " but actual installed version is " 2862 + dataOwnerPkg.getLongVersionCode(); 2863 Slog.w(TAG, errorMsg); 2864 return Pair.create( 2865 PackageManager.INSTALL_FAILED_WRONG_INSTALLED_VERSION, errorMsg); 2866 } 2867 } 2868 2869 // If dataOwnerPkg is null but dataOwnerPs is not null, there is always data on 2870 // some users. Wwe should do the downgrade check. E.g. DELETE_KEEP_DATA and 2871 // archived apps 2872 if (dataOwnerPkg == null) { 2873 if (!PackageManagerServiceUtils.isDowngradePermitted(installFlags, 2874 dataOwnerPs.isDebuggable())) { 2875 // The data exists on some users and downgrade is not permitted; a lower 2876 // version of the app will not be allowed. 2877 try { 2878 PackageManagerServiceUtils.checkDowngrade(dataOwnerPs, pkgLite); 2879 } catch (PackageManagerException e) { 2880 String errorMsg = "Downgrade detected on app uninstalled with" 2881 + " DELETE_KEEP_DATA: " + e.getMessage(); 2882 Slog.w(TAG, errorMsg); 2883 return Pair.create( 2884 PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE, errorMsg); 2885 } 2886 } 2887 // dataOwnerPs.getPkg() is not null on system apps case. Don't need to consider 2888 // system apps case like below. 2889 } else if (dataOwnerPkg != null && !dataOwnerPkg.isSdkLibrary()) { 2890 if (!PackageManagerServiceUtils.isDowngradePermitted(installFlags, 2891 dataOwnerPkg.isDebuggable())) { 2892 // Downgrade is not permitted; a lower version of the app will not be allowed 2893 try { 2894 PackageManagerServiceUtils.checkDowngrade(dataOwnerPkg, pkgLite); 2895 } catch (PackageManagerException e) { 2896 String errorMsg = "Downgrade detected: " + e.getMessage(); 2897 Slog.w(TAG, errorMsg); 2898 return Pair.create( 2899 PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE, errorMsg); 2900 } 2901 } else if (dataOwnerPs.isSystem()) { 2902 // Downgrade is permitted, but system apps can't be downgraded below 2903 // the version preloaded onto the system image 2904 final PackageSetting disabledPs = mPm.mSettings.getDisabledSystemPkgLPr( 2905 dataOwnerPs); 2906 if (disabledPs != null) { 2907 dataOwnerPkg = disabledPs.getPkg(); 2908 } 2909 if (!Build.IS_DEBUGGABLE && !dataOwnerPkg.isDebuggable()) { 2910 // Only restrict non-debuggable builds and non-debuggable version of the app 2911 try { 2912 PackageManagerServiceUtils.checkDowngrade(dataOwnerPkg, pkgLite); 2913 } catch (PackageManagerException e) { 2914 String errorMsg = 2915 "System app: " + packageName + " cannot be downgraded to" 2916 + " older than its preloaded version on the system" 2917 + " image. " + e.getMessage(); 2918 Slog.w(TAG, errorMsg); 2919 return Pair.create( 2920 PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE, errorMsg); 2921 } 2922 } 2923 } 2924 } 2925 } 2926 return Pair.create(PackageManager.INSTALL_SUCCEEDED, null); 2927 } 2928 verifyReplacingVersionCodeForApex(PackageInfoLite pkgLite, long requiredInstalledVersionCode, int installFlags)2929 private Pair<Integer, String> verifyReplacingVersionCodeForApex(PackageInfoLite pkgLite, 2930 long requiredInstalledVersionCode, int installFlags) { 2931 String packageName = pkgLite.packageName; 2932 2933 final PackageInfo activePackage = mPm.snapshotComputer().getPackageInfo( 2934 packageName, PackageManager.MATCH_APEX, UserHandle.USER_SYSTEM); 2935 if (activePackage == null) { 2936 String errorMsg = "Attempting to install new APEX package " + packageName; 2937 Slog.w(TAG, errorMsg); 2938 return Pair.create(PackageManager.INSTALL_FAILED_PACKAGE_CHANGED, errorMsg); 2939 } 2940 2941 final long activeVersion = activePackage.getLongVersionCode(); 2942 if (requiredInstalledVersionCode != PackageManager.VERSION_CODE_HIGHEST 2943 && activeVersion != requiredInstalledVersionCode) { 2944 String errorMsg = "Installed version of APEX package " + packageName 2945 + " does not match required. Active version: " + activeVersion 2946 + " required: " + requiredInstalledVersionCode; 2947 Slog.w(TAG, errorMsg); 2948 return Pair.create(PackageManager.INSTALL_FAILED_WRONG_INSTALLED_VERSION, errorMsg); 2949 } 2950 2951 final boolean isAppDebuggable = (activePackage.applicationInfo.flags 2952 & ApplicationInfo.FLAG_DEBUGGABLE) != 0; 2953 final long newVersionCode = pkgLite.getLongVersionCode(); 2954 if (!PackageManagerServiceUtils.isDowngradePermitted(installFlags, isAppDebuggable) 2955 && newVersionCode < activeVersion) { 2956 String errorMsg = "Downgrade of APEX package " + packageName 2957 + " is not allowed. Active version: " + activeVersion 2958 + " attempted: " + newVersionCode; 2959 Slog.w(TAG, errorMsg); 2960 return Pair.create(PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE, errorMsg); 2961 } 2962 2963 return Pair.create(PackageManager.INSTALL_SUCCEEDED, null); 2964 } 2965 getUidForVerifier(VerifierInfo verifierInfo)2966 int getUidForVerifier(VerifierInfo verifierInfo) { 2967 synchronized (mPm.mLock) { 2968 final AndroidPackage pkg = mPm.mPackages.get(verifierInfo.packageName); 2969 if (pkg == null) { 2970 return -1; 2971 } else if (pkg.getSigningDetails().getSignatures().length != 1) { 2972 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 2973 + " has more than one signature; ignoring"); 2974 return -1; 2975 } 2976 2977 /* 2978 * If the public key of the package's signature does not match 2979 * our expected public key, then this is a different package and 2980 * we should skip. 2981 */ 2982 2983 final byte[] expectedPublicKey; 2984 try { 2985 final Signature verifierSig = pkg.getSigningDetails().getSignatures()[0]; 2986 final PublicKey publicKey = verifierSig.getPublicKey(); 2987 expectedPublicKey = publicKey.getEncoded(); 2988 } catch (CertificateException e) { 2989 return -1; 2990 } 2991 2992 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded(); 2993 2994 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) { 2995 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 2996 + " does not have the expected public key; ignoring"); 2997 return -1; 2998 } 2999 3000 return pkg.getUid(); 3001 } 3002 } 3003 sendPendingBroadcasts(String reasonForTrace, int callingUidForTrace)3004 public void sendPendingBroadcasts(String reasonForTrace, int callingUidForTrace) { 3005 String[] packages; 3006 ArrayList<String>[] components; 3007 int numBroadcasts = 0, numUsers; 3008 int[] uids; 3009 3010 synchronized (mPm.mLock) { 3011 final SparseArray<ArrayMap<String, ArrayList<String>>> userIdToPackagesToComponents = 3012 mPm.mPendingBroadcasts.copiedMap(); 3013 numUsers = userIdToPackagesToComponents.size(); 3014 for (int n = 0; n < numUsers; n++) { 3015 numBroadcasts += userIdToPackagesToComponents.valueAt(n).size(); 3016 } 3017 if (numBroadcasts == 0) { 3018 // Nothing to be done. Just return 3019 return; 3020 } 3021 packages = new String[numBroadcasts]; 3022 components = new ArrayList[numBroadcasts]; 3023 uids = new int[numBroadcasts]; 3024 int i = 0; // filling out the above arrays 3025 3026 for (int n = 0; n < numUsers; n++) { 3027 final int packageUserId = userIdToPackagesToComponents.keyAt(n); 3028 final ArrayMap<String, ArrayList<String>> componentsToBroadcast = 3029 userIdToPackagesToComponents.valueAt(n); 3030 final int numComponents = CollectionUtils.size(componentsToBroadcast); 3031 for (int index = 0; index < numComponents; index++) { 3032 packages[i] = componentsToBroadcast.keyAt(index); 3033 components[i] = componentsToBroadcast.valueAt(index); 3034 final PackageSetting ps = mPm.mSettings.getPackageLPr(packages[i]); 3035 uids[i] = (ps != null) 3036 ? UserHandle.getUid(packageUserId, ps.getAppId()) 3037 : -1; 3038 i++; 3039 } 3040 } 3041 numBroadcasts = i; 3042 mPm.mPendingBroadcasts.clear(); 3043 } 3044 final Computer snapshot = mPm.snapshotComputer(); 3045 // Send broadcasts 3046 for (int i = 0; i < numBroadcasts; i++) { 3047 mBroadcastHelper.sendPackageChangedBroadcast(snapshot, packages[i], 3048 true /* dontKillApp */, components[i], uids[i], null /* reason */, 3049 reasonForTrace, callingUidForTrace); 3050 } 3051 } 3052 handlePackagePostInstall(InstallRequest request, boolean launchedForRestore)3053 void handlePackagePostInstall(InstallRequest request, boolean launchedForRestore) { 3054 final boolean killApp = 3055 (request.getInstallFlags() & PackageManager.INSTALL_DONT_KILL_APP) == 0; 3056 final boolean succeeded = request.getReturnCode() == PackageManager.INSTALL_SUCCEEDED; 3057 final boolean update = request.isUpdate(); 3058 final boolean archived = request.isArchived(); 3059 final String packageName = request.getName(); 3060 final Computer snapshot = mPm.snapshotComputer(); 3061 final PackageStateInternal pkgSetting = 3062 succeeded ? snapshot.getPackageStateInternal(packageName) : null; 3063 final boolean removedBeforeUpdate = (pkgSetting == null) 3064 || (pkgSetting.isSystem() && !pkgSetting.getPath().getPath().equals( 3065 request.getPkg().getPath())); 3066 if (succeeded && removedBeforeUpdate) { 3067 Slog.e(TAG, packageName + " was removed before handlePackagePostInstall " 3068 + "could be executed"); 3069 request.setReturnCode(INSTALL_FAILED_PACKAGE_CHANGED); 3070 request.setReturnMessage("Package was removed before install could complete."); 3071 3072 // Remove the update failed package's older resources safely now 3073 mRemovePackageHelper.cleanUpResources(packageName, request.getOldCodeFile(), 3074 request.getOldInstructionSet()); 3075 mPm.notifyInstallObserver(request); 3076 return; 3077 } 3078 3079 if (succeeded) { 3080 Slog.i(TAG, "installation completed for package:" + packageName 3081 + ". Final code path: " + pkgSetting.getPath().getPath()); 3082 3083 if (Flags.aslInApkAppMetadataSource() 3084 && pkgSetting.getAppMetadataSource() == APP_METADATA_SOURCE_APK) { 3085 if (!extractAppMetadataFromApk(request.getPkg(), 3086 pkgSetting.getAppMetadataFilePath(), pkgSetting.isSystem())) { 3087 synchronized (mPm.mLock) { 3088 PackageSetting setting = mPm.mSettings.getPackageLPr(packageName); 3089 if (setting != null) { 3090 setting.setAppMetadataFilePath(null) 3091 .setAppMetadataSource(APP_METADATA_SOURCE_UNKNOWN); 3092 } 3093 } 3094 } 3095 } 3096 3097 // Clear the uid cache after we installed a new package. 3098 mPm.mPerUidReadTimeoutsCache = null; 3099 3100 mPm.notifyInstantAppPackageInstalled(request.getPkg().getPackageName(), 3101 request.getNewUsers()); 3102 3103 final int[] firstUserIds = request.getFirstTimeBroadcastUserIds(); 3104 3105 if (request.getPkg().getStaticSharedLibraryName() == null) { 3106 mPm.mProcessLoggingHandler.invalidateBaseApkHash(request.getPkg().getBaseApkPath()); 3107 } 3108 3109 mBroadcastHelper.sendPostInstallBroadcasts(mPm::snapshotComputer, request, packageName, 3110 mPm.mRequiredPermissionControllerPackage, mPm.mRequiredVerifierPackages, 3111 mPm.mRequiredInstallerPackage, 3112 /* packageSender= */ mPm, launchedForRestore, killApp, update, archived); 3113 3114 if (request.isAllNewUsers() && !update) { 3115 mPm.notifyPackageAdded(packageName, request.getAppId()); 3116 } else { 3117 mPm.notifyPackageChanged(packageName, request.getAppId()); 3118 } 3119 3120 // Set the OP_ACCESS_RESTRICTED_SETTINGS op, which is used by ECM (see {@link 3121 // EnhancedConfirmationManager}) as a persistent state denoting whether an app is 3122 // currently guarded by ECM, not guarded by ECM or (in Android V+) that this should 3123 // be decided later. In Android B, the op's default mode was updated to the 3124 // "should be decided later" case, and so this step is now unnecessary. 3125 if (!android.permission.flags.Flags.enhancedConfirmationModeApisEnabled() 3126 || !android.security.Flags.extendEcmToAllSettings()) { 3127 // Apply restricted settings on potentially dangerous packages. Needs to happen 3128 // after appOpsManager is notified of the new package 3129 if (request.getPackageSource() == PackageInstaller.PACKAGE_SOURCE_LOCAL_FILE 3130 || request.getPackageSource() 3131 == PackageInstaller.PACKAGE_SOURCE_DOWNLOADED_FILE) { 3132 final int appId = request.getAppId(); 3133 mPm.mHandler.post(() -> { 3134 for (int userId : firstUserIds) { 3135 // MODE_ERRORED means that the app is explicitly guarded 3136 setAccessRestrictedSettingsMode(packageName, appId, userId, 3137 AppOpsManager.MODE_ERRORED); 3138 } 3139 }); 3140 } 3141 } 3142 3143 // Log current value of "unknown sources" setting 3144 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED, 3145 getUnknownSourcesSettings()); 3146 3147 // Remove the replaced package's older resources safely now 3148 CleanUpArgs args = request.getRemovedInfo() != null 3149 ? request.getRemovedInfo().mArgs : null; 3150 if (args != null) { 3151 if (!killApp) { 3152 // If we didn't kill the app, defer the deletion of code/resource files, 3153 // since the old code/resource files may still be in use by the running 3154 // application. This mitigates problems and cases where resources or 3155 // code is loaded by a new Activity before ApplicationInfo changes have 3156 // propagated to all application threads. 3157 mPm.scheduleDeferredNoKillPostDelete(args); 3158 if (Flags.improveInstallDontKill()) { 3159 try (var installLock = mPm.mInstallLock.acquireLock()) { 3160 PackageManagerServiceUtils.linkFilesToOldDirs(mPm.mInstaller, 3161 packageName, pkgSetting.getPath(), pkgSetting.getOldPaths()); 3162 } 3163 } 3164 } else { 3165 mRemovePackageHelper.cleanUpResources(packageName, args.getCodeFile(), 3166 args.getInstructionSets()); 3167 } 3168 } else { 3169 // Force a gc to clear up things. Ask for a background one, it's fine to go on 3170 // and not block here. 3171 VMRuntime.getRuntime().requestConcurrentGC(); 3172 } 3173 3174 if (!archived) { 3175 // Notify DexManager that the package was installed for new users. 3176 // The updated users should already be indexed and the package code paths 3177 // should not change. 3178 // Don't notify the manager for ephemeral apps as they are not expected to 3179 // survive long enough to benefit of background optimizations. 3180 for (int userId : firstUserIds) { 3181 PackageInfo info = snapshot.getPackageInfo(packageName, /*flags*/ 0, userId); 3182 // There's a race currently where some install events may interleave with an 3183 // uninstall. This can lead to package info being null (b/36642664). 3184 if (info != null) { 3185 mDexManager.notifyPackageInstalled(info, userId); 3186 } 3187 } 3188 } else { 3189 // Now send PACKAGE_REMOVED + EXTRA_REPLACING broadcast. 3190 final PackageRemovedInfo info = new PackageRemovedInfo(); 3191 info.mRemovedPackage = packageName; 3192 info.mInstallerPackageName = request.getInstallerPackageName(); 3193 info.mRemovedUsers = firstUserIds; 3194 info.mBroadcastUsers = firstUserIds; 3195 info.mUid = request.getAppId(); 3196 info.mRemovedPackageVersionCode = request.getPkg().getLongVersionCode(); 3197 info.mRemovedForAllUsers = true; 3198 3199 mBroadcastHelper.sendPackageRemovedBroadcasts(info, mPm, 3200 false /*killApp*/, false /*removedBySystem*/, true /*isArchived*/); 3201 } 3202 } 3203 3204 final boolean deferInstallObserver = succeeded && update; 3205 if (deferInstallObserver) { 3206 if (killApp) { 3207 mPm.scheduleDeferredPendingKillInstallObserver(request); 3208 } else { 3209 mPm.scheduleDeferredNoKillInstallObserver(request); 3210 } 3211 } else { 3212 mPm.notifyInstallObserver(request); 3213 } 3214 3215 // Prune unused static shared libraries which have been cached a period of time 3216 mPm.schedulePruneUnusedStaticSharedLibraries(true /* delay */); 3217 3218 // Log tracing if needed 3219 if (request.getTraceMethod() != null) { 3220 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, request.getTraceMethod(), 3221 request.getTraceCookie()); 3222 } 3223 } 3224 3225 /** 3226 * Get the "allow unknown sources" setting. 3227 * 3228 * @return the current "allow unknown sources" setting 3229 */ getUnknownSourcesSettings()3230 private int getUnknownSourcesSettings() { 3231 return android.provider.Settings.Secure.getIntForUser(mContext.getContentResolver(), 3232 android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS, 3233 -1, UserHandle.USER_SYSTEM); 3234 } 3235 3236 /** 3237 * Uncompress and install stub applications. 3238 * <p>In order to save space on the system partition, some applications are shipped in a 3239 * compressed form. In addition the compressed bits for the full application, the 3240 * system image contains a tiny stub comprised of only the Android manifest. 3241 * <p>During the first boot, attempt to uncompress and install the full application. If 3242 * the application can't be installed for any reason, disable the stub and prevent 3243 * uncompressing the full application during future boots. 3244 * <p>In order to forcefully attempt an installation of a full application, go to app 3245 * settings and enable the application. 3246 */ 3247 @GuardedBy({"mPm.mLock", "mPm.mInstallLock"}) installSystemStubPackages(@onNull List<String> systemStubPackageNames, @PackageManagerService.ScanFlags int scanFlags)3248 void installSystemStubPackages(@NonNull List<String> systemStubPackageNames, 3249 @PackageManagerService.ScanFlags int scanFlags) { 3250 for (int i = systemStubPackageNames.size() - 1; i >= 0; --i) { 3251 final String packageName = systemStubPackageNames.get(i); 3252 // skip if the system package is already disabled 3253 if (mPm.mSettings.isDisabledSystemPackageLPr(packageName)) { 3254 systemStubPackageNames.remove(i); 3255 continue; 3256 } 3257 // skip if the package isn't installed (?!); this should never happen 3258 final AndroidPackage pkg = mPm.mPackages.get(packageName); 3259 if (pkg == null) { 3260 systemStubPackageNames.remove(i); 3261 continue; 3262 } 3263 // skip if the package has been disabled by the user 3264 final PackageSetting ps = mPm.mSettings.getPackageLPr(packageName); 3265 if (ps != null) { 3266 final int enabledState = ps.getEnabled(UserHandle.USER_SYSTEM); 3267 if (enabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) { 3268 systemStubPackageNames.remove(i); 3269 continue; 3270 } 3271 } 3272 3273 // install the package to replace the stub on /system 3274 try { 3275 installStubPackageLI(pkg, 0, scanFlags); 3276 ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, 3277 UserHandle.USER_SYSTEM, "android"); 3278 systemStubPackageNames.remove(i); 3279 } catch (PackageManagerException e) { 3280 Slog.e(TAG, "Failed to parse uncompressed system package: " + e.getMessage()); 3281 } 3282 3283 // any failed attempt to install the package will be cleaned up later 3284 } 3285 3286 // disable any stub still left; these failed to install the full application 3287 for (int i = systemStubPackageNames.size() - 1; i >= 0; --i) { 3288 final String pkgName = systemStubPackageNames.get(i); 3289 final PackageSetting ps = mPm.mSettings.getPackageLPr(pkgName); 3290 ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 3291 UserHandle.USER_SYSTEM, "android"); 3292 logCriticalInfo(Log.ERROR, "Stub disabled; pkg: " + pkgName); 3293 } 3294 } 3295 3296 /** 3297 * Extract, install and enable a stub package. 3298 * <p>If the compressed file can not be extracted / installed for any reason, the stub 3299 * APK will be installed and the package will be disabled. To recover from this situation, 3300 * the user will need to go into system settings and re-enable the package. 3301 */ enableCompressedPackage(AndroidPackage stubPkg, @NonNull PackageSetting stubPkgSetting)3302 boolean enableCompressedPackage(AndroidPackage stubPkg, 3303 @NonNull PackageSetting stubPkgSetting) { 3304 final int parseFlags = mPm.getDefParseFlags() | ParsingPackageUtils.PARSE_CHATTY 3305 | ParsingPackageUtils.PARSE_ENFORCE_CODE; 3306 try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) { 3307 final AndroidPackage pkg; 3308 try (PackageFreezer freezer = 3309 mPm.freezePackage(stubPkg.getPackageName(), UserHandle.USER_ALL, 3310 "setEnabledSetting", 3311 ApplicationExitInfo.REASON_PACKAGE_UPDATED, null /* request */)) { 3312 pkg = installStubPackageLI(stubPkg, parseFlags, 0 /*scanFlags*/); 3313 mAppDataHelper.prepareAppDataAfterInstallLIF(pkg); 3314 synchronized (mPm.mLock) { 3315 try { 3316 mSharedLibraries.updateSharedLibraries( 3317 pkg, stubPkgSetting, null, null, 3318 Collections.unmodifiableMap(mPm.mPackages)); 3319 } catch (PackageManagerException e) { 3320 Slog.w(TAG, "updateAllSharedLibrariesLPw failed: ", e); 3321 } 3322 mPm.mPermissionManager.onPackageInstalled(pkg, 3323 Process.INVALID_UID /* previousAppId */, 3324 PermissionManagerServiceInternal.PackageInstalledParams.DEFAULT, 3325 UserHandle.USER_ALL); 3326 mPm.writeSettingsLPrTEMP(); 3327 // Since compressed package can be system app only, we do not need to 3328 // set restricted settings on it. 3329 } 3330 } catch (PackageManagerException e) { 3331 // Whoops! Something went very wrong; roll back to the stub and disable the package 3332 try (PackageFreezer freezer = 3333 mPm.freezePackage(stubPkg.getPackageName(), UserHandle.USER_ALL, 3334 "setEnabledSetting", 3335 ApplicationExitInfo.REASON_PACKAGE_UPDATED, 3336 null /* request */)) { 3337 synchronized (mPm.mLock) { 3338 // NOTE: Ensure the system package is enabled; even for a compressed stub. 3339 // If we don't, installing the system package fails during scan 3340 mPm.mSettings.enableSystemPackageLPw(stubPkg.getPackageName()); 3341 } 3342 installPackageFromSystemLIF(stubPkg.getPath(), 3343 mPm.mUserManager.getUserIds() /*allUserHandles*/, 3344 null /*origUserHandles*/, 3345 true /*writeSettings*/); 3346 } catch (PackageManagerException pme) { 3347 // Serious WTF; we have to be able to install the stub 3348 Slog.wtf(TAG, "Failed to restore system package:" + stubPkg.getPackageName(), 3349 pme); 3350 } finally { 3351 // Disable the package; the stub by itself is not runnable 3352 synchronized (mPm.mLock) { 3353 final PackageSetting stubPs = mPm.mSettings.getPackageLPr( 3354 stubPkg.getPackageName()); 3355 if (stubPs != null) { 3356 stubPs.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, 3357 UserHandle.USER_SYSTEM, "android"); 3358 } 3359 mPm.writeSettingsLPrTEMP(); 3360 } 3361 } 3362 return false; 3363 } 3364 mAppDataHelper.clearAppDataLIF(pkg, UserHandle.USER_ALL, 3365 FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL 3366 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 3367 mDexManager.notifyPackageUpdated(pkg.getPackageName(), 3368 pkg.getBaseApkPath(), pkg.getSplitCodePaths()); 3369 } 3370 return true; 3371 } 3372 3373 @GuardedBy("mPm.mInstallLock") installStubPackageLI(AndroidPackage stubPkg, @ParsingPackageUtils.ParseFlags int parseFlags, @PackageManagerService.ScanFlags int scanFlags)3374 private AndroidPackage installStubPackageLI(AndroidPackage stubPkg, 3375 @ParsingPackageUtils.ParseFlags int parseFlags, 3376 @PackageManagerService.ScanFlags int scanFlags) 3377 throws PackageManagerException { 3378 if (DEBUG_COMPRESSION) { 3379 Slog.i(TAG, "Uncompressing system stub; pkg: " + stubPkg.getPackageName()); 3380 } 3381 // uncompress the binary to its eventual destination on /data 3382 final File scanFile = decompressPackage(stubPkg.getPackageName(), stubPkg.getPath()); 3383 if (scanFile == null) { 3384 throw PackageManagerException.ofInternalError( 3385 "Unable to decompress stub at " + stubPkg.getPath(), 3386 PackageManagerException.INTERNAL_ERROR_DECOMPRESS_STUB); 3387 } 3388 synchronized (mPm.mLock) { 3389 mPm.mSettings.disableSystemPackageLPw(stubPkg.getPackageName(), true /*replaced*/); 3390 } 3391 mRemovePackageHelper.removePackage(stubPkg, true /*chatty*/); 3392 try { 3393 return initPackageTracedLI(scanFile, parseFlags, scanFlags); 3394 } catch (PackageManagerException e) { 3395 Slog.w(TAG, "Failed to install compressed system package:" + stubPkg.getPackageName(), 3396 e); 3397 // Remove the failed install 3398 mRemovePackageHelper.removeCodePath(scanFile); 3399 throw e; 3400 } 3401 } 3402 3403 /** 3404 * Decompresses the given package on the system image onto 3405 * the /data partition. 3406 * @return The directory the package was decompressed into. Otherwise, {@code null}. 3407 */ 3408 @GuardedBy("mPm.mInstallLock") decompressPackage(String packageName, String codePath)3409 private File decompressPackage(String packageName, String codePath) { 3410 if (!compressedFileExists(codePath)) { 3411 if (DEBUG_COMPRESSION) { 3412 Slog.i(TAG, "No files to decompress at: " + codePath); 3413 } 3414 return null; 3415 } 3416 final File dstCodePath = 3417 PackageManagerServiceUtils.getNextCodePath(Environment.getDataAppDirectory(null), 3418 packageName); 3419 int ret = PackageManagerServiceUtils.decompressFiles(codePath, dstCodePath, packageName); 3420 if (ret == PackageManager.INSTALL_SUCCEEDED) { 3421 ret = PackageManagerServiceUtils.extractNativeBinaries(dstCodePath, packageName); 3422 } 3423 if (ret == PackageManager.INSTALL_SUCCEEDED) { 3424 // NOTE: During boot, we have to delay releasing cblocks for no other reason than 3425 // we cannot retrieve the setting {@link Secure#RELEASE_COMPRESS_BLOCKS_ON_INSTALL}. 3426 // When we no longer need to read that setting, cblock release can occur always 3427 // occur here directly 3428 if (!mPm.isSystemReady()) { 3429 if (mPm.mReleaseOnSystemReady == null) { 3430 mPm.mReleaseOnSystemReady = new ArrayList<>(); 3431 } 3432 mPm.mReleaseOnSystemReady.add(dstCodePath); 3433 } else { 3434 final ContentResolver resolver = mContext.getContentResolver(); 3435 F2fsUtils.releaseCompressedBlocks(resolver, dstCodePath); 3436 } 3437 } else { 3438 if (!dstCodePath.exists()) { 3439 return null; 3440 } 3441 mRemovePackageHelper.removeCodePath(dstCodePath); 3442 return null; 3443 } 3444 3445 return dstCodePath; 3446 } 3447 3448 /** 3449 * Tries to restore the disabled system package after an update has been deleted. 3450 */ 3451 @GuardedBy("mPm.mInstallLock") restoreDisabledSystemPackageLIF(DeletePackageAction action, @NonNull int[] allUserHandles, boolean writeSettings)3452 public void restoreDisabledSystemPackageLIF(DeletePackageAction action, 3453 @NonNull int[] allUserHandles, boolean writeSettings) throws SystemDeleteException { 3454 final PackageSetting deletedPs = action.mDeletingPs; 3455 final PackageRemovedInfo outInfo = action.mRemovedInfo; 3456 final PackageSetting disabledPs = action.mDisabledPs; 3457 3458 synchronized (mPm.mLock) { 3459 // NOTE: The system package always needs to be enabled; even if it's for 3460 // a compressed stub. If we don't, installing the system package fails 3461 // during scan [scanning checks the disabled packages]. We will reverse 3462 // this later, after we've "installed" the stub. 3463 // Reinstate the old system package 3464 mPm.mSettings.enableSystemPackageLPw(disabledPs.getPkg().getPackageName()); 3465 // Remove any native libraries from the upgraded package. 3466 PackageManagerServiceUtils.removeNativeBinariesLI(deletedPs); 3467 } 3468 // Install the system package 3469 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs); 3470 try { 3471 final int[] origUsers = outInfo == null ? null : outInfo.mOrigUsers; 3472 try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) { 3473 installPackageFromSystemLIF(disabledPs.getPathString(), allUserHandles, 3474 origUsers, writeSettings); 3475 } 3476 if (origUsers != null) { 3477 mPm.commitPackageStateMutation(null, mutator -> { 3478 for (int userId : origUsers) { 3479 mutator.forPackage(disabledPs.getPackageName()) 3480 .userState(userId) 3481 .setOverlayPaths(deletedPs.getOverlayPaths(userId)); 3482 } 3483 }); 3484 } 3485 } catch (PackageManagerException e) { 3486 Slog.w(TAG, "Failed to restore system package:" + deletedPs.getPackageName() + ": " 3487 + e.getMessage()); 3488 // TODO(b/194319951): can we avoid this; throw would come from scan... 3489 throw new SystemDeleteException(e); 3490 } finally { 3491 if (disabledPs.getPkg().isStub()) { 3492 // We've re-installed the stub; make sure it's disabled here. If package was 3493 // originally enabled, we'll install the compressed version of the application 3494 // and re-enable it afterward. 3495 synchronized (mPm.mLock) { 3496 disableStubPackage(action, deletedPs, allUserHandles); 3497 } 3498 } 3499 } 3500 } 3501 3502 @GuardedBy("mPm.mLock") disableStubPackage(DeletePackageAction action, PackageSetting deletedPs, @NonNull int[] allUserHandles)3503 private void disableStubPackage(DeletePackageAction action, PackageSetting deletedPs, 3504 @NonNull int[] allUserHandles) { 3505 final PackageSetting stubPs = mPm.mSettings.getPackageLPr( 3506 deletedPs.getPackageName()); 3507 if (stubPs != null) { 3508 int userId = action.mUser == null 3509 ? UserHandle.USER_ALL : action.mUser.getIdentifier(); 3510 if (userId == UserHandle.USER_ALL) { 3511 for (int aUserId : allUserHandles) { 3512 stubPs.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, aUserId, "android"); 3513 } 3514 } else if (userId >= UserHandle.USER_SYSTEM) { 3515 stubPs.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, userId, "android"); 3516 } 3517 } 3518 } 3519 3520 /** 3521 * Installs a package that's already on the system partition. 3522 */ 3523 @GuardedBy("mPm.mInstallLock") installPackageFromSystemLIF(@onNull String codePathString, @NonNull int[] allUserHandles, @Nullable int[] origUserHandles, boolean writeSettings)3524 private void installPackageFromSystemLIF(@NonNull String codePathString, 3525 @NonNull int[] allUserHandles, @Nullable int[] origUserHandles, 3526 boolean writeSettings) 3527 throws PackageManagerException { 3528 final File codePath = new File(codePathString); 3529 @ParsingPackageUtils.ParseFlags int parseFlags = 3530 mPm.getDefParseFlags() 3531 | ParsingPackageUtils.PARSE_MUST_BE_APK 3532 | ParsingPackageUtils.PARSE_IS_SYSTEM_DIR; 3533 @PackageManagerService.ScanFlags int scanFlags = mPm.getSystemPackageScanFlags(codePath); 3534 final AndroidPackage pkg = initPackageTracedLI(codePath, parseFlags, scanFlags); 3535 3536 synchronized (mPm.mLock) { 3537 PackageSetting pkgSetting = mPm.mSettings.getPackageLPr(pkg.getPackageName()); 3538 try { 3539 // update shared libraries for the newly re-installed system package 3540 mSharedLibraries.updateSharedLibraries(pkg, pkgSetting, null, null, 3541 Collections.unmodifiableMap(mPm.mPackages)); 3542 } catch (PackageManagerException e) { 3543 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 3544 } 3545 } 3546 setPackageInstalledForSystemPackage(pkg, allUserHandles, origUserHandles, writeSettings); 3547 3548 mAppDataHelper.prepareAppDataAfterInstallLIF(pkg); 3549 } 3550 setPackageInstalledForSystemPackage(@onNull AndroidPackage pkg, @NonNull int[] allUserHandles, @Nullable int[] origUserHandles, boolean writeSettings)3551 private void setPackageInstalledForSystemPackage(@NonNull AndroidPackage pkg, 3552 @NonNull int[] allUserHandles, @Nullable int[] origUserHandles, 3553 boolean writeSettings) { 3554 // writer 3555 synchronized (mPm.mLock) { 3556 PackageSetting ps = mPm.mSettings.getPackageLPr(pkg.getPackageName()); 3557 3558 final boolean applyUserRestrictions = origUserHandles != null; 3559 if (applyUserRestrictions) { 3560 boolean installedStateChanged = false; 3561 if (DEBUG_REMOVE) { 3562 Slog.d(TAG, "Propagating install state across reinstall"); 3563 } 3564 for (int userId : allUserHandles) { 3565 final boolean installed = ArrayUtils.contains(origUserHandles, userId); 3566 if (DEBUG_REMOVE) { 3567 Slog.d(TAG, " user " + userId + " => " + installed); 3568 } 3569 if (installed != ps.getInstalled(userId)) { 3570 installedStateChanged = true; 3571 } 3572 ps.setInstalled(installed, userId); 3573 if (installed) { 3574 ps.setUninstallReason(UNINSTALL_REASON_UNKNOWN, userId); 3575 } 3576 } 3577 // Regardless of writeSettings we need to ensure that this restriction 3578 // state propagation is persisted 3579 mPm.mSettings.writeAllUsersPackageRestrictionsLPr(); 3580 if (installedStateChanged) { 3581 mPm.mSettings.writeKernelMappingLPr(ps); 3582 } 3583 } 3584 3585 // The method below will take care of removing obsolete permissions and granting 3586 // install permissions. 3587 mPm.mPermissionManager.onPackageInstalled(pkg, Process.INVALID_UID, 3588 PermissionManagerServiceInternal.PackageInstalledParams.DEFAULT, 3589 UserHandle.USER_ALL); 3590 for (final int userId : allUserHandles) { 3591 if (applyUserRestrictions) { 3592 mPm.mSettings.writePermissionStateForUserLPr(userId, false); 3593 } 3594 } 3595 3596 // can downgrade to reader here 3597 if (writeSettings) { 3598 mPm.writeSettingsLPrTEMP(); 3599 } 3600 } 3601 } 3602 3603 @GuardedBy("mPm.mLock") prepareSystemPackageCleanUp( WatchedArrayMap<String, PackageSetting> packageSettings, List<String> possiblyDeletedUpdatedSystemApps, ArrayMap<String, File> expectingBetter, int[] userIds)3604 public void prepareSystemPackageCleanUp( 3605 WatchedArrayMap<String, PackageSetting> packageSettings, 3606 List<String> possiblyDeletedUpdatedSystemApps, 3607 ArrayMap<String, File> expectingBetter, int[] userIds) { 3608 // Iterates PackageSettings in reversed order because the item could be removed 3609 // during the iteration. 3610 for (int index = packageSettings.size() - 1; index >= 0; index--) { 3611 final PackageSetting ps = packageSettings.valueAt(index); 3612 final String packageName = ps.getPackageName(); 3613 /* 3614 * If this is not a system app, it can't be a 3615 * disable system app. 3616 */ 3617 if (!ps.isSystem()) { 3618 continue; 3619 } 3620 3621 /* 3622 * If the package is scanned, it's not erased. 3623 */ 3624 final AndroidPackage scannedPkg = mPm.mPackages.get(packageName); 3625 final PackageSetting disabledPs = 3626 mPm.mSettings.getDisabledSystemPkgLPr(packageName); 3627 if (scannedPkg != null) { 3628 if (scannedPkg.isApex()) { 3629 // APEX on /data has been scanned. No need to expect better. 3630 continue; 3631 } 3632 /* 3633 * If the system app is both scanned and in the 3634 * disabled packages list, then it must have been 3635 * added via OTA. Remove it from the currently 3636 * scanned package so the previously user-installed 3637 * application can be scanned. 3638 */ 3639 if (disabledPs != null) { 3640 logCriticalInfo(Log.WARN, 3641 "Expecting better updated system app for " 3642 + packageName 3643 + "; removing system app. Last known" 3644 + " codePath=" + ps.getPathString() 3645 + ", versionCode=" + ps.getVersionCode() 3646 + "; scanned versionCode=" 3647 + scannedPkg.getLongVersionCode()); 3648 mRemovePackageHelper.removePackage(scannedPkg, true); 3649 expectingBetter.put(ps.getPackageName(), ps.getPath()); 3650 } 3651 3652 continue; 3653 } 3654 3655 if (disabledPs == null) { 3656 logCriticalInfo(Log.WARN, "System package " + packageName 3657 + " no longer exists; its data will be wiped"); 3658 mRemovePackageHelper.removePackageData(ps, userIds); 3659 } else { 3660 // we still have a disabled system package, but, it still might have 3661 // been removed. check the code path still exists and check there's 3662 // still a package. the latter can happen if an OTA keeps the same 3663 // code path, but, changes the package name. 3664 if (disabledPs.getPath() == null || !disabledPs.getPath().exists() 3665 || disabledPs.getPkg() == null) { 3666 possiblyDeletedUpdatedSystemApps.add(packageName); 3667 } else { 3668 // We're expecting that the system app should remain disabled, but add 3669 // it to expecting better to recover in case the data version cannot 3670 // be scanned. 3671 expectingBetter.put(disabledPs.getPackageName(), disabledPs.getPath()); 3672 } 3673 } 3674 } 3675 } 3676 3677 @GuardedBy("mPm.mLock") 3678 // Remove disable package settings for updated system apps that were 3679 // removed via an OTA. If the update is no longer present, remove the 3680 // app completely. Otherwise, revoke their system privileges. cleanupDisabledPackageSettings(List<String> possiblyDeletedUpdatedSystemApps, int[] userIds, int scanFlags)3681 public void cleanupDisabledPackageSettings(List<String> possiblyDeletedUpdatedSystemApps, 3682 int[] userIds, int scanFlags) { 3683 for (int i = possiblyDeletedUpdatedSystemApps.size() - 1; i >= 0; --i) { 3684 final String packageName = possiblyDeletedUpdatedSystemApps.get(i); 3685 final AndroidPackage pkg = mPm.mPackages.get(packageName); 3686 final String msg; 3687 3688 // remove from the disabled system list; do this first so any future 3689 // scans of this package are performed without this state 3690 mPm.mSettings.removeDisabledSystemPackageLPw(packageName); 3691 3692 if (pkg == null) { 3693 // should have found an update, but, we didn't; remove everything 3694 msg = "Updated system package " + packageName 3695 + " no longer exists; removing its data"; 3696 // Actual deletion of code and data will be handled by later 3697 // reconciliation step 3698 } else { 3699 // found an update; revoke system privileges 3700 msg = "Updated system package " + packageName 3701 + " no longer exists; rescanning package on data"; 3702 3703 // NOTE: We don't do anything special if a stub is removed from the 3704 // system image. But, if we were [like removing the uncompressed 3705 // version from the /data partition], this is where it'd be done. 3706 3707 // remove the package from the system and re-scan it without any 3708 // special privileges 3709 mRemovePackageHelper.removePackage(pkg, true); 3710 PackageSetting ps = mPm.mSettings.getPackageLPr(packageName); 3711 if (ps != null) { 3712 ps.getPkgState().setUpdatedSystemApp(false); 3713 } 3714 final File codePath = new File(pkg.getPath()); 3715 try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) { 3716 initPackageTracedLI(codePath, 0, scanFlags); 3717 } catch (PackageManagerException e) { 3718 Slog.e(TAG, "Failed to parse updated, ex-system package: " 3719 + e.getMessage()); 3720 } 3721 } 3722 3723 // one final check. if we still have a package setting [ie. it was 3724 // previously scanned and known to the system], but, we don't have 3725 // a package [ie. there was an error scanning it from the /data 3726 // partition], completely remove the package data. 3727 final PackageSetting ps = mPm.mSettings.getPackageLPr(packageName); 3728 if (ps != null && mPm.mPackages.get(packageName) == null) { 3729 mRemovePackageHelper.removePackageData(ps, userIds); 3730 } 3731 logCriticalInfo(Log.WARN, msg); 3732 } 3733 } 3734 3735 /** 3736 * Scans APEX packages and registers them with the system. 3737 * 3738 * apexd has its own policy to decide which APEX to activate and which not. The policy might 3739 * conflicts that of PMS. The APEX package info stored in PMS is a mirror of that managed by 3740 * apexd. To keep things simple and keep activation status in sync for both apexd and PMS, we 3741 * don't persist APEX in settings and always scan APEX from scratch during boot. However, some 3742 * data like lastUpdateTime will be lost if PackageSetting is not persisted for APEX. 3743 * 3744 * TODO(b/225756739): Read lastUpdateTime from ApexInfoList to populate PackageSetting correctly 3745 */ 3746 @GuardedBy({"mPm.mInstallLock", "mPm.mLock"}) scanApexPackages(ApexInfo[] allPackages, int parseFlags, int scanFlags, PackageParser2 packageParser, ExecutorService executorService)3747 public List<ApexManager.ScanResult> scanApexPackages(ApexInfo[] allPackages, int parseFlags, 3748 int scanFlags, PackageParser2 packageParser, ExecutorService executorService) { 3749 if (allPackages == null) { 3750 return Collections.EMPTY_LIST; 3751 } 3752 3753 ParallelPackageParser parallelPackageParser = 3754 new ParallelPackageParser(packageParser, executorService); 3755 3756 // Submit files for parsing in parallel 3757 ArrayMap<File, ApexInfo> parsingApexInfo = new ArrayMap<>(); 3758 for (ApexInfo ai : allPackages) { 3759 File apexFile = new File(ai.modulePath); 3760 parallelPackageParser.submit(apexFile, parseFlags); 3761 parsingApexInfo.put(apexFile, ai); 3762 } 3763 3764 List<ParallelPackageParser.ParseResult> parseResults = 3765 new ArrayList<>(parsingApexInfo.size()); 3766 for (int i = 0; i < parsingApexInfo.size(); i++) { 3767 ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take(); 3768 parseResults.add(parseResult); 3769 } 3770 // Sort the list to ensure we always process factory packages first 3771 Collections.sort(parseResults, (a, b) -> { 3772 ApexInfo i1 = parsingApexInfo.get(a.scanFile); 3773 ApexInfo i2 = parsingApexInfo.get(b.scanFile); 3774 return Boolean.compare(i2.isFactory, i1.isFactory); 3775 }); 3776 3777 3778 // Process results one by one 3779 List<ApexManager.ScanResult> results = new ArrayList<>(parsingApexInfo.size()); 3780 for (int i = 0; i < parseResults.size(); i++) { 3781 ParallelPackageParser.ParseResult parseResult = parseResults.get(i); 3782 Throwable throwable = parseResult.throwable; 3783 ApexInfo ai = parsingApexInfo.get(parseResult.scanFile); 3784 int newParseFlags = parseFlags; 3785 int newScanFlags = scanFlags | SCAN_AS_APEX 3786 | mPm.getSystemPackageScanFlags(parseResult.scanFile); 3787 if (!ai.isFactory) { 3788 newParseFlags &= ~ParsingPackageUtils.PARSE_IS_SYSTEM_DIR; 3789 newScanFlags |= SCAN_NEW_INSTALL; 3790 } 3791 3792 if (throwable == null) { 3793 try { 3794 addForInitLI(parseResult.parsedPackage, newParseFlags, newScanFlags, null, 3795 new ApexManager.ActiveApexInfo(ai)); 3796 AndroidPackage pkg = parseResult.parsedPackage.hideAsFinal(); 3797 if (ai.isFactory && !ai.isActive) { 3798 disableSystemPackageLPw(pkg); 3799 } 3800 results.add(new ApexManager.ScanResult(ai, pkg, pkg.getPackageName())); 3801 } catch (PackageManagerException e) { 3802 throw new IllegalStateException("Failed to scan: " + ai.modulePath, e); 3803 } 3804 } else if (throwable instanceof PackageManagerException) { 3805 throw new IllegalStateException("Unable to parse: " + ai.modulePath, throwable); 3806 } else { 3807 throw new IllegalStateException("Unexpected exception occurred while parsing " 3808 + ai.modulePath, throwable); 3809 } 3810 } 3811 3812 return results; 3813 } 3814 3815 @GuardedBy({"mPm.mInstallLock", "mPm.mLock"}) installPackagesFromDir(File scanDir, int parseFlags, int scanFlags, PackageParser2 packageParser, ExecutorService executorService, @Nullable ApexManager.ActiveApexInfo apexInfo)3816 public void installPackagesFromDir(File scanDir, int parseFlags, 3817 int scanFlags, PackageParser2 packageParser, ExecutorService executorService, 3818 @Nullable ApexManager.ActiveApexInfo apexInfo) { 3819 final File[] files = scanDir.listFiles(); 3820 if (ArrayUtils.isEmpty(files)) { 3821 Log.d(TAG, "No files in app dir " + scanDir); 3822 return; 3823 } 3824 3825 if (DEBUG_PACKAGE_SCANNING) { 3826 Log.d(TAG, "Scanning app dir " + scanDir + " scanFlags=" + scanFlags 3827 + " flags=0x" + Integer.toHexString(parseFlags)); 3828 } 3829 ParallelPackageParser parallelPackageParser = 3830 new ParallelPackageParser(packageParser, executorService); 3831 3832 // Submit files for parsing in parallel 3833 int fileCount = 0; 3834 for (File file : files) { 3835 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 3836 && !PackageInstallerService.isStageName(file.getName()); 3837 if (!isPackage) { 3838 // Ignore entries which are not packages 3839 continue; 3840 } 3841 if ((scanFlags & SCAN_DROP_CACHE) != 0) { 3842 final PackageCacher cacher = new PackageCacher(mPm.getCacheDir(), 3843 mPm.mPackageParserCallback); 3844 Log.w(TAG, "Dropping cache of " + file.getAbsolutePath()); 3845 cacher.cleanCachedResult(file); 3846 } 3847 parallelPackageParser.submit(file, parseFlags); 3848 fileCount++; 3849 } 3850 3851 // Process results one by one 3852 for (; fileCount > 0; fileCount--) { 3853 ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take(); 3854 Throwable throwable = parseResult.throwable; 3855 int errorCode = PackageManager.INSTALL_SUCCEEDED; 3856 String errorMsg = null; 3857 3858 if (throwable == null) { 3859 try { 3860 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "addForInitLI"); 3861 addForInitLI(parseResult.parsedPackage, parseFlags, scanFlags, 3862 new UserHandle(UserHandle.USER_SYSTEM), apexInfo); 3863 } catch (PackageManagerException e) { 3864 errorCode = e.error; 3865 errorMsg = "Failed to scan " + parseResult.scanFile + ": " + e.getMessage(); 3866 Slog.w(TAG, errorMsg); 3867 } finally { 3868 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 3869 } 3870 } else if (throwable instanceof PackageManagerException) { 3871 PackageManagerException e = (PackageManagerException) throwable; 3872 errorCode = e.error; 3873 errorMsg = "Failed to parse " + parseResult.scanFile + ": " + e.getMessage(); 3874 Slog.w(TAG, errorMsg); 3875 } else { 3876 throw new IllegalStateException("Unexpected exception occurred while parsing " 3877 + parseResult.scanFile, throwable); 3878 } 3879 3880 if ((scanFlags & SCAN_AS_APK_IN_APEX) != 0 && errorCode != INSTALL_SUCCEEDED) { 3881 mApexManager.reportErrorWithApkInApex(scanDir.getAbsolutePath(), errorMsg); 3882 } 3883 3884 // Delete invalid userdata apps 3885 if ((scanFlags & SCAN_AS_SYSTEM) == 0 3886 && errorCode != PackageManager.INSTALL_SUCCEEDED) { 3887 logCriticalInfo(Log.WARN, 3888 "Deleting invalid package at " + parseResult.scanFile); 3889 mRemovePackageHelper.removeCodePath(parseResult.scanFile); 3890 } 3891 } 3892 } 3893 3894 /** 3895 * Make sure all system apps that we expected to appear on 3896 * the userdata partition actually showed up. If they never 3897 * appeared, crawl back and revive the system version. 3898 */ 3899 @GuardedBy("mPm.mLock") checkExistingBetterPackages(ArrayMap<String, File> expectingBetterPackages, List<String> stubSystemApps, int systemScanFlags, int systemParseFlags)3900 public void checkExistingBetterPackages(ArrayMap<String, File> expectingBetterPackages, 3901 List<String> stubSystemApps, int systemScanFlags, int systemParseFlags) { 3902 for (int i = 0; i < expectingBetterPackages.size(); i++) { 3903 final String packageName = expectingBetterPackages.keyAt(i); 3904 if (mPm.mPackages.containsKey(packageName)) { 3905 continue; 3906 } 3907 final File scanFile = expectingBetterPackages.valueAt(i); 3908 3909 logCriticalInfo(Log.WARN, "Expected better " + packageName 3910 + " but never showed up; reverting to system"); 3911 3912 final Pair<Integer, Integer> rescanAndReparseFlags = 3913 mPm.getSystemPackageRescanFlagsAndReparseFlags(scanFile, 3914 systemScanFlags, systemParseFlags); 3915 @PackageManagerService.ScanFlags int rescanFlags = rescanAndReparseFlags.first; 3916 @ParsingPackageUtils.ParseFlags int reparseFlags = rescanAndReparseFlags.second; 3917 3918 if (rescanFlags == 0) { 3919 Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile); 3920 continue; 3921 } 3922 mPm.mSettings.enableSystemPackageLPw(packageName); 3923 3924 try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) { 3925 final AndroidPackage newPkg = initPackageTracedLI( 3926 scanFile, reparseFlags, rescanFlags); 3927 // We rescanned a stub, add it to the list of stubbed system packages 3928 if (newPkg.isStub()) { 3929 stubSystemApps.add(packageName); 3930 } 3931 } catch (PackageManagerException e) { 3932 Slog.e(TAG, "Failed to parse original system package: " 3933 + e.getMessage()); 3934 } 3935 } 3936 } 3937 3938 /** 3939 * Traces a package scan and registers it with the system. 3940 * @see #initPackageLI(File, int, int) 3941 */ 3942 @GuardedBy("mPm.mInstallLock") initPackageTracedLI(File scanFile, final int parseFlags, int scanFlags)3943 public AndroidPackage initPackageTracedLI(File scanFile, final int parseFlags, int scanFlags) 3944 throws PackageManagerException { 3945 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]"); 3946 try { 3947 return initPackageLI(scanFile, parseFlags, scanFlags); 3948 } finally { 3949 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 3950 } 3951 } 3952 3953 /** 3954 * Scans a package, registers it with the system and returns the newly parsed package. 3955 * Returns {@code null} in case of errors and the error code is stored in mLastScanError 3956 */ 3957 @GuardedBy("mPm.mInstallLock") initPackageLI(File scanFile, int parseFlags, int scanFlags)3958 private AndroidPackage initPackageLI(File scanFile, int parseFlags, int scanFlags) 3959 throws PackageManagerException { 3960 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile); 3961 3962 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage"); 3963 final ParsedPackage parsedPackage; 3964 try (PackageParser2 pp = mPm.mInjector.getScanningPackageParser()) { 3965 parsedPackage = pp.parsePackage(scanFile, parseFlags, false); 3966 } catch (PackageParserException e) { 3967 throw new PackageManagerException(e.error, e.getMessage(), e); 3968 } finally { 3969 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 3970 } 3971 3972 return addForInitLI(parsedPackage, parseFlags, scanFlags, 3973 new UserHandle(UserHandle.USER_SYSTEM), null); 3974 } 3975 3976 /** 3977 * Adds a new package to the internal data structures during platform initialization. 3978 * <p>After adding, the package is known to the system and available for querying. 3979 * <p>For packages located on the device ROM [eg. packages located in /system, /vendor, 3980 * etc...], additional checks are performed. Basic verification [such as ensuring 3981 * matching signatures, checking version codes, etc...] occurs if the package is 3982 * identical to a previously known package. If the package fails a signature check, 3983 * the version installed on /data will be removed. If the version of the new package 3984 * is less than or equal than the version on /data, it will be ignored. 3985 * <p>Regardless of the package location, the results are applied to the internal 3986 * structures and the package is made available to the rest of the system. 3987 * <p>NOTE: The return value should be removed. It's the passed in package object. 3988 */ 3989 @GuardedBy("mPm.mInstallLock") addForInitLI(ParsedPackage parsedPackage, @ParsingPackageUtils.ParseFlags int parseFlags, @PackageManagerService.ScanFlags int scanFlags, @Nullable UserHandle user, @Nullable ApexManager.ActiveApexInfo activeApexInfo)3990 private AndroidPackage addForInitLI(ParsedPackage parsedPackage, 3991 @ParsingPackageUtils.ParseFlags int parseFlags, 3992 @PackageManagerService.ScanFlags int scanFlags, 3993 @Nullable UserHandle user, @Nullable ApexManager.ActiveApexInfo activeApexInfo) 3994 throws PackageManagerException { 3995 PackageSetting disabledPkgSetting; 3996 synchronized (mPm.mLock) { 3997 // Static shared libraries have synthetic package names 3998 if (activeApexInfo == null && parsedPackage.isStaticSharedLibrary()) { 3999 PackageManagerService.renameStaticSharedLibraryPackage(parsedPackage); 4000 } 4001 disabledPkgSetting = 4002 mPm.mSettings.getDisabledSystemPkgLPr(parsedPackage.getPackageName()); 4003 if (activeApexInfo != null && disabledPkgSetting != null) { 4004 // When a disabled system package is scanned, its final PackageSetting is actually 4005 // skipped and not added to any data structures, instead relying on the disabled 4006 // setting read from the persisted Settings XML file. This persistence does not 4007 // include the APEX module name, so here, re-set it from the active APEX info. 4008 // 4009 // This also has the (beneficial) side effect where if a package disappears from an 4010 // APEX, leaving only a /data copy, it will lose its apexModuleName. 4011 // 4012 // This must be done before scanPackageForInitLI as that will throw in the case of a 4013 // system -> data package. 4014 disabledPkgSetting.setApexModuleName(activeApexInfo.apexModuleName); 4015 } 4016 } 4017 4018 final Pair<ScanResult, Boolean> scanResultPair = scanPackageForInitLI( 4019 parsedPackage, parseFlags, scanFlags, user); 4020 final ScanResult scanResult = scanResultPair.first; 4021 boolean shouldHideSystemApp = scanResultPair.second; 4022 final InstallRequest installRequest = new InstallRequest( 4023 parsedPackage, parseFlags, scanFlags, user, scanResult, disabledPkgSetting); 4024 4025 String existingApexModuleName = null; 4026 synchronized (mPm.mLock) { 4027 var existingPkgSetting = mPm.mSettings.getPackageLPr(parsedPackage.getPackageName()); 4028 if (existingPkgSetting != null) { 4029 existingApexModuleName = existingPkgSetting.getApexModuleName(); 4030 } 4031 } 4032 4033 if (activeApexInfo != null) { 4034 installRequest.setApexModuleName(activeApexInfo.apexModuleName); 4035 } else { 4036 if (disabledPkgSetting != null) { 4037 installRequest.setApexModuleName(disabledPkgSetting.getApexModuleName()); 4038 } else if (existingApexModuleName != null) { 4039 installRequest.setApexModuleName(existingApexModuleName); 4040 } 4041 } 4042 4043 synchronized (mPm.mLock) { 4044 boolean appIdCreated = false; 4045 try { 4046 final String pkgName = scanResult.mPkgSetting.getPackageName(); 4047 final List<ReconciledPackage> reconcileResult = 4048 ReconcilePackageUtils.reconcilePackages( 4049 Collections.singletonList(installRequest), 4050 mPm.mPackages, Collections.singletonMap(pkgName, 4051 mPm.getSettingsVersionForPackage(parsedPackage)), 4052 mSharedLibraries, mPm.mSettings.getKeySetManagerService(), 4053 mPm.mSettings, mPm.mInjector.getSystemConfig()); 4054 if ((scanFlags & SCAN_AS_APEX) == 0) { 4055 appIdCreated = optimisticallyRegisterAppId(installRequest); 4056 } else { 4057 installRequest.setScannedPackageSettingAppId(Process.INVALID_UID); 4058 } 4059 commitReconciledScanResultLocked(reconcileResult.get(0), 4060 mPm.mUserManager.getUserIds()); 4061 } catch (PackageManagerException e) { 4062 if (appIdCreated) { 4063 cleanUpAppIdCreation(installRequest); 4064 } 4065 throw e; 4066 } 4067 } 4068 4069 if (shouldHideSystemApp) { 4070 synchronized (mPm.mLock) { 4071 mPm.mSettings.disableSystemPackageLPw(parsedPackage.getPackageName(), true); 4072 } 4073 } 4074 4075 if (mIncrementalManager != null && isIncrementalPath(parsedPackage.getPath())) { 4076 if (scanResult.mPkgSetting != null && scanResult.mPkgSetting.isLoading()) { 4077 // Continue monitoring loading progress of active incremental packages 4078 mIncrementalManager.registerLoadingProgressCallback(parsedPackage.getPath(), 4079 new IncrementalProgressListener(parsedPackage.getPackageName(), mPm)); 4080 } 4081 } 4082 4083 if (Flags.aslInApkAppMetadataSource() 4084 && scanResult.mPkgSetting.getAppMetadataSource() == APP_METADATA_SOURCE_APK) { 4085 if (!extractAppMetadataFromApk(parsedPackage, 4086 scanResult.mPkgSetting.getAppMetadataFilePath(), 4087 scanResult.mPkgSetting.isSystem())) { 4088 synchronized (mPm.mLock) { 4089 scanResult.mPkgSetting.setAppMetadataFilePath(null) 4090 .setAppMetadataSource(APP_METADATA_SOURCE_UNKNOWN); 4091 } 4092 } 4093 } 4094 return scanResult.mPkgSetting.getPkg(); 4095 } 4096 4097 /** 4098 * Prepares the system to commit a {@link ScanResult} in a way that will not fail by registering 4099 * the app ID required for reconcile. 4100 * @return {@code true} if a new app ID was registered and will need to be cleaned up on 4101 * failure. 4102 */ optimisticallyRegisterAppId(@onNull InstallRequest installRequest)4103 private boolean optimisticallyRegisterAppId(@NonNull InstallRequest installRequest) 4104 throws PackageManagerException { 4105 if (!installRequest.isExistingSettingCopied() || installRequest.needsNewAppId()) { 4106 synchronized (mPm.mLock) { 4107 // THROWS: when we can't allocate a user id. add call to check if there's 4108 // enough space to ensure we won't throw; otherwise, don't modify state 4109 return mPm.mSettings.registerAppIdLPw(installRequest.getScannedPackageSetting(), 4110 installRequest.needsNewAppId()); 4111 } 4112 } 4113 return false; 4114 } 4115 4116 /** 4117 * Reverts any app ID creation that were made by 4118 * {@link #optimisticallyRegisterAppId(InstallRequest)}. Note: this is only necessary if the 4119 * referenced method returned true. 4120 */ cleanUpAppIdCreation(@onNull InstallRequest installRequest)4121 private void cleanUpAppIdCreation(@NonNull InstallRequest installRequest) { 4122 // iff we've acquired an app ID for a new package setting, remove it so that it can be 4123 // acquired by another request. 4124 if (installRequest.getScannedPackageSetting() != null 4125 && installRequest.getScannedPackageSetting().getAppId() > 0) { 4126 synchronized (mPm.mLock) { 4127 mPm.mSettings.removeAppIdLPw(installRequest.getScannedPackageSetting().getAppId()); 4128 } 4129 } 4130 } 4131 scanPackageTraced(ParsedPackage parsedPackage, final @ParsingPackageUtils.ParseFlags int parseFlags, @PackageManagerService.ScanFlags int scanFlags, long currentTime, @Nullable UserHandle user, String cpuAbiOverride)4132 private ScanResult scanPackageTraced(ParsedPackage parsedPackage, 4133 final @ParsingPackageUtils.ParseFlags int parseFlags, 4134 @PackageManagerService.ScanFlags int scanFlags, long currentTime, 4135 @Nullable UserHandle user, String cpuAbiOverride) throws PackageManagerException { 4136 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage"); 4137 try { 4138 return scanPackageNew(parsedPackage, parseFlags, scanFlags, currentTime, user, 4139 cpuAbiOverride); 4140 } finally { 4141 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 4142 } 4143 } 4144 prepareInitialScanRequest(@onNull ParsedPackage parsedPackage, @ParsingPackageUtils.ParseFlags int parseFlags, @PackageManagerService.ScanFlags int scanFlags, @Nullable UserHandle user, String cpuAbiOverride)4145 private ScanRequest prepareInitialScanRequest(@NonNull ParsedPackage parsedPackage, 4146 @ParsingPackageUtils.ParseFlags int parseFlags, 4147 @PackageManagerService.ScanFlags int scanFlags, 4148 @Nullable UserHandle user, String cpuAbiOverride) 4149 throws PackageManagerException { 4150 final AndroidPackage platformPackage; 4151 final String realPkgName; 4152 final PackageSetting disabledPkgSetting; 4153 final PackageSetting installedPkgSetting; 4154 final PackageSetting originalPkgSetting; 4155 final SharedUserSetting sharedUserSetting; 4156 SharedUserSetting oldSharedUserSetting = null; 4157 4158 synchronized (mPm.mLock) { 4159 platformPackage = mPm.getPlatformPackage(); 4160 var isSystemApp = AndroidPackageLegacyUtils.isSystem(parsedPackage); 4161 final String renamedPkgName = mPm.mSettings.getRenamedPackageLPr( 4162 AndroidPackageUtils.getRealPackageOrNull(parsedPackage, isSystemApp)); 4163 realPkgName = ScanPackageUtils.getRealPackageName(parsedPackage, renamedPkgName, 4164 isSystemApp); 4165 if (realPkgName != null) { 4166 ScanPackageUtils.ensurePackageRenamed(parsedPackage, renamedPkgName); 4167 } 4168 originalPkgSetting = getOriginalPackageLocked(parsedPackage, renamedPkgName); 4169 installedPkgSetting = mPm.mSettings.getPackageLPr(parsedPackage.getPackageName()); 4170 if (mPm.mTransferredPackages.contains(parsedPackage.getPackageName())) { 4171 Slog.w(TAG, "Package " + parsedPackage.getPackageName() 4172 + " was transferred to another, but its .apk remains"); 4173 } 4174 disabledPkgSetting = mPm.mSettings.getDisabledSystemPkgLPr( 4175 parsedPackage.getPackageName()); 4176 4177 boolean ignoreSharedUserId = false; 4178 if (installedPkgSetting == null || !installedPkgSetting.hasSharedUser()) { 4179 // Directly ignore sharedUserSetting for new installs, or if the app has 4180 // already left shared UID 4181 ignoreSharedUserId = parsedPackage.isLeavingSharedUser(); 4182 } 4183 4184 if (!ignoreSharedUserId && parsedPackage.getSharedUserId() != null) { 4185 sharedUserSetting = mPm.mSettings.getSharedUserLPw( 4186 parsedPackage.getSharedUserId(), 4187 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/); 4188 } else { 4189 sharedUserSetting = null; 4190 } 4191 if (DEBUG_PACKAGE_SCANNING 4192 && (parseFlags & ParsingPackageUtils.PARSE_CHATTY) != 0 4193 && sharedUserSetting != null) { 4194 Log.d(TAG, "Shared UserID " + parsedPackage.getSharedUserId() 4195 + " (uid=" + sharedUserSetting.mAppId + "):" 4196 + " packages=" + sharedUserSetting.getPackageStates()); 4197 } 4198 if (installedPkgSetting != null) { 4199 oldSharedUserSetting = mPm.mSettings.getSharedUserSettingLPr(installedPkgSetting); 4200 } 4201 } 4202 4203 final boolean isPlatformPackage = platformPackage != null 4204 && platformPackage.getPackageName().equals(parsedPackage.getPackageName()); 4205 4206 return new ScanRequest(parsedPackage, oldSharedUserSetting, 4207 installedPkgSetting == null ? null : installedPkgSetting.getPkg() /* oldPkg */, 4208 installedPkgSetting /* packageSetting */, 4209 sharedUserSetting, 4210 disabledPkgSetting /* disabledPackageSetting */, 4211 originalPkgSetting /* originalPkgSetting */, 4212 realPkgName, parseFlags, scanFlags, isPlatformPackage, user, cpuAbiOverride); 4213 } 4214 scanPackageNew(@onNull ParsedPackage parsedPackage, final @ParsingPackageUtils.ParseFlags int parseFlags, @PackageManagerService.ScanFlags int scanFlags, long currentTime, @Nullable UserHandle user, String cpuAbiOverride)4215 private ScanResult scanPackageNew(@NonNull ParsedPackage parsedPackage, 4216 final @ParsingPackageUtils.ParseFlags int parseFlags, 4217 @PackageManagerService.ScanFlags int scanFlags, long currentTime, 4218 @Nullable UserHandle user, String cpuAbiOverride) 4219 throws PackageManagerException { 4220 final ScanRequest initialScanRequest = prepareInitialScanRequest(parsedPackage, parseFlags, 4221 scanFlags, user, cpuAbiOverride); 4222 final PackageSetting installedPkgSetting = initialScanRequest.mPkgSetting; 4223 final PackageSetting disabledPkgSetting = initialScanRequest.mDisabledPkgSetting; 4224 4225 boolean isUpdatedSystemApp; 4226 if (installedPkgSetting != null) { 4227 isUpdatedSystemApp = installedPkgSetting.isUpdatedSystemApp(); 4228 } else { 4229 isUpdatedSystemApp = disabledPkgSetting != null; 4230 } 4231 4232 final int newScanFlags = adjustScanFlags(scanFlags, installedPkgSetting, disabledPkgSetting, 4233 user, parsedPackage); 4234 ScanPackageUtils.applyPolicy(parsedPackage, newScanFlags, 4235 mPm.getPlatformPackage(), isUpdatedSystemApp); 4236 4237 synchronized (mPm.mLock) { 4238 assertPackageIsValid(parsedPackage, parseFlags, newScanFlags); 4239 final ScanRequest request = new ScanRequest(parsedPackage, 4240 initialScanRequest.mOldSharedUserSetting, 4241 initialScanRequest.mOldPkg, installedPkgSetting, 4242 initialScanRequest.mSharedUserSetting, disabledPkgSetting, 4243 initialScanRequest.mOriginalPkgSetting, initialScanRequest.mRealPkgName, 4244 parseFlags, scanFlags, initialScanRequest.mIsPlatformPackage, user, 4245 cpuAbiOverride); 4246 return ScanPackageUtils.scanPackageOnly(request, mPm.mInjector, mPm.mFactoryTest, 4247 currentTime); 4248 } 4249 } 4250 scanPackageForInitLI(ParsedPackage parsedPackage, @ParsingPackageUtils.ParseFlags int parseFlags, @PackageManagerService.ScanFlags int scanFlags, @Nullable UserHandle user)4251 private Pair<ScanResult, Boolean> scanPackageForInitLI(ParsedPackage parsedPackage, 4252 @ParsingPackageUtils.ParseFlags int parseFlags, 4253 @PackageManagerService.ScanFlags int scanFlags, 4254 @Nullable UserHandle user) throws PackageManagerException { 4255 final boolean scanSystemPartition = 4256 (parseFlags & ParsingPackageUtils.PARSE_IS_SYSTEM_DIR) != 0; 4257 final ScanRequest initialScanRequest = prepareInitialScanRequest(parsedPackage, parseFlags, 4258 scanFlags, user, null); 4259 final PackageSetting installedPkgSetting = initialScanRequest.mPkgSetting; 4260 final PackageSetting originalPkgSetting = initialScanRequest.mOriginalPkgSetting; 4261 final PackageSetting pkgSetting = 4262 originalPkgSetting == null ? installedPkgSetting : originalPkgSetting; 4263 final boolean pkgAlreadyExists = pkgSetting != null; 4264 final String disabledPkgName = pkgAlreadyExists 4265 ? pkgSetting.getPackageName() : parsedPackage.getPackageName(); 4266 final boolean isSystemPkgUpdated; 4267 final PackageSetting disabledPkgSetting; 4268 final boolean isUpgrade; 4269 synchronized (mPm.mLock) { 4270 isUpgrade = mPm.isDeviceUpgrading(); 4271 if (scanSystemPartition && !pkgAlreadyExists 4272 && mPm.mSettings.getDisabledSystemPkgLPr(disabledPkgName) != null) { 4273 // The updated-package data for /system apk remains inconsistently 4274 // after the package data for /data apk is lost accidentally. 4275 // To recover it, enable /system apk and install it as non-updated system app. 4276 Slog.w(TAG, "Inconsistent package setting of updated system app for " 4277 + disabledPkgName + ". To recover it, enable the system app " 4278 + "and install it as non-updated system app."); 4279 mPm.mSettings.removeDisabledSystemPackageLPw(disabledPkgName); 4280 } 4281 disabledPkgSetting = mPm.mSettings.getDisabledSystemPkgLPr(disabledPkgName); 4282 isSystemPkgUpdated = disabledPkgSetting != null; 4283 4284 if (DEBUG_INSTALL && isSystemPkgUpdated) { 4285 Slog.d(TAG, "updatedPkg = " + disabledPkgSetting); 4286 } 4287 4288 if (scanSystemPartition && isSystemPkgUpdated) { 4289 // we're updating the disabled package, so, scan it as the package setting 4290 final ScanRequest request = new ScanRequest(parsedPackage, 4291 mPm.mSettings.getSharedUserSettingLPr(disabledPkgSetting), 4292 null, disabledPkgSetting /* pkgSetting */, 4293 initialScanRequest.mSharedUserSetting, 4294 null /* disabledPkgSetting */, null /* originalPkgSetting */, 4295 null, parseFlags, scanFlags, 4296 initialScanRequest.mIsPlatformPackage, user, null); 4297 ScanPackageUtils.applyPolicy(parsedPackage, scanFlags, 4298 mPm.getPlatformPackage(), true); 4299 final ScanResult scanResult = 4300 ScanPackageUtils.scanPackageOnly(request, mPm.mInjector, 4301 mPm.mFactoryTest, -1L); 4302 if (scanResult.mExistingSettingCopied 4303 && scanResult.mRequest.mPkgSetting != null) { 4304 scanResult.mRequest.mPkgSetting.updateFrom(scanResult.mPkgSetting); 4305 } 4306 } 4307 } // End of mLock 4308 4309 final boolean newPkgChangedPaths = pkgAlreadyExists 4310 && !pkgSetting.getPathString().equals(parsedPackage.getPath()); 4311 final boolean newPkgVersionGreater = pkgAlreadyExists 4312 && parsedPackage.getLongVersionCode() > pkgSetting.getVersionCode(); 4313 final boolean newSharedUserSetting = pkgAlreadyExists 4314 && (initialScanRequest.mOldSharedUserSetting 4315 != initialScanRequest.mSharedUserSetting); 4316 final boolean isSystemPkgBetter = scanSystemPartition && isSystemPkgUpdated 4317 && newPkgChangedPaths && (newPkgVersionGreater || newSharedUserSetting); 4318 if (isSystemPkgBetter) { 4319 // The version of the application on /system is greater than the version on 4320 // /data. Switch back to the application on /system. 4321 // It's safe to assume the application on /system will correctly scan. If not, 4322 // there won't be a working copy of the application. 4323 // Also, if the sharedUserSetting of the application on /system is different 4324 // from the sharedUserSetting on /data, switch back to the application on /system. 4325 // We should trust the sharedUserSetting on /system, even if the application 4326 // version on /system is smaller than the version on /data. 4327 synchronized (mPm.mLock) { 4328 // just remove the loaded entries from package lists 4329 mPm.mPackages.remove(pkgSetting.getPackageName()); 4330 } 4331 4332 logCriticalInfo(Log.WARN, 4333 "System package updated;" 4334 + " name: " + pkgSetting.getPackageName() 4335 + "; " + pkgSetting.getVersionCode() + " --> " 4336 + parsedPackage.getLongVersionCode() 4337 + "; " + pkgSetting.getPathString() 4338 + " --> " + parsedPackage.getPath()); 4339 4340 mRemovePackageHelper.cleanUpResources(pkgSetting.getPackageName(), 4341 new File(pkgSetting.getPathString()), 4342 getAppDexInstructionSets(pkgSetting.getPrimaryCpuAbiLegacy(), 4343 pkgSetting.getSecondaryCpuAbiLegacy())); 4344 synchronized (mPm.mLock) { 4345 mPm.mSettings.enableSystemPackageLPw(pkgSetting.getPackageName()); 4346 } 4347 } 4348 4349 // The version of the application on the /system partition is less than or 4350 // equal to the version on the /data partition. Throw an exception and use 4351 // the application already installed on the /data partition. 4352 if (scanSystemPartition && isSystemPkgUpdated && !isSystemPkgBetter) { 4353 // For some updated system packages, during addForInit we want to ensure the 4354 // PackageSetting has the correct SigningDetails compares to the original version on 4355 // the system partition. For the check to happen later during the /data scan, update 4356 // the disabled package setting per the original APK on a system partition so that it 4357 // can be trusted during reconcile. 4358 if (needSignatureMatchToSystem(parsedPackage.getPackageName())) { 4359 final ParseTypeImpl input = ParseTypeImpl.forDefaultParsing(); 4360 final ParseResult<SigningDetails> result = 4361 ParsingPackageUtils.getSigningDetails(input, parsedPackage, 4362 false /*skipVerify*/); 4363 if (result.isError()) { 4364 throw new PrepareFailure("Failed collect during scanPackageForInitLI", 4365 result.getException()); 4366 } 4367 disabledPkgSetting.setSigningDetails(result.getResult()); 4368 } 4369 4370 // In the case of a skipped package, commitReconciledScanResultLocked is not called to 4371 // add the object to the "live" data structures, so this is the final mutation step 4372 // for the package. Which means it needs to be finalized here to cache derived fields. 4373 // This is relevant for cases where the disabled system package is used for flags or 4374 // other metadata. 4375 parsedPackage.hideAsFinal(); 4376 throw PackageManagerException.ofInternalError( 4377 "Package " + parsedPackage.getPackageName() 4378 + " at " + parsedPackage.getPath() + " ignored: updated version " 4379 + (pkgAlreadyExists ? String.valueOf(pkgSetting.getVersionCode()) : "unknown") 4380 + " better than this " + parsedPackage.getLongVersionCode(), 4381 PackageManagerException.INTERNAL_ERROR_UPDATED_VERSION_BETTER_THAN_SYSTEM); 4382 } 4383 4384 // Verify certificates against what was last scanned. Force re-collecting certificate in two 4385 // special cases: 4386 // 1) when scanning system, force re-collect only if system is upgrading. 4387 // 2) when scanning /data, force re-collect only if the package name is allowlisted. 4388 final boolean forceCollect = scanSystemPartition ? isUpgrade 4389 : pkgAlreadyExists && needSignatureMatchToSystem(pkgSetting.getPackageName()); 4390 if (DEBUG_VERIFY && forceCollect) { 4391 Slog.d(TAG, "Force collect certificate of " + parsedPackage.getPackageName()); 4392 } 4393 4394 // APK verification can be skipped during certificate collection, only if the file is in a 4395 // verified partition. 4396 final boolean skipVerify = scanSystemPartition; 4397 ScanPackageUtils.collectCertificatesLI(pkgSetting, parsedPackage, 4398 mPm.getSettingsVersionForPackage(parsedPackage), forceCollect, skipVerify, 4399 mPm.isPreNMR1Upgrade()); 4400 4401 // Reset profile if the application version is changed 4402 maybeClearProfilesForUpgradesLI(pkgSetting, parsedPackage); 4403 4404 /* 4405 * A new system app appeared, but we already had a non-system one of the 4406 * same name installed earlier. 4407 */ 4408 boolean shouldHideSystemApp = false; 4409 // A new application appeared on /system, but, we already have a copy of 4410 // the application installed on /data. 4411 if (scanSystemPartition && !isSystemPkgUpdated && pkgAlreadyExists 4412 && !pkgSetting.isSystem()) { 4413 4414 if (!parsedPackage.getSigningDetails() 4415 .checkCapability(pkgSetting.getSigningDetails(), 4416 SigningDetails.CertCapabilities.INSTALLED_DATA) 4417 && !pkgSetting.getSigningDetails().checkCapability( 4418 parsedPackage.getSigningDetails(), 4419 SigningDetails.CertCapabilities.ROLLBACK)) { 4420 logCriticalInfo(Log.WARN, 4421 "System package signature mismatch;" 4422 + " name: " + pkgSetting.getPackageName()); 4423 try (@SuppressWarnings("unused") PackageFreezer freezer = mPm.freezePackage( 4424 parsedPackage.getPackageName(), UserHandle.USER_ALL, 4425 "scanPackageInternalLI", ApplicationExitInfo.REASON_OTHER, 4426 null /* request */)) { 4427 mDeletePackageHelper.deletePackageLIF( 4428 parsedPackage.getPackageName(), null, true, 4429 mPm.mUserManager.getUserIds(), 0, new PackageRemovedInfo(), false); 4430 } 4431 } else if (newPkgVersionGreater || newSharedUserSetting) { 4432 // The application on /system is newer than the application on /data. 4433 // Simply remove the application on /data [keeping application data] 4434 // and replace it with the version on /system. 4435 // Also, if the sharedUserSetting of the application on /system is different 4436 // from the sharedUserSetting on data, we should trust the sharedUserSetting 4437 // on /system, even if the application version on /system is smaller than 4438 // the version on /data. 4439 logCriticalInfo(Log.WARN, 4440 "System package enabled;" 4441 + " name: " + pkgSetting.getPackageName() 4442 + "; " + pkgSetting.getVersionCode() + " --> " 4443 + parsedPackage.getLongVersionCode() 4444 + "; " + pkgSetting.getPathString() + " --> " 4445 + parsedPackage.getPath()); 4446 mRemovePackageHelper.cleanUpResources(pkgSetting.getPackageName(), 4447 new File(pkgSetting.getPathString()), 4448 getAppDexInstructionSets( 4449 pkgSetting.getPrimaryCpuAbiLegacy(), pkgSetting.getSecondaryCpuAbiLegacy())); 4450 } else { 4451 // The application on /system is older than the application on /data. Hide 4452 // the application on /system and the version on /data will be scanned later 4453 // and re-added like an update. 4454 shouldHideSystemApp = true; 4455 logCriticalInfo(Log.INFO, 4456 "System package disabled;" 4457 + " name: " + pkgSetting.getPackageName() 4458 + "; old: " + pkgSetting.getPathString() + " @ " 4459 + pkgSetting.getVersionCode() 4460 + "; new: " + parsedPackage.getPath() + " @ " 4461 + parsedPackage.getLongVersionCode()); 4462 } 4463 } 4464 4465 // A new application appeared on /system, and we are seeing it for the first time. 4466 // Its also not updated as we don't have a copy of it on /data. So, scan it in a 4467 // STOPPED state. 4468 // We'll skip this step under the following conditions: 4469 // - It's "android" 4470 // - It's an APEX or overlay package since stopped state does not affect them. 4471 // - It is enumerated with a <initial-package-state> tag having the stopped attribute 4472 // set to false 4473 // - It doesn't have an enabled and exported launcher activity, which means the user 4474 // wouldn't have a way to un-stop it 4475 final boolean isApexPkg = (scanFlags & SCAN_AS_APEX) != 0; 4476 if (mPm.mShouldStopSystemPackagesByDefault 4477 && scanSystemPartition 4478 && !pkgAlreadyExists 4479 && !isApexPkg 4480 && !parsedPackage.isOverlayIsStatic() 4481 ) { 4482 String packageName = parsedPackage.getPackageName(); 4483 if (!"android".contentEquals(packageName) 4484 && !mPm.mInitialNonStoppedSystemPackages.contains(packageName) 4485 && hasLauncherEntry(parsedPackage)) { 4486 scanFlags |= SCAN_AS_STOPPED_SYSTEM_APP; 4487 } 4488 } 4489 4490 final long firstInstallTime = Flags.fixSystemAppsFirstInstallTime() 4491 ? System.currentTimeMillis() : 0; 4492 final ScanResult scanResult = scanPackageNew(parsedPackage, parseFlags, 4493 scanFlags | SCAN_UPDATE_SIGNATURE, firstInstallTime, user, null); 4494 return new Pair<>(scanResult, shouldHideSystemApp); 4495 } 4496 hasLauncherEntry(ParsedPackage parsedPackage)4497 private static boolean hasLauncherEntry(ParsedPackage parsedPackage) { 4498 final HashSet<String> categories = new HashSet<>(); 4499 categories.add(Intent.CATEGORY_LAUNCHER); 4500 final List<ParsedActivity> activities = parsedPackage.getActivities(); 4501 for (int indexActivity = 0; indexActivity < activities.size(); indexActivity++) { 4502 final ParsedActivity activity = activities.get(indexActivity); 4503 if (!activity.isEnabled() || !activity.isExported()) { 4504 continue; 4505 } 4506 final List<ParsedIntentInfo> intents = activity.getIntents(); 4507 for (int indexIntent = 0; indexIntent < intents.size(); indexIntent++) { 4508 final IntentFilter intentFilter = intents.get(indexIntent).getIntentFilter(); 4509 if (intentFilter != null && intentFilter.matchCategories(categories) == null) { 4510 return true; 4511 } 4512 } 4513 } 4514 return false; 4515 } 4516 4517 /** 4518 * Returns whether the package needs a signature verification against the pre-installed version 4519 * at boot. 4520 */ needSignatureMatchToSystem(String packageName)4521 private boolean needSignatureMatchToSystem(String packageName) { 4522 return mPm.mInjector.getSystemConfig().getPreinstallPackagesWithStrictSignatureCheck() 4523 .contains(packageName); 4524 } 4525 4526 /** 4527 * Clear the package profile if this was an upgrade and the package 4528 * version was updated. 4529 */ maybeClearProfilesForUpgradesLI( @ullable PackageSetting originalPkgSetting, @NonNull AndroidPackage pkg)4530 private void maybeClearProfilesForUpgradesLI( 4531 @Nullable PackageSetting originalPkgSetting, 4532 @NonNull AndroidPackage pkg) { 4533 if (originalPkgSetting == null || !mPm.isDeviceUpgrading()) { 4534 return; 4535 } 4536 if (originalPkgSetting.getVersionCode() == pkg.getLongVersionCode()) { 4537 return; 4538 } 4539 4540 mAppDataHelper.clearAppProfilesLIF(pkg); 4541 if (DEBUG_INSTALL) { 4542 Slog.d(TAG, originalPkgSetting.getPackageName() 4543 + " clear profile due to version change " 4544 + originalPkgSetting.getVersionCode() + " != " 4545 + pkg.getLongVersionCode()); 4546 } 4547 } 4548 4549 /** 4550 * Returns the original package setting. 4551 * <p>A package can migrate its name during an update. In this scenario, a package 4552 * designates a set of names that it considers as one of its original names. 4553 * <p>An original package must be signed identically and it must have the same 4554 * shared user [if any]. 4555 */ 4556 @GuardedBy("mPm.mLock") 4557 @Nullable getOriginalPackageLocked(@onNull AndroidPackage pkg, @Nullable String renamedPkgName)4558 private PackageSetting getOriginalPackageLocked(@NonNull AndroidPackage pkg, 4559 @Nullable String renamedPkgName) { 4560 if (ScanPackageUtils.isPackageRenamed(pkg, renamedPkgName)) { 4561 return null; 4562 } 4563 for (int i = ArrayUtils.size(pkg.getOriginalPackages()) - 1; i >= 0; --i) { 4564 final PackageSetting originalPs = 4565 mPm.mSettings.getPackageLPr(pkg.getOriginalPackages().get(i)); 4566 if (originalPs != null) { 4567 // the package is already installed under its original name... 4568 // but, should we use it? 4569 if (!verifyPackageUpdateLPr(originalPs, pkg)) { 4570 // the new package is incompatible with the original 4571 continue; 4572 } else if (mPm.mSettings.getSharedUserSettingLPr(originalPs) != null) { 4573 final String sharedUserSettingsName = 4574 mPm.mSettings.getSharedUserSettingLPr(originalPs).name; 4575 if (!sharedUserSettingsName.equals(pkg.getSharedUserId())) { 4576 // the shared user id is incompatible with the original 4577 Slog.w(TAG, "Unable to migrate data from " + originalPs.getPackageName() 4578 + " to " + pkg.getPackageName() + ": old shared user settings name " 4579 + sharedUserSettingsName 4580 + " differs from " + pkg.getSharedUserId()); 4581 continue; 4582 } 4583 // TODO: Add case when shared user id is added [b/28144775] 4584 } else { 4585 if (DEBUG_UPGRADE) { 4586 Log.v(TAG, "Renaming new package " 4587 + pkg.getPackageName() + " to old name " 4588 + originalPs.getPackageName()); 4589 } 4590 } 4591 return originalPs; 4592 } 4593 } 4594 return null; 4595 } 4596 4597 @GuardedBy("mPm.mLock") verifyPackageUpdateLPr(PackageSetting oldPkg, AndroidPackage newPkg)4598 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, AndroidPackage newPkg) { 4599 if ((oldPkg.getFlags() & ApplicationInfo.FLAG_SYSTEM) == 0) { 4600 Slog.w(TAG, "Unable to update from " + oldPkg.getPackageName() 4601 + " to " + newPkg.getPackageName() 4602 + ": old package not in system partition"); 4603 return false; 4604 } else if (mPm.mPackages.get(oldPkg.getPackageName()) != null) { 4605 Slog.w(TAG, "Unable to update from " + oldPkg.getPackageName() 4606 + " to " + newPkg.getPackageName() 4607 + ": old package still exists"); 4608 return false; 4609 } 4610 return true; 4611 } 4612 4613 /** 4614 * Asserts the parsed package is valid according to the given policy. If the 4615 * package is invalid, for whatever reason, throws {@link PackageManagerException}. 4616 * <p> 4617 * Implementation detail: This method must NOT have any side effects. It would 4618 * ideally be static, but, it requires locks to read system state. 4619 * 4620 * @throws PackageManagerException If the package fails any of the validation checks 4621 */ assertPackageIsValid(AndroidPackage pkg, final @ParsingPackageUtils.ParseFlags int parseFlags, final @PackageManagerService.ScanFlags int scanFlags)4622 private void assertPackageIsValid(AndroidPackage pkg, 4623 final @ParsingPackageUtils.ParseFlags int parseFlags, 4624 final @PackageManagerService.ScanFlags int scanFlags) 4625 throws PackageManagerException { 4626 if ((parseFlags & ParsingPackageUtils.PARSE_ENFORCE_CODE) != 0) { 4627 ScanPackageUtils.assertCodePolicy(pkg); 4628 } 4629 4630 if (pkg.getPath() == null) { 4631 // Bail out. The resource and code paths haven't been set. 4632 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 4633 "Code and resource paths haven't been set correctly"); 4634 } 4635 4636 // Check that there is an APEX package with the same name only during install/first boot 4637 // after OTA. 4638 final boolean isUserInstall = (scanFlags & SCAN_BOOTING) == 0; 4639 final boolean isFirstBootOrUpgrade = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0; 4640 // It is allowed to install a new APEX with the same name. But there shouldn't be 4641 // conflicting names between APK and APEX. 4642 final boolean installApex = (scanFlags & SCAN_AS_APEX) != 0; 4643 if ((isUserInstall || isFirstBootOrUpgrade) 4644 && mPm.snapshotComputer().isApexPackage(pkg.getPackageName()) 4645 && !installApex) { 4646 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 4647 pkg.getPackageName() 4648 + " is an APEX package and can't be installed as an APK."); 4649 } 4650 4651 // Make sure we're not adding any bogus keyset info 4652 final KeySetManagerService ksms = mPm.mSettings.getKeySetManagerService(); 4653 ksms.assertScannedPackageValid(pkg); 4654 4655 synchronized (mPm.mLock) { 4656 // The special "android" package can only be defined once 4657 if (pkg.getPackageName().equals("android")) { 4658 if (mPm.getCoreAndroidApplication() != null) { 4659 Slog.w(TAG, "*************************************************"); 4660 Slog.w(TAG, "Core android package being redefined. Skipping."); 4661 Slog.w(TAG, " codePath=" + pkg.getPath()); 4662 Slog.w(TAG, "*************************************************"); 4663 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 4664 "Core android package being redefined. Skipping."); 4665 } 4666 } 4667 4668 // A package name must be unique; don't allow duplicates 4669 if ((scanFlags & SCAN_NEW_INSTALL) == 0 4670 && mPm.mPackages.containsKey(pkg.getPackageName())) { 4671 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 4672 "Application package " + pkg.getPackageName() 4673 + " already installed. Skipping duplicate."); 4674 } 4675 4676 if (pkg.isStaticSharedLibrary()) { 4677 // Static libs have a synthetic package name containing the version 4678 // but we still want the base name to be unique. 4679 if ((scanFlags & SCAN_NEW_INSTALL) == 0 4680 && mPm.mPackages.containsKey(pkg.getManifestPackageName())) { 4681 throw PackageManagerException.ofInternalError( 4682 "Duplicate static shared lib provider package", 4683 PackageManagerException.INTERNAL_ERROR_DUP_STATIC_SHARED_LIB_PROVIDER); 4684 } 4685 ScanPackageUtils.assertStaticSharedLibraryIsValid(pkg, scanFlags); 4686 assertStaticSharedLibraryVersionCodeIsValid(pkg); 4687 } 4688 4689 // If we're only installing presumed-existing packages, require that the 4690 // scanned APK is both already known and at the path previously established 4691 // for it. Previously unknown packages we pick up normally, but if we have an 4692 // a priori expectation about this package's install presence, enforce it. 4693 // With a singular exception for new system packages. When an OTA contains 4694 // a new system package, we allow the codepath to change from a system location 4695 // to the user-installed location. If we don't allow this change, any newer, 4696 // user-installed version of the application will be ignored. 4697 if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) { 4698 if (mPm.isExpectingBetter(pkg.getPackageName())) { 4699 Slog.w(TAG, "Relax SCAN_REQUIRE_KNOWN requirement for package " 4700 + pkg.getPackageName()); 4701 } else { 4702 PackageSetting known = mPm.mSettings.getPackageLPr(pkg.getPackageName()); 4703 if (known != null) { 4704 if (DEBUG_PACKAGE_SCANNING) { 4705 Log.d(TAG, "Examining " + pkg.getPath() 4706 + " and requiring known path " + known.getPathString()); 4707 } 4708 if (!pkg.getPath().equals(known.getPathString())) { 4709 throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED, 4710 "Application package " + pkg.getPackageName() 4711 + " found at " + pkg.getPath() 4712 + " but expected at " + known.getPathString() 4713 + "; ignoring."); 4714 } 4715 } else { 4716 throw new PackageManagerException(INSTALL_FAILED_INVALID_INSTALL_LOCATION, 4717 "Application package " + pkg.getPackageName() 4718 + " not found; ignoring."); 4719 } 4720 } 4721 } 4722 4723 // Verify that this new package doesn't have any content providers 4724 // that conflict with existing packages. Only do this if the 4725 // package isn't already installed, since we don't want to break 4726 // things that are installed. 4727 if ((scanFlags & SCAN_NEW_INSTALL) != 0) { 4728 mPm.mComponentResolver.assertProvidersNotDefined(pkg); 4729 } 4730 4731 // If this package has defined explicit processes, then ensure that these are 4732 // the only processes used by its components. 4733 ScanPackageUtils.assertProcessesAreValid(pkg); 4734 4735 // Verify that packages sharing a user with a privileged app are marked as privileged. 4736 assertPackageWithSharedUserIdIsPrivileged(pkg); 4737 4738 // Apply policies specific for runtime resource overlays (RROs). 4739 if (pkg.getOverlayTarget() != null) { 4740 assertOverlayIsValid(pkg, parseFlags, scanFlags); 4741 } 4742 4743 // Ensure the package is signed with at least the minimum signature scheme version 4744 // required for its target SDK. 4745 ScanPackageUtils.assertMinSignatureSchemeIsValid(pkg, parseFlags); 4746 } 4747 } 4748 assertStaticSharedLibraryVersionCodeIsValid(AndroidPackage pkg)4749 private void assertStaticSharedLibraryVersionCodeIsValid(AndroidPackage pkg) 4750 throws PackageManagerException { 4751 // The version codes must be ordered as lib versions 4752 long minVersionCode = Long.MIN_VALUE; 4753 long maxVersionCode = Long.MAX_VALUE; 4754 4755 WatchedLongSparseArray<SharedLibraryInfo> versionedLib = 4756 mSharedLibraries.getSharedLibraryInfos(pkg.getStaticSharedLibraryName()); 4757 if (versionedLib != null) { 4758 final int versionCount = versionedLib.size(); 4759 for (int i = 0; i < versionCount; i++) { 4760 SharedLibraryInfo libInfo = versionedLib.valueAt(i); 4761 final long libVersionCode = libInfo.getDeclaringPackage() 4762 .getLongVersionCode(); 4763 if (libInfo.getLongVersion() < pkg.getStaticSharedLibraryVersion()) { 4764 minVersionCode = Math.max(minVersionCode, libVersionCode + 1); 4765 } else if (libInfo.getLongVersion() 4766 > pkg.getStaticSharedLibraryVersion()) { 4767 maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1); 4768 } else { 4769 minVersionCode = maxVersionCode = libVersionCode; 4770 break; 4771 } 4772 } 4773 } 4774 if (pkg.getLongVersionCode() < minVersionCode 4775 || pkg.getLongVersionCode() > maxVersionCode) { 4776 throw PackageManagerException.ofInternalError("Static shared" 4777 + " lib version codes must be ordered as lib versions", 4778 PackageManagerException.INTERNAL_ERROR_STATIC_SHARED_LIB_VERSION_CODES_ORDER); 4779 } 4780 } 4781 assertOverlayIsValid(AndroidPackage pkg, @ParsingPackageUtils.ParseFlags int parseFlags, @PackageManagerService.ScanFlags int scanFlags)4782 private void assertOverlayIsValid(AndroidPackage pkg, 4783 @ParsingPackageUtils.ParseFlags int parseFlags, 4784 @PackageManagerService.ScanFlags int scanFlags) throws PackageManagerException { 4785 // System overlays have some restrictions on their use of the 'static' state. 4786 if ((scanFlags & SCAN_AS_SYSTEM) != 0) { 4787 // We are scanning a system overlay. This can be the first scan of the 4788 // system/vendor/oem partition, or an update to the system overlay. 4789 if ((parseFlags & ParsingPackageUtils.PARSE_IS_SYSTEM_DIR) == 0) { 4790 // This must be an update to a system overlay. Immutable overlays cannot be 4791 // upgraded. 4792 if (!mPm.isOverlayMutable(pkg.getPackageName())) { 4793 throw PackageManagerException.ofInternalError("Overlay " 4794 + pkg.getPackageName() 4795 + " is static and cannot be upgraded.", 4796 PackageManagerException.INTERNAL_ERROR_SYSTEM_OVERLAY_STATIC); 4797 } 4798 } else { 4799 if ((scanFlags & (SCAN_AS_VENDOR | SCAN_AS_ODM)) != 0) { 4800 if (pkg.getTargetSdkVersion() < ScanPackageUtils.getVendorPartitionVersion()) { 4801 Slog.w(TAG, "System overlay " + pkg.getPackageName() 4802 + " targets an SDK below the required SDK level of vendor" 4803 + " overlays (" 4804 + ScanPackageUtils.getVendorPartitionVersion() 4805 + ")." 4806 + " This will become an install error in a future release"); 4807 } 4808 } else if (pkg.getTargetSdkVersion() < Build.VERSION.SDK_INT) { 4809 Slog.w(TAG, "System overlay " + pkg.getPackageName() 4810 + " targets an SDK below the required SDK level of system" 4811 + " overlays (" + Build.VERSION.SDK_INT + ")." 4812 + " This will become an install error in a future release"); 4813 } 4814 } 4815 } else { 4816 // A non-preloaded overlay packages must have targetSdkVersion >= Q, or be 4817 // signed with the platform certificate. Check this in increasing order of 4818 // computational cost. 4819 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.Q) { 4820 final PackageSetting platformPkgSetting; 4821 synchronized (mPm.mLock) { 4822 platformPkgSetting = mPm.mSettings.getPackageLPr("android"); 4823 } 4824 if (!comparePackageSignatures(platformPkgSetting, pkg.getSigningDetails())) { 4825 throw PackageManagerException.ofInternalError("Overlay " 4826 + pkg.getPackageName() 4827 + " must target Q or later, " 4828 + "or be signed with the platform certificate", 4829 PackageManagerException.INTERNAL_ERROR_OVERLAY_LOW_TARGET_SDK); 4830 } 4831 } 4832 4833 // A non-preloaded overlay package, without <overlay android:targetName>, will 4834 // only be used if it is signed with the same certificate as its target OR if 4835 // it is signed with the same certificate as a reference package declared 4836 // in 'overlay-config-signature' tag of SystemConfig. 4837 // If the target is already installed or 'overlay-config-signature' tag in 4838 // SystemConfig is set, check this here to augment the last line of defense 4839 // which is OMS. 4840 if (pkg.getOverlayTargetOverlayableName() == null) { 4841 final PackageSetting targetPkgSetting; 4842 synchronized (mPm.mLock) { 4843 targetPkgSetting = mPm.mSettings.getPackageLPr(pkg.getOverlayTarget()); 4844 } 4845 if (targetPkgSetting != null) { 4846 if (!comparePackageSignatures(targetPkgSetting, pkg.getSigningDetails())) { 4847 // check reference signature 4848 if (mPm.mOverlayConfigSignaturePackage == null) { 4849 throw PackageManagerException.ofInternalError("Overlay " 4850 + pkg.getPackageName() + " and target " 4851 + pkg.getOverlayTarget() + " signed with" 4852 + " different certificates, and the overlay lacks" 4853 + " <overlay android:targetName>", 4854 PackageManagerException.INTERNAL_ERROR_OVERLAY_SIGNATURE1); 4855 } 4856 final PackageSetting refPkgSetting; 4857 synchronized (mPm.mLock) { 4858 refPkgSetting = mPm.mSettings.getPackageLPr( 4859 mPm.mOverlayConfigSignaturePackage); 4860 } 4861 if (!comparePackageSignatures(refPkgSetting, pkg.getSigningDetails())) { 4862 throw PackageManagerException.ofInternalError("Overlay " 4863 + pkg.getPackageName() + " signed with a different " 4864 + "certificate than both the reference package and " 4865 + "target " + pkg.getOverlayTarget() + ", and the " 4866 + "overlay lacks <overlay android:targetName>", 4867 PackageManagerException.INTERNAL_ERROR_OVERLAY_SIGNATURE2); 4868 } 4869 } 4870 } 4871 } 4872 } 4873 } 4874 assertPackageWithSharedUserIdIsPrivileged(AndroidPackage pkg)4875 private void assertPackageWithSharedUserIdIsPrivileged(AndroidPackage pkg) 4876 throws PackageManagerException { 4877 if (!AndroidPackageLegacyUtils.isPrivileged(pkg) 4878 && (pkg.getSharedUserId() != null) 4879 && !pkg.isLeavingSharedUser()) { 4880 SharedUserSetting sharedUserSetting = null; 4881 try { 4882 synchronized (mPm.mLock) { 4883 sharedUserSetting = mPm.mSettings.getSharedUserLPw(pkg.getSharedUserId(), 4884 0, 0, false); 4885 } 4886 } catch (PackageManagerException ignore) { 4887 } 4888 if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) { 4889 // Exempt SharedUsers signed with the platform key. 4890 final PackageSetting platformPkgSetting; 4891 synchronized (mPm.mLock) { 4892 platformPkgSetting = mPm.mSettings.getPackageLPr("android"); 4893 } 4894 if (!comparePackageSignatures(platformPkgSetting, pkg.getSigningDetails())) { 4895 throw PackageManagerException.ofInternalError("Apps that share a user with a " 4896 + "privileged app must themselves be marked as privileged. " 4897 + pkg.getPackageName() + " shares privileged user " 4898 + pkg.getSharedUserId() + ".", 4899 PackageManagerException.INTERNAL_ERROR_NOT_PRIV_SHARED_USER); 4900 } 4901 } 4902 } 4903 } 4904 adjustScanFlags( @ackageManagerService.ScanFlags int scanFlags, @Nullable PackageSetting existingPkgSetting, @Nullable PackageSetting disabledPkgSetting, UserHandle user, @NonNull AndroidPackage pkg)4905 private @PackageManagerService.ScanFlags int adjustScanFlags( 4906 @PackageManagerService.ScanFlags int scanFlags, 4907 @Nullable PackageSetting existingPkgSetting, 4908 @Nullable PackageSetting disabledPkgSetting, UserHandle user, 4909 @NonNull AndroidPackage pkg) { 4910 scanFlags = ScanPackageUtils.adjustScanFlagsWithPackageSetting(scanFlags, existingPkgSetting, 4911 disabledPkgSetting, user); 4912 4913 // Exception for privileged apps that share a user with a priv-app. 4914 final boolean skipVendorPrivilegeScan = ((scanFlags & SCAN_AS_VENDOR) != 0) 4915 && ScanPackageUtils.getVendorPartitionVersion() < 28; 4916 if (((scanFlags & SCAN_AS_PRIVILEGED) == 0) 4917 && !AndroidPackageLegacyUtils.isPrivileged(pkg) 4918 && (pkg.getSharedUserId() != null) 4919 && !skipVendorPrivilegeScan 4920 && !pkg.isLeavingSharedUser()) { 4921 SharedUserSetting sharedUserSetting = null; 4922 synchronized (mPm.mLock) { 4923 try { 4924 sharedUserSetting = mPm.mSettings.getSharedUserLPw(pkg.getSharedUserId(), 0, 4925 0, false); 4926 } catch (PackageManagerException ignore) { 4927 } 4928 if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) { 4929 // Exempt SharedUsers signed with the platform key. 4930 // TODO(b/72378145) Fix this exemption. Force signature apps 4931 // to allowlist their privileged permissions just like other 4932 // priv-apps. 4933 PackageSetting platformPkgSetting = mPm.mSettings.getPackageLPr("android"); 4934 if ((compareSignatures(platformPkgSetting.getSigningDetails(), 4935 pkg.getSigningDetails()) != PackageManager.SIGNATURE_MATCH)) { 4936 scanFlags |= SCAN_AS_PRIVILEGED; 4937 } 4938 } 4939 } 4940 } 4941 4942 return scanFlags; 4943 } 4944 } 4945