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.server.pm.PackageManagerService.CHECK_PENDING_INTEGRITY_VERIFICATION; 22 import static com.android.server.pm.PackageManagerService.CHECK_PENDING_VERIFICATION; 23 import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL; 24 import static com.android.server.pm.PackageManagerService.DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD; 25 import static com.android.server.pm.PackageManagerService.DEFERRED_NO_KILL_INSTALL_OBSERVER; 26 import static com.android.server.pm.PackageManagerService.DEFERRED_NO_KILL_POST_DELETE; 27 import static com.android.server.pm.PackageManagerService.DEFERRED_PENDING_KILL_INSTALL_OBSERVER; 28 import static com.android.server.pm.PackageManagerService.DOMAIN_VERIFICATION; 29 import static com.android.server.pm.PackageManagerService.ENABLE_ROLLBACK_STATUS; 30 import static com.android.server.pm.PackageManagerService.ENABLE_ROLLBACK_TIMEOUT; 31 import static com.android.server.pm.PackageManagerService.INSTANT_APP_RESOLUTION_PHASE_TWO; 32 import static com.android.server.pm.PackageManagerService.INTEGRITY_VERIFICATION_COMPLETE; 33 import static com.android.server.pm.PackageManagerService.PACKAGE_VERIFIED; 34 import static com.android.server.pm.PackageManagerService.POST_INSTALL; 35 import static com.android.server.pm.PackageManagerService.PRUNE_UNUSED_STATIC_SHARED_LIBRARIES; 36 import static com.android.server.pm.PackageManagerService.SEND_PENDING_BROADCAST; 37 import static com.android.server.pm.PackageManagerService.TAG; 38 import static com.android.server.pm.PackageManagerService.WRITE_PACKAGE_LIST; 39 import static com.android.server.pm.PackageManagerService.WRITE_SETTINGS; 40 41 import android.content.Intent; 42 import android.content.pm.InstantAppRequest; 43 import android.content.pm.PackageManager; 44 import android.content.pm.PackageManagerInternal; 45 import android.net.Uri; 46 import android.os.Handler; 47 import android.os.Looper; 48 import android.os.Message; 49 import android.os.Process; 50 import android.os.Trace; 51 import android.os.UserHandle; 52 import android.provider.Settings; 53 import android.util.Log; 54 import android.util.Slog; 55 56 import java.io.IOException; 57 58 /** 59 * Part of PackageManagerService that handles events. 60 */ 61 final class PackageHandler extends Handler { 62 private final PackageManagerService mPm; 63 PackageHandler(Looper looper, PackageManagerService pm)64 PackageHandler(Looper looper, PackageManagerService pm) { 65 super(looper); 66 mPm = pm; 67 } 68 69 @Override handleMessage(Message msg)70 public void handleMessage(Message msg) { 71 try { 72 doHandleMessage(msg); 73 } finally { 74 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 75 } 76 } 77 doHandleMessage(Message msg)78 void doHandleMessage(Message msg) { 79 switch (msg.what) { 80 case SEND_PENDING_BROADCAST: { 81 mPm.sendPendingBroadcasts(); 82 break; 83 } 84 case POST_INSTALL: { 85 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1); 86 87 InstallRequest request = mPm.mRunningInstalls.get(msg.arg1); 88 final boolean didRestore = (msg.arg2 != 0); 89 mPm.mRunningInstalls.delete(msg.arg1); 90 91 if (request == null) { 92 if (DEBUG_INSTALL) { 93 Slog.i(TAG, "InstallRequest is null. Nothing to do for post-install " 94 + "token " + msg.arg1); 95 } 96 break; 97 } 98 request.closeFreezer(); 99 request.onInstallCompleted(); 100 request.runPostInstallRunnable(); 101 if (!request.isInstallExistingForUser()) { 102 mPm.handlePackagePostInstall(request, didRestore); 103 } else if (DEBUG_INSTALL) { 104 // No post-install when we run restore from installExistingPackageForUser 105 Slog.i(TAG, "Nothing to do for post-install token " + msg.arg1); 106 } 107 108 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1); 109 } break; 110 case DEFERRED_NO_KILL_POST_DELETE: { 111 CleanUpArgs args = (CleanUpArgs) msg.obj; 112 if (args != null) { 113 mPm.cleanUpResources(args.getPackageName(), args.getCodeFile(), 114 args.getInstructionSets()); 115 } 116 } break; 117 case DEFERRED_NO_KILL_INSTALL_OBSERVER: 118 case DEFERRED_PENDING_KILL_INSTALL_OBSERVER: { 119 final String packageName = (String) msg.obj; 120 if (packageName != null) { 121 final boolean killApp = msg.what == DEFERRED_PENDING_KILL_INSTALL_OBSERVER; 122 mPm.notifyInstallObserver(packageName, killApp); 123 } 124 } break; 125 case WRITE_SETTINGS: { 126 mPm.writeSettings(/*sync=*/false); 127 } break; 128 case WRITE_PACKAGE_LIST: { 129 mPm.writePackageList(msg.arg1); 130 } break; 131 case CHECK_PENDING_VERIFICATION: { 132 final int verificationId = msg.arg1; 133 final boolean streaming = msg.arg2 != 0; 134 final PackageVerificationState state = mPm.mPendingVerification.get(verificationId); 135 136 if (state == null || state.isVerificationComplete()) { 137 // Not found or complete. 138 break; 139 } 140 141 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj; 142 if (!streaming && state.timeoutExtended(response.callerUid)) { 143 // Timeout extended. 144 break; 145 } 146 147 VerificationUtils.processVerificationResponseOnTimeout(verificationId, state, 148 response, mPm); 149 150 break; 151 } 152 case CHECK_PENDING_INTEGRITY_VERIFICATION: { 153 final int verificationId = msg.arg1; 154 final PackageVerificationState state = mPm.mPendingVerification.get(verificationId); 155 156 if (state != null && !state.isIntegrityVerificationComplete()) { 157 final VerifyingSession verifyingSession = state.getVerifyingSession(); 158 final Uri originUri = Uri.fromFile(verifyingSession.mOriginInfo.mResolvedFile); 159 160 String errorMsg = "Integrity verification timed out for " + originUri; 161 Slog.i(TAG, errorMsg); 162 163 state.setIntegrityVerificationResult( 164 getDefaultIntegrityVerificationResponse()); 165 166 if (getDefaultIntegrityVerificationResponse() 167 == PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW) { 168 Slog.i(TAG, "Integrity check times out, continuing with " + originUri); 169 } else { 170 verifyingSession.setReturnCode( 171 PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE, 172 errorMsg); 173 } 174 175 if (state.areAllVerificationsComplete()) { 176 mPm.mPendingVerification.remove(verificationId); 177 } 178 179 Trace.asyncTraceEnd( 180 TRACE_TAG_PACKAGE_MANAGER, 181 "integrity_verification", 182 verificationId); 183 184 verifyingSession.handleIntegrityVerificationFinished(); 185 } 186 break; 187 } 188 case PACKAGE_VERIFIED: { 189 final int verificationId = msg.arg1; 190 191 final PackageVerificationState state = mPm.mPendingVerification.get(verificationId); 192 if (state == null) { 193 Slog.w(TAG, "Verification with id " + verificationId 194 + " not found." 195 + " It may be invalid or overridden by integrity verification"); 196 break; 197 } 198 if (state.isVerificationComplete()) { 199 Slog.w(TAG, "Verification with id " + verificationId + " already complete."); 200 break; 201 } 202 203 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj; 204 VerificationUtils.processVerificationResponse(verificationId, state, response, mPm); 205 206 break; 207 } 208 case INTEGRITY_VERIFICATION_COMPLETE: { 209 final int verificationId = msg.arg1; 210 211 final PackageVerificationState state = mPm.mPendingVerification.get(verificationId); 212 if (state == null) { 213 Slog.w(TAG, "Integrity verification with id " + verificationId 214 + " not found. It may be invalid or overridden by verifier"); 215 break; 216 } 217 218 final int response = (Integer) msg.obj; 219 final VerifyingSession verifyingSession = state.getVerifyingSession(); 220 final Uri originUri = Uri.fromFile(verifyingSession.mOriginInfo.mResolvedFile); 221 222 state.setIntegrityVerificationResult(response); 223 224 if (response == PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW) { 225 Slog.i(TAG, "Integrity check passed for " + originUri); 226 } else { 227 verifyingSession.setReturnCode( 228 PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE, 229 "Integrity check failed for " + originUri); 230 } 231 232 if (state.areAllVerificationsComplete()) { 233 mPm.mPendingVerification.remove(verificationId); 234 } 235 236 Trace.asyncTraceEnd( 237 TRACE_TAG_PACKAGE_MANAGER, 238 "integrity_verification", 239 verificationId); 240 241 verifyingSession.handleIntegrityVerificationFinished(); 242 break; 243 } 244 case INSTANT_APP_RESOLUTION_PHASE_TWO: { 245 InstantAppResolver.doInstantAppResolutionPhaseTwo(mPm.mContext, 246 mPm.snapshotComputer(), 247 mPm.mUserManager, 248 mPm.mInstantAppResolverConnection, 249 (InstantAppRequest) msg.obj, 250 mPm.mInstantAppInstallerActivity, 251 mPm.mHandler); 252 break; 253 } 254 case ENABLE_ROLLBACK_STATUS: { 255 final int enableRollbackToken = msg.arg1; 256 final int enableRollbackCode = msg.arg2; 257 final VerifyingSession params = 258 mPm.mPendingEnableRollback.get(enableRollbackToken); 259 if (params == null) { 260 Slog.w(TAG, "Invalid rollback enabled token " 261 + enableRollbackToken + " received"); 262 break; 263 } 264 265 mPm.mPendingEnableRollback.remove(enableRollbackToken); 266 267 if (enableRollbackCode != PackageManagerInternal.ENABLE_ROLLBACK_SUCCEEDED) { 268 final Uri originUri = Uri.fromFile(params.mOriginInfo.mResolvedFile); 269 Slog.w(TAG, "Failed to enable rollback for " + originUri); 270 Slog.w(TAG, "Continuing with installation of " + originUri); 271 } 272 273 Trace.asyncTraceEnd( 274 TRACE_TAG_PACKAGE_MANAGER, "enable_rollback", enableRollbackToken); 275 276 params.handleRollbackEnabled(); 277 break; 278 } 279 case ENABLE_ROLLBACK_TIMEOUT: { 280 final int enableRollbackToken = msg.arg1; 281 final int sessionId = msg.arg2; 282 final VerifyingSession params = 283 mPm.mPendingEnableRollback.get(enableRollbackToken); 284 if (params != null) { 285 final Uri originUri = Uri.fromFile(params.mOriginInfo.mResolvedFile); 286 287 Slog.w(TAG, "Enable rollback timed out for " + originUri); 288 mPm.mPendingEnableRollback.remove(enableRollbackToken); 289 290 Slog.w(TAG, "Continuing with installation of " + originUri); 291 Trace.asyncTraceEnd( 292 TRACE_TAG_PACKAGE_MANAGER, "enable_rollback", enableRollbackToken); 293 params.handleRollbackEnabled(); 294 Intent rollbackTimeoutIntent = new Intent( 295 Intent.ACTION_CANCEL_ENABLE_ROLLBACK); 296 rollbackTimeoutIntent.putExtra( 297 PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_SESSION_ID, 298 sessionId); 299 rollbackTimeoutIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT 300 | Intent.FLAG_RECEIVER_FOREGROUND); 301 mPm.mContext.sendBroadcastAsUser(rollbackTimeoutIntent, UserHandle.SYSTEM, 302 android.Manifest.permission.PACKAGE_ROLLBACK_AGENT); 303 } 304 break; 305 } 306 case DOMAIN_VERIFICATION: { 307 int messageCode = msg.arg1; 308 Object object = msg.obj; 309 mPm.mDomainVerificationManager.runMessage(messageCode, object); 310 break; 311 } 312 case PRUNE_UNUSED_STATIC_SHARED_LIBRARIES: { 313 try { 314 mPm.mInjector.getSharedLibrariesImpl().pruneUnusedStaticSharedLibraries( 315 mPm.snapshotComputer(), 316 Long.MAX_VALUE, 317 Settings.Global.getLong(mPm.mContext.getContentResolver(), 318 Settings.Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD, 319 DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD)); 320 } catch (IOException e) { 321 Log.w(TAG, "Failed to prune unused static shared libraries :" 322 + e.getMessage()); 323 } 324 break; 325 } 326 } 327 } 328 329 /** 330 * Get the default integrity verification response code. 331 */ getDefaultIntegrityVerificationResponse()332 private int getDefaultIntegrityVerificationResponse() { 333 // We are not exposing this as a user-configurable setting because we don't want to provide 334 // an easy way to get around the integrity check. 335 return PackageManager.VERIFICATION_REJECT; 336 } 337 } 338