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