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.Intent.EXTRA_LONG_VERSION_CODE;
20 import static android.content.Intent.EXTRA_PACKAGE_NAME;
21 import static android.content.Intent.EXTRA_VERSION_CODE;
22 import static android.content.pm.PackageInstaller.SessionParams.MODE_INHERIT_EXISTING;
23 import static android.content.pm.PackageManager.EXTRA_VERIFICATION_ID;
24 import static android.content.pm.PackageManager.INSTALL_SUCCEEDED;
25 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
26 import static android.content.pm.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V4;
27 import static android.os.PowerWhitelistManager.REASON_PACKAGE_VERIFIER;
28 import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
29 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
30 
31 import static com.android.server.pm.PackageManagerService.CHECK_PENDING_INTEGRITY_VERIFICATION;
32 import static com.android.server.pm.PackageManagerService.CHECK_PENDING_VERIFICATION;
33 import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
34 import static com.android.server.pm.PackageManagerService.DEBUG_VERIFY;
35 import static com.android.server.pm.PackageManagerService.DEFAULT_VERIFICATION_RESPONSE;
36 import static com.android.server.pm.PackageManagerService.ENABLE_ROLLBACK_TIMEOUT;
37 import static com.android.server.pm.PackageManagerService.PACKAGE_MIME_TYPE;
38 import static com.android.server.pm.PackageManagerService.TAG;
39 
40 import android.annotation.NonNull;
41 import android.annotation.Nullable;
42 import android.app.AppOpsManager;
43 import android.app.BroadcastOptions;
44 import android.content.BroadcastReceiver;
45 import android.content.ComponentName;
46 import android.content.Context;
47 import android.content.Intent;
48 import android.content.pm.ActivityInfo;
49 import android.content.pm.DataLoaderType;
50 import android.content.pm.Flags;
51 import android.content.pm.IPackageInstallObserver2;
52 import android.content.pm.PackageInfoLite;
53 import android.content.pm.PackageInstaller;
54 import android.content.pm.PackageManager;
55 import android.content.pm.PackageManagerInternal;
56 import android.content.pm.ParceledListSlice;
57 import android.content.pm.ResolveInfo;
58 import android.content.pm.SigningDetails;
59 import android.content.pm.VerifierInfo;
60 import android.content.pm.parsing.PackageLite;
61 import android.net.Uri;
62 import android.os.Bundle;
63 import android.os.Message;
64 import android.os.Process;
65 import android.os.RemoteException;
66 import android.os.SystemProperties;
67 import android.os.Trace;
68 import android.os.UserHandle;
69 import android.os.UserManager;
70 import android.os.incremental.IncrementalManager;
71 import android.provider.DeviceConfig;
72 import android.provider.Settings;
73 import android.text.TextUtils;
74 import android.util.Pair;
75 import android.util.Slog;
76 
77 import com.android.server.DeviceIdleInternal;
78 import com.android.server.sdksandbox.SdkSandboxManagerLocal;
79 
80 import java.io.File;
81 import java.util.ArrayList;
82 import java.util.Arrays;
83 import java.util.List;
84 
85 final class VerifyingSession {
86     /**
87      * Whether verification is enabled by default.
88      */
89     private static final boolean DEFAULT_VERIFY_ENABLE = true;
90 
91     /**
92      * Whether integrity verification is enabled by default.
93      */
94     private static final boolean DEFAULT_INTEGRITY_VERIFY_ENABLE = true;
95     /**
96      * The default maximum time to wait for the integrity verification to return in
97      * milliseconds.
98      */
99     private static final long DEFAULT_INTEGRITY_VERIFICATION_TIMEOUT = 30 * 1000;
100     /**
101      * Timeout duration in milliseconds for enabling package rollback. If we fail to enable
102      * rollback within that period, the install will proceed without rollback enabled.
103      *
104      * <p>If flag value is negative, the default value will be assigned.
105      *
106      * Flag type: {@code long}
107      * Namespace: NAMESPACE_ROLLBACK
108      */
109     private static final String PROPERTY_ENABLE_ROLLBACK_TIMEOUT_MILLIS = "enable_rollback_timeout";
110     /**
111      * The default duration to wait for rollback to be enabled in
112      * milliseconds.
113      */
114     private static final long DEFAULT_ENABLE_ROLLBACK_TIMEOUT_MILLIS = 10 * 1000;
115 
116     final OriginInfo mOriginInfo;
117     final IPackageInstallObserver2 mObserver;
118     private final int mInstallFlags;
119     @NonNull
120     private final InstallSource mInstallSource;
121     private final String mPackageAbiOverride;
122     private final VerificationInfo mVerificationInfo;
123     private final SigningDetails mSigningDetails;
124     @Nullable
125     MultiPackageVerifyingSession mParentVerifyingSession;
126     private final long mRequiredInstalledVersionCode;
127     private final int mDataLoaderType;
128     private final int mSessionId;
129     private final boolean mUserActionRequired;
130     private final int mUserActionRequiredType;
131     private boolean mWaitForVerificationToComplete;
132     private boolean mWaitForIntegrityVerificationToComplete;
133     private boolean mWaitForEnableRollbackToComplete;
134     private int mRet = PackageManager.INSTALL_SUCCEEDED;
135     private String mErrorMessage = null;
136     private final boolean mIsInherit;
137     private final boolean mIsStaged;
138 
139     private final PackageLite mPackageLite;
140     private final UserHandle mUser;
141     @NonNull
142     private final PackageManagerService mPm;
143 
144     private final int mInstallReason;
145 
VerifyingSession(UserHandle user, File stagedDir, IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams, InstallSource installSource, int installerUid, SigningDetails signingDetails, int sessionId, PackageLite lite, boolean userActionRequired, PackageManagerService pm)146     VerifyingSession(UserHandle user, File stagedDir, IPackageInstallObserver2 observer,
147             PackageInstaller.SessionParams sessionParams, InstallSource installSource,
148             int installerUid, SigningDetails signingDetails, int sessionId, PackageLite lite,
149             boolean userActionRequired, PackageManagerService pm) {
150         mPm = pm;
151         mUser = user;
152         mOriginInfo = OriginInfo.fromStagedFile(stagedDir);
153         mObserver = observer;
154         mInstallFlags = sessionParams.installFlags;
155         mInstallSource = installSource;
156         mPackageAbiOverride = sessionParams.abiOverride;
157         mVerificationInfo = new VerificationInfo(
158                 sessionParams.originatingUri,
159                 sessionParams.referrerUri,
160                 sessionParams.originatingUid,
161                 installerUid
162         );
163         mSigningDetails = signingDetails;
164         mRequiredInstalledVersionCode = sessionParams.requiredInstalledVersionCode;
165         mDataLoaderType = (sessionParams.dataLoaderParams != null)
166                 ? sessionParams.dataLoaderParams.getType() : DataLoaderType.NONE;
167         mSessionId = sessionId;
168         mPackageLite = lite;
169         mUserActionRequired = userActionRequired;
170         mUserActionRequiredType = sessionParams.requireUserAction;
171         mIsInherit = sessionParams.mode == MODE_INHERIT_EXISTING;
172         mIsStaged = sessionParams.isStaged;
173         mInstallReason = sessionParams.installReason;
174     }
175 
176     @Override
toString()177     public String toString() {
178         return "VerifyingSession{" + Integer.toHexString(System.identityHashCode(this))
179                 + " file=" + mOriginInfo.mFile + "}";
180     }
181 
handleStartVerify()182     public void handleStartVerify() {
183         PackageInfoLite pkgLite = PackageManagerServiceUtils.getMinimalPackageInfo(mPm.mContext,
184                 mPackageLite, mOriginInfo.mResolvedPath, mInstallFlags, mPackageAbiOverride);
185 
186         Pair<Integer, String> ret = mPm.verifyReplacingVersionCode(
187                 pkgLite, mRequiredInstalledVersionCode, mInstallFlags);
188         setReturnCode(ret.first, ret.second);
189         if (mRet != INSTALL_SUCCEEDED) {
190             return;
191         }
192 
193         // Perform package verification and enable rollback (unless we are simply moving the
194         // package).
195         if (!mOriginInfo.mExisting) {
196             final boolean verifyForRollback = Flags.recoverabilityDetection()
197                     ? !isARollback() : true;
198             if (!isApex() && !isArchivedInstallation() && verifyForRollback) {
199                 // TODO(b/182426975): treat APEX as APK when APK verification is concerned
200                 sendApkVerificationRequest(pkgLite);
201             }
202             if ((mInstallFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) {
203                 sendEnableRollbackRequest();
204             }
205         }
206     }
207 
isARollback()208     private boolean isARollback() {
209         return mInstallReason == PackageManager.INSTALL_REASON_ROLLBACK
210                 && mInstallSource.mInitiatingPackageName.equals("android");
211     }
212 
sendApkVerificationRequest(PackageInfoLite pkgLite)213     private void sendApkVerificationRequest(PackageInfoLite pkgLite) {
214         final int verificationId = mPm.mPendingVerificationToken++;
215 
216         PackageVerificationState verificationState =
217                 new PackageVerificationState(this);
218         mPm.mPendingVerification.append(verificationId, verificationState);
219 
220         sendIntegrityVerificationRequest(verificationId, pkgLite, verificationState);
221         sendPackageVerificationRequest(
222                 verificationId, pkgLite, verificationState);
223 
224         // If both verifications are skipped, we should remove the state.
225         if (verificationState.areAllVerificationsComplete()) {
226             mPm.mPendingVerification.remove(verificationId);
227         }
228     }
229 
sendEnableRollbackRequest()230     void sendEnableRollbackRequest() {
231         final int enableRollbackToken = mPm.mPendingEnableRollbackToken++;
232         Trace.asyncTraceBegin(
233                 TRACE_TAG_PACKAGE_MANAGER, "enable_rollback", enableRollbackToken);
234         mPm.mPendingEnableRollback.append(enableRollbackToken, this);
235 
236         Intent enableRollbackIntent = new Intent(Intent.ACTION_PACKAGE_ENABLE_ROLLBACK);
237         enableRollbackIntent.putExtra(
238                 PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_TOKEN,
239                 enableRollbackToken);
240         enableRollbackIntent.putExtra(
241                 PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_SESSION_ID,
242                 mSessionId);
243         enableRollbackIntent.setType(PACKAGE_MIME_TYPE);
244         enableRollbackIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
245                 | Intent.FLAG_RECEIVER_FOREGROUND);
246 
247         // Allow the broadcast to be sent before boot complete.
248         // This is needed when committing the apk part of a staged
249         // session in early boot. The rollback manager registers
250         // its receiver early enough during the boot process that
251         // it will not miss the broadcast.
252         enableRollbackIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
253 
254         mPm.mContext.sendBroadcastAsUser(enableRollbackIntent, UserHandle.SYSTEM,
255                 android.Manifest.permission.PACKAGE_ROLLBACK_AGENT);
256 
257         mWaitForEnableRollbackToComplete = true;
258 
259         // the duration to wait for rollback to be enabled, in millis
260         long rollbackTimeout = DeviceConfig.getLong(
261                 DeviceConfig.NAMESPACE_ROLLBACK,
262                 PROPERTY_ENABLE_ROLLBACK_TIMEOUT_MILLIS,
263                 DEFAULT_ENABLE_ROLLBACK_TIMEOUT_MILLIS);
264         if (rollbackTimeout < 0) {
265             rollbackTimeout = DEFAULT_ENABLE_ROLLBACK_TIMEOUT_MILLIS;
266         }
267         final Message msg = mPm.mHandler.obtainMessage(ENABLE_ROLLBACK_TIMEOUT);
268         msg.arg1 = enableRollbackToken;
269         msg.arg2 = mSessionId;
270         mPm.mHandler.sendMessageDelayed(msg, rollbackTimeout);
271     }
272 
273     /**
274      * Send a request to check the integrity of the package.
275      */
sendIntegrityVerificationRequest( int verificationId, PackageInfoLite pkgLite, PackageVerificationState verificationState)276     void sendIntegrityVerificationRequest(
277             int verificationId,
278             PackageInfoLite pkgLite,
279             PackageVerificationState verificationState) {
280         if (!isIntegrityVerificationEnabled()) {
281             // Consider the integrity check as passed.
282             verificationState.setIntegrityVerificationResult(
283                     PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW);
284             return;
285         }
286 
287         final Intent integrityVerification =
288                 new Intent(Intent.ACTION_PACKAGE_NEEDS_INTEGRITY_VERIFICATION);
289 
290         integrityVerification.setDataAndType(Uri.fromFile(new File(mOriginInfo.mResolvedPath)),
291                 PACKAGE_MIME_TYPE);
292 
293         final int flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
294                 | Intent.FLAG_RECEIVER_REGISTERED_ONLY
295                 | Intent.FLAG_RECEIVER_FOREGROUND;
296         integrityVerification.addFlags(flags);
297 
298         integrityVerification.putExtra(EXTRA_VERIFICATION_ID, verificationId);
299         integrityVerification.putExtra(EXTRA_PACKAGE_NAME, pkgLite.packageName);
300         integrityVerification.putExtra(EXTRA_VERSION_CODE, pkgLite.versionCode);
301         integrityVerification.putExtra(EXTRA_LONG_VERSION_CODE, pkgLite.getLongVersionCode());
302         populateInstallerExtras(integrityVerification);
303 
304         // send to integrity component only.
305         integrityVerification.setPackage("android");
306 
307         final BroadcastOptions options = BroadcastOptions.makeBasic();
308 
309         mPm.mContext.sendOrderedBroadcastAsUser(integrityVerification, UserHandle.SYSTEM,
310                 /* receiverPermission= */ null,
311                 /* appOp= */ AppOpsManager.OP_NONE,
312                 /* options= */ options.toBundle(),
313                 new BroadcastReceiver() {
314                     @Override
315                     public void onReceive(Context context, Intent intent) {
316                         final Message msg =
317                                 mPm.mHandler.obtainMessage(CHECK_PENDING_INTEGRITY_VERIFICATION);
318                         msg.arg1 = verificationId;
319                         mPm.mHandler.sendMessageDelayed(msg, getIntegrityVerificationTimeout());
320                     }
321                 }, /* scheduler= */ null,
322                 /* initialCode= */ 0,
323                 /* initialData= */ null,
324                 /* initialExtras= */ null);
325 
326         Trace.asyncTraceBegin(
327                 TRACE_TAG_PACKAGE_MANAGER, "integrity_verification", verificationId);
328 
329         // stop the copy until verification succeeds.
330         mWaitForIntegrityVerificationToComplete = true;
331     }
332 
333 
334     /**
335      * Get the integrity verification timeout.
336      *
337      * @return verification timeout in milliseconds
338      */
getIntegrityVerificationTimeout()339     private long getIntegrityVerificationTimeout() {
340         long timeout = Settings.Global.getLong(mPm.mContext.getContentResolver(),
341                 Settings.Global.APP_INTEGRITY_VERIFICATION_TIMEOUT,
342                 DEFAULT_INTEGRITY_VERIFICATION_TIMEOUT);
343         // The setting can be used to increase the timeout but not decrease it, since that is
344         // equivalent to disabling the integrity component.
345         return Math.max(timeout, DEFAULT_INTEGRITY_VERIFICATION_TIMEOUT);
346     }
347 
348     /**
349      * Check whether or not integrity verification has been enabled.
350      */
isIntegrityVerificationEnabled()351     private boolean isIntegrityVerificationEnabled() {
352         // We are not exposing this as a user-configurable setting because we don't want to provide
353         // an easy way to get around the integrity check.
354         return DEFAULT_INTEGRITY_VERIFY_ENABLE;
355     }
356 
357     /**
358      * Send a request to verifier(s) to verify the package if necessary.
359      */
sendPackageVerificationRequest( int verificationId, PackageInfoLite pkgLite, PackageVerificationState verificationState)360     private void sendPackageVerificationRequest(
361             int verificationId,
362             PackageInfoLite pkgLite,
363             PackageVerificationState verificationState) {
364 
365         // Apps installed for "all" users use the current user to verify the app
366         UserHandle verifierUser = getUser();
367         if (verifierUser == UserHandle.ALL) {
368             verifierUser = UserHandle.of(mPm.mUserManager.getCurrentUserId());
369         }
370         // TODO(b/300965895): Remove when inconsistencies loading classpaths from apex for
371         // user > 1 are fixed. Tests should cover verifiers from apex classpaths run on
372         // primary user, secondary user and work profile.
373         if (pkgLite.isSdkLibrary) {
374             verifierUser = UserHandle.SYSTEM;
375         }
376         final int verifierUserId = verifierUser.getIdentifier();
377 
378         List<String> requiredVerifierPackages = new ArrayList<>(
379                 Arrays.asList(mPm.mRequiredVerifierPackages));
380         boolean requiredVerifierPackagesOverridden = false;
381 
382         // Allow verifier override for ADB installations which could already be unverified using
383         // PackageManager.INSTALL_DISABLE_VERIFICATION flag.
384         if ((mInstallFlags & PackageManager.INSTALL_FROM_ADB) != 0
385                 && (mInstallFlags & PackageManager.INSTALL_DISABLE_VERIFICATION) == 0) {
386             String property = SystemProperties.get("debug.pm.adb_verifier_override_packages", "");
387             if (!TextUtils.isEmpty(property)) {
388                 String[] verifierPackages = property.split(";");
389                 List<String> adbVerifierOverridePackages = new ArrayList<>();
390                 for (String verifierPackage : verifierPackages) {
391                     if (!TextUtils.isEmpty(verifierPackage) && packageExists(verifierPackage)) {
392                         adbVerifierOverridePackages.add(verifierPackage);
393                     }
394                 }
395                 // Check if the package installed.
396                 if (adbVerifierOverridePackages.size() > 0) {
397                     // Pretend we requested to disable verification from command line.
398                     boolean requestedDisableVerification = true;
399                     // If this returns false then the caller can already skip verification, so we
400                     // are not adding a new way to disable verifications.
401                     if (!isAdbVerificationEnabled(pkgLite, verifierUserId,
402                             requestedDisableVerification)) {
403                         requiredVerifierPackages = adbVerifierOverridePackages;
404                         requiredVerifierPackagesOverridden = true;
405                     }
406                 }
407             }
408         }
409 
410         if (mOriginInfo.mExisting || !isVerificationEnabled(pkgLite, verifierUserId,
411                 requiredVerifierPackages)) {
412             verificationState.passRequiredVerification();
413             return;
414         }
415 
416         /*
417          * Determine if we have any installed package verifiers. If we
418          * do, then we'll defer to them to verify the packages.
419          */
420         final Computer snapshot = mPm.snapshotComputer();
421 
422         final int numRequiredVerifierPackages = requiredVerifierPackages.size();
423         for (int i = numRequiredVerifierPackages - 1; i >= 0; i--) {
424             if (!snapshot.isApplicationEffectivelyEnabled(requiredVerifierPackages.get(i),
425                     verifierUser)) {
426                 Slog.w(TAG,
427                         "Required verifier: " + requiredVerifierPackages.get(i) + " is disabled");
428                 requiredVerifierPackages.remove(i);
429             }
430         }
431 
432         for (String requiredVerifierPackage : requiredVerifierPackages) {
433             final int requiredUid = snapshot.getPackageUid(requiredVerifierPackage,
434                     MATCH_DEBUG_TRIAGED_MISSING, verifierUserId);
435             verificationState.addRequiredVerifierUid(requiredUid);
436         }
437 
438         final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
439         verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
440         verification.setDataAndType(Uri.fromFile(new File(mOriginInfo.mResolvedPath)),
441                 PACKAGE_MIME_TYPE);
442         verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
443 
444         // Query all live verifiers based on current user state
445         final ParceledListSlice<ResolveInfo> receivers = mPm.queryIntentReceivers(snapshot,
446                 verification, PACKAGE_MIME_TYPE, 0, verifierUserId);
447 
448         if (DEBUG_VERIFY) {
449             Slog.d(TAG, "Found " + receivers.getList().size() + " verifiers for intent "
450                     + verification.toString() + " with " + pkgLite.verifiers.length
451                     + " optional verifiers");
452         }
453 
454         verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
455 
456         verification.putExtra(
457                 PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, mInstallFlags);
458 
459         verification.putExtra(
460                 PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, pkgLite.packageName);
461 
462         verification.putExtra(
463                 PackageManager.EXTRA_VERIFICATION_VERSION_CODE, pkgLite.versionCode);
464 
465         verification.putExtra(
466                 PackageManager.EXTRA_VERIFICATION_LONG_VERSION_CODE,
467                 pkgLite.getLongVersionCode());
468 
469         final String baseCodePath = mPackageLite.getBaseApkPath();
470         final String[] splitCodePaths = mPackageLite.getSplitApkPaths();
471 
472         final String rootHashString;
473         if (IncrementalManager.isIncrementalPath(baseCodePath)) {
474             rootHashString = PackageManagerServiceUtils.buildVerificationRootHashString(
475                     baseCodePath, splitCodePaths);
476             verification.putExtra(PackageManager.EXTRA_VERIFICATION_ROOT_HASH, rootHashString);
477         } else {
478             rootHashString = null;
479         }
480 
481         verification.putExtra(PackageInstaller.EXTRA_DATA_LOADER_TYPE, mDataLoaderType);
482 
483         verification.putExtra(PackageInstaller.EXTRA_SESSION_ID, mSessionId);
484 
485         verification.putExtra(PackageManager.EXTRA_USER_ACTION_REQUIRED, mUserActionRequired);
486 
487         populateInstallerExtras(verification);
488 
489         // Streaming installation timeout schema is enabled only for:
490         // 1. Incremental installs with v4,
491         // 2. If device/policy allow unverified app installs by default.
492         final boolean streaming = (mDataLoaderType == DataLoaderType.INCREMENTAL)
493                 && (mSigningDetails.getSignatureSchemeVersion() == SIGNING_BLOCK_V4)
494                 && (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW);
495 
496         final long verificationTimeout = VerificationUtils.getVerificationTimeout(mPm.mContext,
497                 streaming);
498 
499         List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
500                 receivers.getList(), verificationState);
501 
502         // Add broadcastReceiver Component to verify Sdk before run in Sdk sandbox.
503         if (pkgLite.isSdkLibrary) {
504             if (sufficientVerifiers == null) {
505                 sufficientVerifiers = new ArrayList<>();
506             }
507             ComponentName sdkSandboxComponentName = new ComponentName("android",
508                     SdkSandboxManagerLocal.VERIFIER_RECEIVER);
509             sufficientVerifiers.add(sdkSandboxComponentName);
510 
511             // Add uid of system_server the same uid for SdkSandboxManagerService
512             verificationState.addSufficientVerifier(Process.myUid());
513         }
514 
515         DeviceIdleInternal idleController =
516                 mPm.mInjector.getLocalService(DeviceIdleInternal.class);
517         final BroadcastOptions options = BroadcastOptions.makeBasic();
518         options.setTemporaryAppAllowlist(verificationTimeout,
519                 TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
520                 REASON_PACKAGE_VERIFIER, "");
521 
522         /*
523          * If any sufficient verifiers were listed in the package
524          * manifest, attempt to ask them.
525          */
526         if (sufficientVerifiers != null) {
527             final int n = sufficientVerifiers.size();
528             if (n == 0) {
529                 String errorMsg = "Additional verifiers required, but none installed.";
530                 Slog.i(TAG, errorMsg);
531                 setReturnCode(PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE, errorMsg);
532             } else {
533                 for (int i = 0; i < n; i++) {
534                     final ComponentName verifierComponent = sufficientVerifiers.get(i);
535                     idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
536                             verifierComponent.getPackageName(), verificationTimeout,
537                             verifierUserId, false,
538                             REASON_PACKAGE_VERIFIER, "package verifier");
539 
540                     final Intent sufficientIntent = new Intent(verification);
541                     sufficientIntent.setComponent(verifierComponent);
542                     mPm.mContext.sendBroadcastAsUser(sufficientIntent, verifierUser,
543                             /* receiverPermission= */ null,
544                             options.toBundle());
545                 }
546             }
547         }
548 
549         if (requiredVerifierPackages.size() == 0) {
550             Slog.e(TAG, "No required verifiers");
551             return;
552         }
553 
554         final int verificationCodeAtTimeout;
555         // Allows package verification to continue in the event the app being updated is verifying
556         // itself and fails to respond
557         if (Flags.emergencyInstallPermission() && requiredVerifierPackages.contains(
558                 pkgLite.packageName)) {
559             verificationCodeAtTimeout = PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT;
560         } else if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) {
561             verificationCodeAtTimeout = PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT;
562         } else {
563             verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
564         }
565 
566         for (String requiredVerifierPackage : requiredVerifierPackages) {
567             final int requiredUid = snapshot.getPackageUid(requiredVerifierPackage,
568                     MATCH_DEBUG_TRIAGED_MISSING, verifierUserId);
569 
570             final Intent requiredIntent;
571             final String receiverPermission;
572             if (!requiredVerifierPackagesOverridden || requiredVerifierPackages.size() == 1) {
573                 // Prod code OR test code+single verifier.
574                 requiredIntent = new Intent(verification);
575                 if (!requiredVerifierPackagesOverridden) {
576                     ComponentName requiredVerifierComponent = matchComponentForVerifier(
577                             requiredVerifierPackage, receivers.getList());
578                     requiredIntent.setComponent(requiredVerifierComponent);
579                 } else {
580                     requiredIntent.setPackage(requiredVerifierPackage);
581                 }
582                 receiverPermission = android.Manifest.permission.PACKAGE_VERIFICATION_AGENT;
583             } else {
584                 // Test code+multiple verifiers.
585                 // Recreate the intent to contain test-only information.
586                 requiredIntent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
587                 requiredIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
588                 requiredIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
589                 requiredIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
590                 requiredIntent.setDataAndType(Uri.fromFile(new File(mOriginInfo.mResolvedPath)),
591                         PACKAGE_MIME_TYPE);
592                 requiredIntent.putExtra(PackageInstaller.EXTRA_SESSION_ID, mSessionId);
593                 requiredIntent.putExtra(PackageInstaller.EXTRA_DATA_LOADER_TYPE, mDataLoaderType);
594                 if (rootHashString != null) {
595                     requiredIntent.putExtra(PackageManager.EXTRA_VERIFICATION_ROOT_HASH,
596                             rootHashString);
597                 }
598                 requiredIntent.setPackage(requiredVerifierPackage);
599                 // Negative verification id.
600                 requiredIntent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, -verificationId);
601                 // OK not to have permission.
602                 receiverPermission = null;
603             }
604 
605             idleController.addPowerSaveTempWhitelistApp(Process.myUid(), requiredVerifierPackage,
606                     verificationTimeout, verifierUserId, false, REASON_PACKAGE_VERIFIER,
607                     "package verifier");
608 
609             final PackageVerificationResponse response = new PackageVerificationResponse(
610                     verificationCodeAtTimeout, requiredUid);
611 
612             startVerificationTimeoutCountdown(verificationId, streaming, response,
613                     verificationTimeout);
614 
615             // Send the intent to the required verification agent, but only start the
616             // verification timeout after the target BroadcastReceivers have run.
617             mPm.mContext.sendOrderedBroadcastAsUser(requiredIntent, verifierUser,
618                     receiverPermission, AppOpsManager.OP_NONE, options.toBundle(),
619                     null, null, 0, null, null);
620         }
621 
622         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
623 
624         /*
625          * We don't want the copy to proceed until verification
626          * succeeds.
627          */
628         mWaitForVerificationToComplete = true;
629     }
630 
startVerificationTimeoutCountdown(int verificationId, boolean streaming, PackageVerificationResponse response, long verificationTimeout)631     private void startVerificationTimeoutCountdown(int verificationId, boolean streaming,
632             PackageVerificationResponse response, long verificationTimeout) {
633         final Message msg = mPm.mHandler.obtainMessage(CHECK_PENDING_VERIFICATION);
634         msg.arg1 = verificationId;
635         msg.arg2 = streaming ? 1 : 0;
636         msg.obj = response;
637         mPm.mHandler.sendMessageDelayed(msg, verificationTimeout);
638     }
639 
640     /**
641      * Get the default verification agent response code.
642      *
643      * @return default verification response code
644      */
getDefaultVerificationResponse()645     int getDefaultVerificationResponse() {
646         if (mPm.mUserManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS,
647                 getUser().getIdentifier())) {
648             return PackageManager.VERIFICATION_REJECT;
649         }
650         return android.provider.Settings.Global.getInt(mPm.mContext.getContentResolver(),
651                 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
652                 DEFAULT_VERIFICATION_RESPONSE);
653     }
654 
packageExists(String packageName)655     private boolean packageExists(String packageName) {
656         Computer snapshot = mPm.snapshotComputer();
657         return snapshot.getPackageStateInternal(packageName) != null;
658     }
659 
isAdbVerificationEnabled(PackageInfoLite pkgInfoLite, int userId, boolean requestedDisableVerification)660     private boolean isAdbVerificationEnabled(PackageInfoLite pkgInfoLite, int userId,
661             boolean requestedDisableVerification) {
662         boolean verifierIncludeAdb = android.provider.Settings.Global.getInt(
663                 mPm.mContext.getContentResolver(),
664                 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) != 0;
665 
666         if (mPm.isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS)) {
667             if (!verifierIncludeAdb) {
668                 Slog.w(TAG, "Force verification of ADB install because of user restriction.");
669             }
670             return true;
671         }
672 
673         // Check if the verification disabled globally, first.
674         if (!verifierIncludeAdb) {
675             return false;
676         }
677 
678         // Check if the developer wants to skip verification for ADB installs.
679         if (requestedDisableVerification) {
680             if (!packageExists(pkgInfoLite.packageName)) {
681                 // Always verify fresh install.
682                 return true;
683             }
684             // Only skip when apk is debuggable.
685             return !pkgInfoLite.debuggable;
686         }
687 
688         return true;
689     }
690 
691     /**
692      * Check whether package verification has been enabled.
693      *
694      * @return true if verification should be performed
695      */
isVerificationEnabled(PackageInfoLite pkgInfoLite, int userId, List<String> requiredVerifierPackages)696     private boolean isVerificationEnabled(PackageInfoLite pkgInfoLite, int userId,
697             List<String> requiredVerifierPackages) {
698         if (!DEFAULT_VERIFY_ENABLE) {
699             return false;
700         }
701 
702         final int installerUid = mVerificationInfo == null ? -1 : mVerificationInfo.mInstallerUid;
703         final boolean requestedDisableVerification =
704                 (mInstallFlags & PackageManager.INSTALL_DISABLE_VERIFICATION) != 0;
705 
706         // Check if installing from ADB
707         if ((mInstallFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
708             return isAdbVerificationEnabled(pkgInfoLite, userId, requestedDisableVerification);
709         } else if (requestedDisableVerification) {
710             // Skip verification for non-adb installs
711             return false;
712         }
713 
714         // only when not installed from ADB, skip verification for instant apps when
715         // the installer and verifier are the same.
716         if (isInstant() && mPm.mInstantAppInstallerActivity != null) {
717             String installerPackage = mPm.mInstantAppInstallerActivity.packageName;
718             for (String requiredVerifierPackage : requiredVerifierPackages) {
719                 if (installerPackage.equals(requiredVerifierPackage)) {
720                     try {
721                         mPm.mInjector.getSystemService(AppOpsManager.class)
722                                 .checkPackage(installerUid, requiredVerifierPackage);
723                         if (DEBUG_VERIFY) {
724                             Slog.i(TAG, "disable verification for instant app");
725                         }
726                         return false;
727                     } catch (SecurityException ignore) {
728                     }
729                 }
730             }
731         }
732         return true;
733     }
734 
matchVerifiers(PackageInfoLite pkgInfo, List<ResolveInfo> receivers, final PackageVerificationState verificationState)735     private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
736             List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
737         if (pkgInfo.verifiers == null || pkgInfo.verifiers.length == 0) {
738             return null;
739         }
740 
741         final int n = pkgInfo.verifiers.length;
742         final List<ComponentName> sufficientVerifiers = new ArrayList<>(n + 1);
743         for (int i = 0; i < n; i++) {
744             final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
745 
746             final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
747                     receivers);
748             if (comp == null) {
749                 continue;
750             }
751 
752             final int verifierUid = mPm.getUidForVerifier(verifierInfo);
753             if (verifierUid == -1) {
754                 continue;
755             }
756 
757             if (DEBUG_VERIFY) {
758                 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
759                         + " with the correct signature");
760             }
761             sufficientVerifiers.add(comp);
762             verificationState.addSufficientVerifier(verifierUid);
763         }
764 
765         return sufficientVerifiers;
766     }
767 
matchComponentForVerifier(String packageName, List<ResolveInfo> receivers)768     private static ComponentName matchComponentForVerifier(String packageName,
769             List<ResolveInfo> receivers) {
770         ActivityInfo targetReceiver = null;
771 
772         final int nr = receivers.size();
773         for (int i = 0; i < nr; i++) {
774             final ResolveInfo info = receivers.get(i);
775             if (info.activityInfo == null) {
776                 continue;
777             }
778 
779             if (packageName.equals(info.activityInfo.packageName)) {
780                 targetReceiver = info.activityInfo;
781                 break;
782             }
783         }
784 
785         if (targetReceiver == null) {
786             return null;
787         }
788 
789         return new ComponentName(targetReceiver.packageName, targetReceiver.name);
790     }
791 
populateInstallerExtras(Intent intent)792     void populateInstallerExtras(Intent intent) {
793         intent.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
794                 mInstallSource.mInitiatingPackageName);
795 
796         if (mVerificationInfo != null) {
797             if (mVerificationInfo.mOriginatingUri != null) {
798                 intent.putExtra(Intent.EXTRA_ORIGINATING_URI,
799                         mVerificationInfo.mOriginatingUri);
800             }
801             if (mVerificationInfo.mReferrer != null) {
802                 intent.putExtra(Intent.EXTRA_REFERRER,
803                         mVerificationInfo.mReferrer);
804             }
805             if (mVerificationInfo.mOriginatingUid >= 0) {
806                 intent.putExtra(Intent.EXTRA_ORIGINATING_UID,
807                         mVerificationInfo.mOriginatingUid);
808             }
809             if (mVerificationInfo.mInstallerUid >= 0) {
810                 intent.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
811                         mVerificationInfo.mInstallerUid);
812             }
813         }
814     }
815 
setReturnCode(int ret, String message)816     void setReturnCode(int ret, String message) {
817         if (mRet == PackageManager.INSTALL_SUCCEEDED) {
818             // Only update mRet if it was previously INSTALL_SUCCEEDED to
819             // ensure we do not overwrite any previous failure results.
820             mRet = ret;
821             mErrorMessage = message;
822         }
823     }
824 
handleVerificationFinished()825     void handleVerificationFinished() {
826         mWaitForVerificationToComplete = false;
827         handleReturnCode();
828     }
829 
handleIntegrityVerificationFinished()830     void handleIntegrityVerificationFinished() {
831         mWaitForIntegrityVerificationToComplete = false;
832         handleReturnCode();
833     }
834 
handleRollbackEnabled()835     void handleRollbackEnabled() {
836         // TODO(b/112431924): Consider halting the install if we
837         // couldn't enable rollback.
838         mWaitForEnableRollbackToComplete = false;
839         handleReturnCode();
840     }
841 
handleReturnCode()842     void handleReturnCode() {
843         if (mWaitForVerificationToComplete || mWaitForIntegrityVerificationToComplete
844                 || mWaitForEnableRollbackToComplete) {
845             return;
846         }
847         sendVerificationCompleteNotification();
848         if (mRet != INSTALL_SUCCEEDED) {
849             PackageMetrics.onVerificationFailed(this);
850         }
851     }
852 
sendVerificationCompleteNotification()853     private void sendVerificationCompleteNotification() {
854         if (mParentVerifyingSession != null) {
855             mParentVerifyingSession.trySendVerificationCompleteNotification(this);
856         } else {
857             try {
858                 mObserver.onPackageInstalled(null, mRet, mErrorMessage,
859                         new Bundle());
860             } catch (RemoteException e) {
861                 Slog.i(TAG, "Observer no longer exists.");
862             }
863         }
864     }
865 
start()866     private void start() {
867         if (DEBUG_INSTALL) Slog.i(TAG, "start " + mUser + ": " + this);
868         Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueVerify",
869                 System.identityHashCode(this));
870         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "start");
871         handleStartVerify();
872         handleReturnCode();
873         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
874     }
875 
verifyStage()876     public void verifyStage() {
877         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueVerify",
878                 System.identityHashCode(this));
879         mPm.mHandler.post(this::start);
880     }
881 
verifyStage(List<VerifyingSession> children)882     public void verifyStage(List<VerifyingSession> children)
883             throws PackageManagerException {
884         final MultiPackageVerifyingSession multiPackageVerifyingSession =
885                 new MultiPackageVerifyingSession(this, children);
886         mPm.mHandler.post(multiPackageVerifyingSession::start);
887     }
888 
getRet()889     public int getRet() {
890         return mRet;
891     }
getErrorMessage()892     public String getErrorMessage() {
893         return mErrorMessage;
894     }
getUser()895     public UserHandle getUser() {
896         return mUser;
897     }
getSessionId()898     public int getSessionId() {
899         return mSessionId;
900     }
getDataLoaderType()901     public int getDataLoaderType() {
902         return mDataLoaderType;
903     }
getUserActionRequiredType()904     public int getUserActionRequiredType() {
905         return mUserActionRequiredType;
906     }
isInstant()907     public boolean isInstant() {
908         return (mInstallFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
909     }
isInherit()910     public boolean isInherit() {
911         return mIsInherit;
912     }
getInstallerPackageUid()913     public int getInstallerPackageUid() {
914         return mInstallSource.mInstallerPackageUid;
915     }
isApex()916     public boolean isApex() {
917         return (mInstallFlags & PackageManager.INSTALL_APEX) != 0;
918     }
isArchivedInstallation()919     public boolean isArchivedInstallation() {
920         return (mInstallFlags & PackageManager.INSTALL_ARCHIVED) != 0;
921     }
isStaged()922     public boolean isStaged() {
923         return mIsStaged;
924     }
925 }
926