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.os.Trace.TRACE_TAG_PACKAGE_MANAGER; 20 21 import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE; 22 import static com.android.server.pm.PackageManagerService.PACKAGE_MIME_TYPE; 23 import static com.android.server.pm.PackageManagerService.TAG; 24 25 import android.annotation.Nullable; 26 import android.content.Context; 27 import android.content.Intent; 28 import android.content.pm.PackageInstaller; 29 import android.content.pm.PackageManager; 30 import android.net.Uri; 31 import android.os.Trace; 32 import android.os.UserHandle; 33 import android.provider.Settings; 34 import android.util.Slog; 35 36 import com.android.internal.annotations.VisibleForTesting; 37 38 final class VerificationUtils { 39 /** 40 * The default maximum time to wait for the verification agent to return in 41 * milliseconds. 42 */ 43 private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000; 44 45 /** 46 * The default maximum time to wait for the verification agent to return in 47 * milliseconds. 48 */ 49 private static final long DEFAULT_STREAMING_VERIFICATION_TIMEOUT = 3 * 1000; 50 getVerificationTimeout(Context context, boolean streaming)51 public static long getVerificationTimeout(Context context, boolean streaming) { 52 if (streaming) { 53 return getDefaultStreamingVerificationTimeout(context); 54 } 55 return getDefaultVerificationTimeout(context); 56 } 57 58 /** 59 * Get the default verification agent timeout. Used for both the APK verifier and the 60 * intent filter verifier. 61 * 62 * @return verification timeout in milliseconds 63 */ getDefaultVerificationTimeout(Context context)64 public static long getDefaultVerificationTimeout(Context context) { 65 long timeout = Settings.Global.getLong(context.getContentResolver(), 66 Settings.Global.PACKAGE_VERIFIER_TIMEOUT, DEFAULT_VERIFICATION_TIMEOUT); 67 // The setting can be used to increase the timeout but not decrease it, since that is 68 // equivalent to disabling the verifier. 69 return Math.max(timeout, DEFAULT_VERIFICATION_TIMEOUT); 70 } 71 72 /** 73 * Get the default verification agent timeout for streaming installations. 74 * 75 * @return verification timeout in milliseconds 76 */ getDefaultStreamingVerificationTimeout(Context context)77 public static long getDefaultStreamingVerificationTimeout(Context context) { 78 long timeout = Settings.Global.getLong(context.getContentResolver(), 79 Settings.Global.PACKAGE_STREAMING_VERIFIER_TIMEOUT, 80 DEFAULT_STREAMING_VERIFICATION_TIMEOUT); 81 // The setting can be used to increase the timeout but not decrease it, since that is 82 // equivalent to disabling the verifier. 83 return Math.max(timeout, DEFAULT_STREAMING_VERIFICATION_TIMEOUT); 84 } 85 broadcastPackageVerified(int verificationId, Uri packageUri, int verificationCode, @Nullable String rootHashString, int dataLoaderType, UserHandle user, Context context)86 public static void broadcastPackageVerified(int verificationId, Uri packageUri, 87 int verificationCode, @Nullable String rootHashString, int dataLoaderType, 88 UserHandle user, Context context) { 89 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED); 90 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE); 91 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 92 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 93 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode); 94 if (rootHashString != null) { 95 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ROOT_HASH, rootHashString); 96 } 97 intent.putExtra(PackageInstaller.EXTRA_DATA_LOADER_TYPE, dataLoaderType); 98 99 context.sendBroadcastAsUser(intent, user, 100 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT); 101 } 102 103 @VisibleForTesting(visibility = PACKAGE) processVerificationResponseOnTimeout(int verificationId, PackageVerificationState state, PackageVerificationResponse response, PackageManagerService pms)104 static void processVerificationResponseOnTimeout(int verificationId, 105 PackageVerificationState state, PackageVerificationResponse response, 106 PackageManagerService pms) { 107 state.setVerifierResponseOnTimeout(response.callerUid, response.code); 108 processVerificationResponse(verificationId, state, response.code, "Verification timed out", 109 pms); 110 } 111 112 @VisibleForTesting(visibility = PACKAGE) processVerificationResponse(int verificationId, PackageVerificationState state, PackageVerificationResponse response, PackageManagerService pms)113 static void processVerificationResponse(int verificationId, PackageVerificationState state, 114 PackageVerificationResponse response, PackageManagerService pms) { 115 state.setVerifierResponse(response.callerUid, response.code); 116 processVerificationResponse(verificationId, state, response.code, "Install not allowed", 117 pms); 118 } 119 processVerificationResponse(int verificationId, PackageVerificationState state, int verificationResult, String failureReason, PackageManagerService pms)120 private static void processVerificationResponse(int verificationId, 121 PackageVerificationState state, int verificationResult, String failureReason, 122 PackageManagerService pms) { 123 if (!state.isVerificationComplete()) { 124 return; 125 } 126 127 final VerifyingSession verifyingSession = state.getVerifyingSession(); 128 final Uri originUri = verifyingSession != null ? Uri.fromFile( 129 verifyingSession.mOriginInfo.mResolvedFile) : null; 130 131 final int verificationCode = 132 state.isInstallAllowed() ? verificationResult : PackageManager.VERIFICATION_REJECT; 133 134 if (pms != null && verifyingSession != null) { 135 VerificationUtils.broadcastPackageVerified(verificationId, originUri, 136 verificationCode, null, 137 verifyingSession.getDataLoaderType(), verifyingSession.getUser(), 138 pms.mContext); 139 } 140 141 if (state.isInstallAllowed()) { 142 Slog.i(TAG, "Continuing with installation of " + originUri); 143 } else { 144 String errorMsg = failureReason + " for " + originUri; 145 Slog.i(TAG, errorMsg); 146 if (verifyingSession != null) { 147 verifyingSession.setReturnCode( 148 PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE, errorMsg); 149 } 150 } 151 152 if (pms != null && state.areAllVerificationsComplete()) { 153 pms.mPendingVerification.remove(verificationId); 154 } 155 156 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 157 158 if (verifyingSession != null) { 159 verifyingSession.handleVerificationFinished(); 160 } 161 } 162 } 163