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