1 /* 2 * Copyright (C) 2022 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.wm; 18 19 import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND; 20 import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; 21 import static android.app.ActivityOptions.BackgroundActivityStartMode; 22 import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED; 23 import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_COMPAT; 24 import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED; 25 import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED; 26 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; 27 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 28 import static android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE; 29 import static android.os.Process.INVALID_PID; 30 import static android.os.Process.INVALID_UID; 31 import static android.os.Process.ROOT_UID; 32 import static android.os.Process.SYSTEM_UID; 33 import static android.provider.DeviceConfig.NAMESPACE_WINDOW_MANAGER; 34 import static android.security.Flags.asmOptSystemIntoEnforcement; 35 36 import static com.android.server.wm.ActivityStarter.ASM_RESTRICTIONS; 37 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ACTIVITY_STARTS; 38 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM; 39 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME; 40 import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_ALLOW; 41 import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_FG_ONLY; 42 import static com.android.server.wm.ActivityTaskSupervisor.getApplicationLabel; 43 import static com.android.server.wm.PendingRemoteAnimationRegistry.TIMEOUT_MS; 44 import static com.android.window.flags.Flags.balDontBringExistingBackgroundTaskStackToFg; 45 import static com.android.window.flags.Flags.balImprovedMetrics; 46 import static com.android.window.flags.Flags.balImproveRealCallerVisibilityCheck; 47 import static com.android.window.flags.Flags.balRequireOptInByPendingIntentCreator; 48 import static com.android.window.flags.Flags.balRequireOptInSameUid; 49 import static com.android.window.flags.Flags.balRespectAppSwitchStateWhenCheckBoundByForegroundUid; 50 import static com.android.window.flags.Flags.balShowToastsBlocked; 51 52 import static java.lang.annotation.RetentionPolicy.SOURCE; 53 import static java.util.Objects.requireNonNull; 54 55 import android.annotation.IntDef; 56 import android.annotation.NonNull; 57 import android.annotation.Nullable; 58 import android.app.ActivityManager; 59 import android.app.ActivityOptions; 60 import android.app.AppOpsManager; 61 import android.app.BackgroundStartPrivileges; 62 import android.app.compat.CompatChanges; 63 import android.compat.annotation.ChangeId; 64 import android.compat.annotation.EnabledAfter; 65 import android.content.ComponentName; 66 import android.content.Intent; 67 import android.content.pm.ApplicationInfo; 68 import android.content.pm.PackageManager; 69 import android.os.Process; 70 import android.os.SystemClock; 71 import android.os.UserHandle; 72 import android.provider.DeviceConfig; 73 import android.util.ArraySet; 74 import android.util.DebugUtils; 75 import android.util.Slog; 76 import android.widget.Toast; 77 78 import com.android.internal.R; 79 import com.android.internal.annotations.GuardedBy; 80 import com.android.internal.annotations.VisibleForTesting; 81 import com.android.internal.util.FrameworkStatsLog; 82 import com.android.internal.util.Preconditions; 83 import com.android.server.UiThread; 84 import com.android.server.am.PendingIntentRecord; 85 86 import java.lang.annotation.Retention; 87 import java.util.ArrayList; 88 import java.util.HashMap; 89 import java.util.StringJoiner; 90 import java.util.function.Consumer; 91 import java.util.function.Function; 92 import java.util.function.Predicate; 93 94 /** 95 * Helper class to check permissions for starting Activities. 96 * 97 * <p>This class collects all the logic to prevent malicious attempts to start activities. 98 */ 99 public class BackgroundActivityStartController { 100 101 private static final String TAG = 102 TAG_WITH_CLASS_NAME ? "BackgroundActivityStartController" : TAG_ATM; 103 104 private static final long ASM_GRACEPERIOD_TIMEOUT_MS = TIMEOUT_MS; 105 private static final int ASM_GRACEPERIOD_MAX_REPEATS = 5; 106 private static final int NO_PROCESS_UID = -1; 107 108 static final String AUTO_OPT_IN_NOT_PENDING_INTENT = "notPendingIntent"; 109 static final String AUTO_OPT_IN_CALL_FOR_RESULT = "callForResult"; 110 static final String AUTO_OPT_IN_SAME_UID = "sameUid"; 111 static final String AUTO_OPT_IN_COMPAT = "compatibility"; 112 113 /** If enabled the creator will not allow BAL on its behalf by default. */ 114 @ChangeId 115 @EnabledAfter(targetSdkVersion = UPSIDE_DOWN_CAKE) 116 private static final long DEFAULT_RESCIND_BAL_PRIVILEGES_FROM_PENDING_INTENT_CREATOR = 117 296478951; 118 public static final ActivityOptions ACTIVITY_OPTIONS_SYSTEM_DEFINED = 119 ActivityOptions.makeBasic() 120 .setPendingIntentBackgroundActivityStartMode( 121 MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED) 122 .setPendingIntentCreatorBackgroundActivityStartMode( 123 MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED); 124 125 private final ActivityTaskManagerService mService; 126 127 private final ActivityTaskSupervisor mSupervisor; 128 129 // TODO(b/263368846) Rename when ASM logic is moved in 130 @Retention(SOURCE) 131 @IntDef({BAL_BLOCK, 132 BAL_ALLOW_DEFAULT, 133 BAL_ALLOW_ALLOWLISTED_UID, 134 BAL_ALLOW_ALLOWLISTED_COMPONENT, 135 BAL_ALLOW_VISIBLE_WINDOW, 136 BAL_ALLOW_PENDING_INTENT, 137 BAL_ALLOW_PERMISSION, 138 BAL_ALLOW_SAW_PERMISSION, 139 BAL_ALLOW_GRACE_PERIOD, 140 BAL_ALLOW_FOREGROUND, 141 BAL_ALLOW_SDK_SANDBOX 142 }) 143 public @interface BalCode {} 144 145 static final int BAL_BLOCK = 0; 146 147 static final int BAL_ALLOW_DEFAULT = 148 FrameworkStatsLog.BAL_ALLOWED__ALLOWED_REASON__BAL_ALLOW_DEFAULT; 149 150 // Following codes are in order of precedence 151 152 /** Important UIDs which should be always allowed to launch activities */ 153 static final int BAL_ALLOW_ALLOWLISTED_UID = 154 FrameworkStatsLog.BAL_ALLOWED__ALLOWED_REASON__BAL_ALLOW_ALLOWLISTED_UID; 155 156 /** Apps that fulfill a certain role that can can always launch new tasks */ 157 static final int BAL_ALLOW_ALLOWLISTED_COMPONENT = 158 FrameworkStatsLog.BAL_ALLOWED__ALLOWED_REASON__BAL_ALLOW_ALLOWLISTED_COMPONENT; 159 160 /** 161 * Apps which currently have a visible window or are bound by a service with a visible 162 * window 163 */ 164 static final int BAL_ALLOW_VISIBLE_WINDOW = 165 FrameworkStatsLog.BAL_ALLOWED__ALLOWED_REASON__BAL_ALLOW_VISIBLE_WINDOW; 166 167 /** Allowed due to the PendingIntent sender */ 168 static final int BAL_ALLOW_PENDING_INTENT = 169 FrameworkStatsLog.BAL_ALLOWED__ALLOWED_REASON__BAL_ALLOW_PENDING_INTENT; 170 171 /** 172 * App has START_ACTIVITIES_FROM_BACKGROUND permission or BAL instrumentation privileges 173 * granted to it 174 */ 175 static final int BAL_ALLOW_PERMISSION = 176 FrameworkStatsLog.BAL_ALLOWED__ALLOWED_REASON__BAL_ALLOW_BAL_PERMISSION; 177 178 /** Process has SYSTEM_ALERT_WINDOW permission granted to it */ 179 static final int BAL_ALLOW_SAW_PERMISSION = 180 FrameworkStatsLog.BAL_ALLOWED__ALLOWED_REASON__BAL_ALLOW_SAW_PERMISSION; 181 182 /** App is in grace period after an activity was started or finished */ 183 static final int BAL_ALLOW_GRACE_PERIOD = 184 FrameworkStatsLog.BAL_ALLOWED__ALLOWED_REASON__BAL_ALLOW_GRACE_PERIOD; 185 186 /** App is in a foreground task or bound to a foreground service (but not itself visible) */ 187 static final int BAL_ALLOW_FOREGROUND = 188 FrameworkStatsLog.BAL_ALLOWED__ALLOWED_REASON__BAL_ALLOW_FOREGROUND; 189 190 /** Process belongs to a SDK sandbox */ 191 static final int BAL_ALLOW_SDK_SANDBOX = 192 FrameworkStatsLog.BAL_ALLOWED__ALLOWED_REASON__BAL_ALLOW_SDK_SANDBOX; 193 194 /** Process belongs to a SDK sandbox */ 195 static final int BAL_ALLOW_NON_APP_VISIBLE_WINDOW = 196 FrameworkStatsLog.BAL_ALLOWED__ALLOWED_REASON__BAL_ALLOW_NON_APP_VISIBLE_WINDOW; 197 balCodeToString(@alCode int balCode)198 static String balCodeToString(@BalCode int balCode) { 199 return switch (balCode) { 200 case BAL_ALLOW_ALLOWLISTED_COMPONENT -> "BAL_ALLOW_ALLOWLISTED_COMPONENT"; 201 case BAL_ALLOW_ALLOWLISTED_UID -> "BAL_ALLOW_ALLOWLISTED_UID"; 202 case BAL_ALLOW_DEFAULT -> "BAL_ALLOW_DEFAULT"; 203 case BAL_ALLOW_FOREGROUND -> "BAL_ALLOW_FOREGROUND"; 204 case BAL_ALLOW_GRACE_PERIOD -> "BAL_ALLOW_GRACE_PERIOD"; 205 case BAL_ALLOW_NON_APP_VISIBLE_WINDOW -> "BAL_ALLOW_NON_APP_VISIBLE_WINDOW"; 206 case BAL_ALLOW_PENDING_INTENT -> "BAL_ALLOW_PENDING_INTENT"; 207 case BAL_ALLOW_PERMISSION -> "BAL_ALLOW_PERMISSION"; 208 case BAL_ALLOW_SAW_PERMISSION -> "BAL_ALLOW_SAW_PERMISSION"; 209 case BAL_ALLOW_SDK_SANDBOX -> "BAL_ALLOW_SDK_SANDBOX"; 210 case BAL_ALLOW_VISIBLE_WINDOW -> "BAL_ALLOW_VISIBLE_WINDOW"; 211 case BAL_BLOCK -> "BAL_BLOCK"; 212 default -> throw new IllegalArgumentException("Unexpected value: " + balCode); 213 }; 214 } 215 216 @GuardedBy("mService.mGlobalLock") 217 private final HashMap<Integer, FinishedActivityEntry> mTaskIdToFinishedActivity = 218 new HashMap<>(); 219 @GuardedBy("mService.mGlobalLock") 220 private FinishedActivityEntry mTopFinishedActivity = null; 221 BackgroundActivityStartController( final ActivityTaskManagerService service, final ActivityTaskSupervisor supervisor)222 BackgroundActivityStartController( 223 final ActivityTaskManagerService service, final ActivityTaskSupervisor supervisor) { 224 mService = service; 225 mSupervisor = supervisor; 226 } 227 isHomeApp(int uid, @Nullable String packageName)228 private boolean isHomeApp(int uid, @Nullable String packageName) { 229 if (mService.mHomeProcess != null) { 230 // Fast check 231 return uid == mService.mHomeProcess.mUid; 232 } 233 if (packageName == null) { 234 return false; 235 } 236 ComponentName activity = 237 mService.getPackageManagerInternalLocked() 238 .getDefaultHomeActivity(UserHandle.getUserId(uid)); 239 return activity != null && packageName.equals(activity.getPackageName()); 240 } 241 242 @VisibleForTesting class BalState { 243 244 private final String mCallingPackage; 245 private final int mCallingUid; 246 private final int mCallingPid; 247 private final @ActivityTaskManagerService.AppSwitchState int mAppSwitchState; 248 private final boolean mCallingUidHasAnyVisibleWindow; 249 private final @ActivityManager.ProcessState int mCallingUidProcState; 250 private final boolean mIsCallingUidPersistentSystemProcess; 251 final BackgroundStartPrivileges mBalAllowedByPiSender; 252 final BackgroundStartPrivileges mBalAllowedByPiCreatorWithHardening; 253 final BackgroundStartPrivileges mBalAllowedByPiCreator; 254 private final String mRealCallingPackage; 255 private final int mRealCallingUid; 256 private final int mRealCallingPid; 257 private final boolean mRealCallingUidHasAnyVisibleWindow; 258 private final @ActivityManager.ProcessState int mRealCallingUidProcState; 259 private final boolean mIsRealCallingUidPersistentSystemProcess; 260 private final PendingIntentRecord mOriginatingPendingIntent; 261 private final BackgroundStartPrivileges mForcedBalByPiSender; 262 private final Intent mIntent; 263 private final WindowProcessController mCallerApp; 264 private final WindowProcessController mRealCallerApp; 265 private final boolean mIsCallForResult; 266 private final ActivityOptions mCheckedOptions; 267 final String mAutoOptInReason; 268 private final boolean mAutoOptInCaller; 269 private BalVerdict mResultForCaller; 270 private BalVerdict mResultForRealCaller; 271 BalState(int callingUid, int callingPid, final String callingPackage, int realCallingUid, int realCallingPid, WindowProcessController callerApp, PendingIntentRecord originatingPendingIntent, BackgroundStartPrivileges forcedBalByPiSender, ActivityRecord resultRecord, Intent intent, ActivityOptions checkedOptions)272 @VisibleForTesting BalState(int callingUid, int callingPid, final String callingPackage, 273 int realCallingUid, int realCallingPid, 274 WindowProcessController callerApp, 275 PendingIntentRecord originatingPendingIntent, 276 BackgroundStartPrivileges forcedBalByPiSender, 277 ActivityRecord resultRecord, 278 Intent intent, 279 ActivityOptions checkedOptions) { 280 this.mCallingPackage = callingPackage; 281 mCallingUid = callingUid; 282 mCallingPid = callingPid; 283 mRealCallingUid = realCallingUid; 284 mRealCallingPid = realCallingPid; 285 mCallerApp = callerApp; 286 mForcedBalByPiSender = forcedBalByPiSender; 287 mOriginatingPendingIntent = originatingPendingIntent; 288 mIntent = intent; 289 mRealCallingPackage = mService.getPackageNameIfUnique(realCallingUid, realCallingPid); 290 mIsCallForResult = resultRecord != null; 291 mCheckedOptions = checkedOptions; 292 @BackgroundActivityStartMode int callerBackgroundActivityStartMode = 293 checkedOptions.getPendingIntentCreatorBackgroundActivityStartMode(); 294 @BackgroundActivityStartMode int realCallerBackgroundActivityStartMode = 295 checkedOptions.getPendingIntentBackgroundActivityStartMode(); 296 297 if (!balImproveRealCallerVisibilityCheck()) { 298 // without this fix the auto-opt ins below would violate CTS tests 299 mAutoOptInReason = null; 300 mAutoOptInCaller = false; 301 } else if (originatingPendingIntent == null) { 302 mAutoOptInReason = AUTO_OPT_IN_NOT_PENDING_INTENT; 303 mAutoOptInCaller = true; 304 } else if (mIsCallForResult) { 305 mAutoOptInReason = AUTO_OPT_IN_CALL_FOR_RESULT; 306 mAutoOptInCaller = false; 307 } else if (callingUid == realCallingUid && !balRequireOptInSameUid()) { 308 mAutoOptInReason = AUTO_OPT_IN_SAME_UID; 309 mAutoOptInCaller = false; 310 } else if (realCallerBackgroundActivityStartMode 311 == MODE_BACKGROUND_ACTIVITY_START_COMPAT) { 312 mAutoOptInReason = AUTO_OPT_IN_COMPAT; 313 mAutoOptInCaller = false; 314 } else { 315 mAutoOptInReason = null; 316 mAutoOptInCaller = false; 317 } 318 319 if (mAutoOptInCaller) { 320 // grant BAL privileges unless explicitly opted out 321 mBalAllowedByPiCreatorWithHardening = mBalAllowedByPiCreator = 322 callerBackgroundActivityStartMode == MODE_BACKGROUND_ACTIVITY_START_DENIED 323 ? BackgroundStartPrivileges.NONE 324 : BackgroundStartPrivileges.ALLOW_BAL; 325 } else { 326 // for PendingIntents we restrict BAL based on target_sdk 327 mBalAllowedByPiCreatorWithHardening = getBackgroundStartPrivilegesAllowedByCreator( 328 callingUid, callingPackage, checkedOptions); 329 final BackgroundStartPrivileges mBalAllowedByPiCreatorWithoutHardening = 330 callerBackgroundActivityStartMode 331 == MODE_BACKGROUND_ACTIVITY_START_DENIED 332 ? BackgroundStartPrivileges.NONE 333 : BackgroundStartPrivileges.ALLOW_BAL; 334 mBalAllowedByPiCreator = balRequireOptInByPendingIntentCreator() 335 ? mBalAllowedByPiCreatorWithHardening 336 : mBalAllowedByPiCreatorWithoutHardening; 337 } 338 339 if (mAutoOptInReason != null) { 340 // grant BAL privileges unless explicitly opted out 341 mBalAllowedByPiSender = realCallerBackgroundActivityStartMode 342 == MODE_BACKGROUND_ACTIVITY_START_DENIED 343 ? BackgroundStartPrivileges.NONE 344 : BackgroundStartPrivileges.ALLOW_BAL; 345 } else { 346 // for PendingIntents we restrict BAL based on target_sdk 347 mBalAllowedByPiSender = 348 PendingIntentRecord.getBackgroundStartPrivilegesAllowedByCaller( 349 checkedOptions, realCallingUid, mRealCallingPackage); 350 } 351 352 mAppSwitchState = mService.getBalAppSwitchesState(); 353 mCallingUidProcState = mService.mActiveUids.getUidState(callingUid); 354 mIsCallingUidPersistentSystemProcess = 355 mCallingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI; 356 mCallingUidHasAnyVisibleWindow = mService.hasActiveVisibleWindow(callingUid); 357 if (realCallingUid == NO_PROCESS_UID) { 358 // no process provided 359 mRealCallingUidProcState = PROCESS_STATE_NONEXISTENT; 360 mRealCallingUidHasAnyVisibleWindow = false; 361 mRealCallerApp = null; 362 mIsRealCallingUidPersistentSystemProcess = false; 363 } else if (callingUid == realCallingUid) { 364 mRealCallingUidProcState = mCallingUidProcState; 365 mRealCallingUidHasAnyVisibleWindow = mCallingUidHasAnyVisibleWindow; 366 // In the PendingIntent case callerApp is not passed in, so resolve it ourselves. 367 mRealCallerApp = callerApp == null 368 ? mService.getProcessController(realCallingPid, realCallingUid) 369 : callerApp; 370 mIsRealCallingUidPersistentSystemProcess = mIsCallingUidPersistentSystemProcess; 371 } else { 372 mRealCallingUidProcState = mService.mActiveUids.getUidState(realCallingUid); 373 mRealCallingUidHasAnyVisibleWindow = 374 mService.hasActiveVisibleWindow(realCallingUid); 375 mRealCallerApp = mService.getProcessController(realCallingPid, realCallingUid); 376 mIsRealCallingUidPersistentSystemProcess = 377 mRealCallingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI; 378 } 379 } 380 getBackgroundStartPrivilegesAllowedByCreator( int callingUid, String callingPackage, ActivityOptions checkedOptions)381 private BackgroundStartPrivileges getBackgroundStartPrivilegesAllowedByCreator( 382 int callingUid, String callingPackage, ActivityOptions checkedOptions) { 383 switch (checkedOptions.getPendingIntentCreatorBackgroundActivityStartMode()) { 384 case MODE_BACKGROUND_ACTIVITY_START_ALLOWED: 385 return BackgroundStartPrivileges.ALLOW_BAL; 386 case MODE_BACKGROUND_ACTIVITY_START_DENIED: 387 return BackgroundStartPrivileges.NONE; 388 case MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED: 389 // no explicit choice by the app - let us decide what to do 390 if (callingUid == ROOT_UID || callingUid == SYSTEM_UID) { 391 // root and system must always opt in explicitly 392 return BackgroundStartPrivileges.NONE; 393 } 394 if (callingPackage != null) { 395 // determine based on the calling/creating package 396 boolean changeEnabled = CompatChanges.isChangeEnabled( 397 DEFAULT_RESCIND_BAL_PRIVILEGES_FROM_PENDING_INTENT_CREATOR, 398 callingPackage, 399 UserHandle.getUserHandleForUid(callingUid)); 400 return changeEnabled ? BackgroundStartPrivileges.NONE 401 : BackgroundStartPrivileges.ALLOW_BAL; 402 } 403 // determine based on the calling/creating uid if we cannot determine the 404 // actual package name (e.g. shared uid) 405 boolean changeEnabled = CompatChanges.isChangeEnabled( 406 DEFAULT_RESCIND_BAL_PRIVILEGES_FROM_PENDING_INTENT_CREATOR, 407 callingUid); 408 return changeEnabled ? BackgroundStartPrivileges.NONE 409 : BackgroundStartPrivileges.ALLOW_BAL; 410 default: 411 throw new IllegalStateException("unsupported BackgroundActivityStartMode: " 412 + checkedOptions.getPendingIntentCreatorBackgroundActivityStartMode()); 413 } 414 } 415 getDebugPackageName(String packageName, int uid)416 private String getDebugPackageName(String packageName, int uid) { 417 if (packageName != null) { 418 return packageName; // use actual package 419 } 420 if (uid == 0) { 421 return "root[debugOnly]"; 422 } 423 String name = mService.getPackageManagerInternalLocked().getNameForUid(uid); 424 if (name == null) { 425 name = "uid=" + uid; 426 } 427 return name + "[debugOnly]"; 428 } 429 hasRealCaller()430 private boolean hasRealCaller() { 431 return mRealCallingUid != NO_PROCESS_UID; 432 } 433 isPendingIntent()434 boolean isPendingIntent() { 435 return mOriginatingPendingIntent != null && hasRealCaller(); 436 } 437 callerIsRealCaller()438 private boolean callerIsRealCaller() { 439 return mCallingUid == mRealCallingUid; 440 } 441 setResultForCaller(BalVerdict resultForCaller)442 public void setResultForCaller(BalVerdict resultForCaller) { 443 Preconditions.checkState(mResultForCaller == null, 444 "mResultForCaller can only be set once"); 445 this.mResultForCaller = resultForCaller; 446 } 447 setResultForRealCaller(BalVerdict resultForRealCaller)448 public void setResultForRealCaller(BalVerdict resultForRealCaller) { 449 Preconditions.checkState(mResultForRealCaller == null, 450 "mResultForRealCaller can only be set once"); 451 this.mResultForRealCaller = resultForRealCaller; 452 } 453 isPendingIntentBalAllowedByPermission()454 public boolean isPendingIntentBalAllowedByPermission() { 455 return PendingIntentRecord.isPendingIntentBalAllowedByPermission(mCheckedOptions); 456 } 457 callerExplicitOptInOrAutoOptIn()458 public boolean callerExplicitOptInOrAutoOptIn() { 459 if (mAutoOptInCaller) { 460 return !callerExplicitOptOut(); 461 } 462 return mCheckedOptions.getPendingIntentCreatorBackgroundActivityStartMode() 463 == MODE_BACKGROUND_ACTIVITY_START_ALLOWED; 464 } 465 realCallerExplicitOptInOrAutoOptIn()466 public boolean realCallerExplicitOptInOrAutoOptIn() { 467 if (mAutoOptInReason != null) { 468 return !realCallerExplicitOptOut(); 469 } 470 return mCheckedOptions.getPendingIntentBackgroundActivityStartMode() 471 == MODE_BACKGROUND_ACTIVITY_START_ALLOWED; 472 } 473 callerExplicitOptOut()474 public boolean callerExplicitOptOut() { 475 return mCheckedOptions.getPendingIntentCreatorBackgroundActivityStartMode() 476 == MODE_BACKGROUND_ACTIVITY_START_DENIED; 477 } 478 realCallerExplicitOptOut()479 public boolean realCallerExplicitOptOut() { 480 return mCheckedOptions.getPendingIntentBackgroundActivityStartMode() 481 == MODE_BACKGROUND_ACTIVITY_START_DENIED; 482 } 483 callerExplicitOptInOrOut()484 public boolean callerExplicitOptInOrOut() { 485 return mCheckedOptions.getPendingIntentCreatorBackgroundActivityStartMode() 486 != MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED; 487 } 488 realCallerExplicitOptInOrOut()489 public boolean realCallerExplicitOptInOrOut() { 490 return mCheckedOptions.getPendingIntentBackgroundActivityStartMode() 491 != MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED; 492 } 493 494 @Override toString()495 public String toString() { 496 StringBuilder sb = new StringBuilder(2048); 497 sb.append("[callingPackage: ") 498 .append(getDebugPackageName(mCallingPackage, mCallingUid)); 499 sb.append("; callingPackageTargetSdk: ").append(getTargetSdk(mCallingPackage)); 500 sb.append("; callingUid: ").append(mCallingUid); 501 sb.append("; callingPid: ").append(mCallingPid); 502 sb.append("; appSwitchState: ").append(mAppSwitchState); 503 sb.append("; callingUidHasAnyVisibleWindow: ").append(mCallingUidHasAnyVisibleWindow); 504 sb.append("; callingUidProcState: ").append(DebugUtils.valueToString( 505 ActivityManager.class, "PROCESS_STATE_", mCallingUidProcState)); 506 sb.append("; isCallingUidPersistentSystemProcess: ") 507 .append(mIsCallingUidPersistentSystemProcess); 508 sb.append("; forcedBalByPiSender: ").append(mForcedBalByPiSender); 509 sb.append("; intent: ").append(mIntent); 510 sb.append("; callerApp: ").append(mCallerApp); 511 if (mCallerApp != null) { 512 sb.append("; inVisibleTask: ").append(mCallerApp.hasActivityInVisibleTask()); 513 } 514 sb.append("; balAllowedByPiCreator: ").append(mBalAllowedByPiCreator); 515 sb.append("; balAllowedByPiCreatorWithHardening: ") 516 .append(mBalAllowedByPiCreatorWithHardening); 517 sb.append("; resultIfPiCreatorAllowsBal: ").append(mResultForCaller); 518 sb.append("; hasRealCaller: ").append(hasRealCaller()); 519 sb.append("; isCallForResult: ").append(mIsCallForResult); 520 sb.append("; isPendingIntent: ").append(isPendingIntent()); 521 sb.append("; autoOptInReason: ").append(mAutoOptInReason); 522 if (hasRealCaller()) { 523 sb.append("; realCallingPackage: ") 524 .append(getDebugPackageName(mRealCallingPackage, mRealCallingUid)); 525 sb.append("; realCallingPackageTargetSdk: ") 526 .append(getTargetSdk(mRealCallingPackage)); 527 sb.append("; realCallingUid: ").append(mRealCallingUid); 528 sb.append("; realCallingPid: ").append(mRealCallingPid); 529 sb.append("; realCallingUidHasAnyVisibleWindow: ") 530 .append(mRealCallingUidHasAnyVisibleWindow); 531 sb.append("; realCallingUidProcState: ").append(DebugUtils.valueToString( 532 ActivityManager.class, "PROCESS_STATE_", mRealCallingUidProcState)); 533 sb.append("; isRealCallingUidPersistentSystemProcess: ") 534 .append(mIsRealCallingUidPersistentSystemProcess); 535 sb.append("; originatingPendingIntent: ").append(mOriginatingPendingIntent); 536 sb.append("; realCallerApp: ").append(mRealCallerApp); 537 if (mRealCallerApp != null) { 538 sb.append("; realInVisibleTask: ") 539 .append(mRealCallerApp.hasActivityInVisibleTask()); 540 } 541 sb.append("; balAllowedByPiSender: ").append(mBalAllowedByPiSender); 542 sb.append("; resultIfPiSenderAllowsBal: ").append(mResultForRealCaller); 543 } 544 // features 545 sb.append("; balImproveRealCallerVisibilityCheck: ") 546 .append(balImproveRealCallerVisibilityCheck()); 547 sb.append("; balRequireOptInByPendingIntentCreator: ") 548 .append(balRequireOptInByPendingIntentCreator()); 549 sb.append("; balRequireOptInSameUid: ").append(balRequireOptInSameUid()); 550 sb.append("; balRespectAppSwitchStateWhenCheckBoundByForegroundUid: ") 551 .append(balRespectAppSwitchStateWhenCheckBoundByForegroundUid()); 552 sb.append("; balDontBringExistingBackgroundTaskStackToFg: ") 553 .append(balDontBringExistingBackgroundTaskStackToFg()); 554 sb.append("]"); 555 return sb.toString(); 556 } 557 } 558 559 static class BalVerdict { 560 561 static final BalVerdict BLOCK = new BalVerdict(BAL_BLOCK, false, "Blocked"); 562 static final BalVerdict ALLOW_BY_DEFAULT = 563 new BalVerdict(BAL_ALLOW_DEFAULT, false, "Default"); 564 // Careful using this - it will bypass all ASM checks. 565 static final BalVerdict ALLOW_PRIVILEGED = 566 new BalVerdict(BAL_ALLOW_ALLOWLISTED_UID, false, "PRIVILEGED"); 567 private final @BalCode int mCode; 568 private final boolean mBackground; 569 private final String mMessage; 570 private String mProcessInfo; 571 // indicates BAL would be blocked because only creator of the PI has the privilege to allow 572 // BAL, the sender does not have the privilege to allow BAL. 573 private boolean mOnlyCreatorAllows; 574 /** indicates that this verdict is based on the real calling UID and not the calling UID */ 575 private boolean mBasedOnRealCaller; 576 BalVerdict(@alCode int balCode, boolean background, String message)577 BalVerdict(@BalCode int balCode, boolean background, String message) { 578 this.mBackground = background; 579 this.mCode = balCode; 580 this.mMessage = message; 581 } 582 withProcessInfo(String msg, WindowProcessController process)583 public BalVerdict withProcessInfo(String msg, WindowProcessController process) { 584 mProcessInfo = msg + " (uid=" + process.mUid + ",pid=" + process.getPid() + ")"; 585 return this; 586 } 587 blocks()588 boolean blocks() { 589 return mCode == BAL_BLOCK; 590 } 591 allows()592 boolean allows() { 593 return !blocks(); 594 } 595 setOnlyCreatorAllows(boolean onlyCreatorAllows)596 void setOnlyCreatorAllows(boolean onlyCreatorAllows) { 597 mOnlyCreatorAllows = onlyCreatorAllows; 598 } 599 onlyCreatorAllows()600 boolean onlyCreatorAllows() { 601 return mOnlyCreatorAllows; 602 } 603 604 @VisibleForTesting setBasedOnRealCaller()605 BalVerdict setBasedOnRealCaller() { 606 mBasedOnRealCaller = true; 607 return this; 608 } 609 toString()610 public String toString() { 611 StringBuilder builder = new StringBuilder(); 612 builder.append(balCodeToString(mCode)); 613 if (DEBUG_ACTIVITY_STARTS) { 614 builder.append(" ("); 615 if (mBackground) { 616 builder.append("Background "); 617 } 618 builder.append("Activity start "); 619 if (mCode == BAL_BLOCK) { 620 builder.append("denied"); 621 } else { 622 builder.append("allowed: ").append(mMessage); 623 } 624 if (mProcessInfo != null) { 625 builder.append(" "); 626 builder.append(mProcessInfo); 627 } 628 builder.append(")"); 629 } 630 return builder.toString(); 631 } 632 getRawCode()633 public @BalCode int getRawCode() { 634 return mCode; 635 } 636 getCode()637 public @BalCode int getCode() { 638 if (mBasedOnRealCaller && mCode != BAL_BLOCK) { 639 // for compatibility always return BAL_ALLOW_PENDING_INTENT if based on real caller 640 return BAL_ALLOW_PENDING_INTENT; 641 } 642 return mCode; 643 } 644 } 645 646 /** 647 * Check if a (background) activity start is allowed. 648 * 649 * @param callingUid The UID that wants to start the activity. 650 * @param callingPid The PID that wants to start the activity. 651 * @param callingPackage The package name that wants to start the activity. 652 * @param realCallingUid The UID that actually calls this method (only if this handles a 653 * PendingIntent, otherwise -1) 654 * @param realCallingPid The PID that actually calls this method (only if this handles a 655 * * PendingIntent, otherwise -1) 656 * @param callerApp The process that calls this method (only if not a PendingIntent) 657 * @param originatingPendingIntent PendingIntentRecord that originated this activity start or 658 * null if not originated by PendingIntent 659 * @param forcedBalByPiSender If set to allow, the 660 * PendingIntent's sender will try to force allow background activity starts. 661 * This is only possible if the sender of the PendingIntent is a system process. 662 * @param resultRecord If not null, this indicates that the caller expects a result. 663 * @param intent Intent that should be started. 664 * @param checkedOptions ActivityOptions to allow specific opt-ins/opt outs. 665 * 666 * @return A verdict denoting which BAL rule allows an activity to be started, 667 * or if the launch should be blocked. 668 */ checkBackgroundActivityStart( int callingUid, int callingPid, final String callingPackage, int realCallingUid, int realCallingPid, WindowProcessController callerApp, PendingIntentRecord originatingPendingIntent, BackgroundStartPrivileges forcedBalByPiSender, ActivityRecord resultRecord, Intent intent, ActivityOptions checkedOptions)669 BalVerdict checkBackgroundActivityStart( 670 int callingUid, 671 int callingPid, 672 final String callingPackage, 673 int realCallingUid, 674 int realCallingPid, 675 WindowProcessController callerApp, 676 PendingIntentRecord originatingPendingIntent, 677 BackgroundStartPrivileges forcedBalByPiSender, 678 ActivityRecord resultRecord, 679 Intent intent, 680 ActivityOptions checkedOptions) { 681 682 if (checkedOptions == null) { 683 // replace null with a constant to simplify evaluation 684 checkedOptions = ACTIVITY_OPTIONS_SYSTEM_DEFINED; 685 } 686 687 BalState state = new BalState(callingUid, callingPid, callingPackage, 688 realCallingUid, realCallingPid, callerApp, originatingPendingIntent, 689 forcedBalByPiSender, resultRecord, intent, checkedOptions); 690 691 // In the case of an SDK sandbox calling uid, check if the corresponding app uid has a 692 // visible window. 693 if (Process.isSdkSandboxUid(state.mRealCallingUid)) { 694 int realCallingSdkSandboxUidToAppUid = 695 Process.getAppUidForSdkSandboxUid(state.mRealCallingUid); 696 // realCallingSdkSandboxUidToAppUid should probably just be used instead (or in addition 697 // to realCallingUid when calculating resultForRealCaller below. 698 if (mService.hasActiveVisibleWindow(realCallingSdkSandboxUidToAppUid)) { 699 state.setResultForRealCaller(new BalVerdict(BAL_ALLOW_SDK_SANDBOX, 700 /*background*/ false, 701 "uid in SDK sandbox has visible (non-toast) window")); 702 return allowBasedOnRealCaller(state); 703 } 704 } 705 706 BalVerdict resultForCaller = checkBackgroundActivityStartAllowedByCaller(state); 707 state.setResultForCaller(resultForCaller); 708 709 if (!state.hasRealCaller()) { 710 if (resultForCaller.allows()) { 711 return allowBasedOnCaller(state); 712 } 713 return abortLaunch(state); 714 } 715 716 // The realCaller result is only calculated for PendingIntents (indicated by a valid 717 // realCallingUid). If caller and realCaller are same UID and we are already allowed based 718 // on the caller (i.e. creator of the PendingIntent) there is no need to calculate this 719 // again, but if the result is block it is possible that there are additional exceptions 720 // that allow based on the realCaller (i.e. sender of the PendingIntent), e.g. if the 721 // realCallerApp process is allowed to start (in the creator path the callerApp for 722 // PendingIntents is null). 723 BalVerdict resultForRealCaller = state.callerIsRealCaller() && resultForCaller.allows() 724 ? resultForCaller 725 : checkBackgroundActivityStartAllowedBySender(state) 726 .setBasedOnRealCaller(); 727 state.setResultForRealCaller(resultForRealCaller); 728 729 if (state.isPendingIntent()) { 730 resultForCaller.setOnlyCreatorAllows( 731 resultForCaller.allows() && resultForRealCaller.blocks()); 732 } 733 734 // Handle cases with explicit opt-in 735 if (resultForCaller.allows() && state.callerExplicitOptInOrAutoOptIn()) { 736 return allowBasedOnCaller(state); 737 } 738 if (resultForRealCaller.allows() && state.realCallerExplicitOptInOrAutoOptIn()) { 739 return allowBasedOnRealCaller(state); 740 } 741 // Handle PendingIntent cases with default behavior next 742 boolean callerCanAllow = resultForCaller.allows() && !state.callerExplicitOptOut(); 743 boolean realCallerCanAllow = resultForRealCaller.allows() 744 && !state.realCallerExplicitOptOut(); 745 if (callerCanAllow) { 746 // Allowed before V by creator 747 if (state.mBalAllowedByPiCreator.allowsBackgroundActivityStarts()) { 748 Slog.wtf(TAG, "With Android 15 BAL hardening this activity start may be blocked" 749 + " if the PI creator upgrades target_sdk to 35+! " 750 + " (missing opt in by PI creator)!" + state); 751 return allowBasedOnCaller(state); 752 } 753 } 754 if (realCallerCanAllow) { 755 // Allowed before U by sender 756 if (state.mBalAllowedByPiSender.allowsBackgroundActivityStarts()) { 757 Slog.wtf(TAG, "With Android 14 BAL hardening this activity start will be blocked" 758 + " if the PI sender upgrades target_sdk to 34+! " 759 + " (missing opt in by PI sender)!" + state); 760 return allowBasedOnRealCaller(state); 761 } 762 } 763 // caller or real caller could start the activity, but would need to explicitly opt in 764 if (callerCanAllow || realCallerCanAllow) { 765 Slog.w(TAG, "Without BAL hardening this activity start would be allowed"); 766 } 767 // neither the caller not the realCaller can allow or have explicitly opted out 768 return abortLaunch(state); 769 } 770 allowBasedOnCaller(BalState state)771 private BalVerdict allowBasedOnCaller(BalState state) { 772 if (DEBUG_ACTIVITY_STARTS) { 773 Slog.d(TAG, "Background activity launch allowed based on caller. " + state); 774 } 775 return statsLog(state.mResultForCaller, state); 776 } 777 allowBasedOnRealCaller(BalState state)778 private BalVerdict allowBasedOnRealCaller(BalState state) { 779 if (DEBUG_ACTIVITY_STARTS) { 780 Slog.d(TAG, "Background activity launch allowed based on real caller. " + state); 781 } 782 return statsLog(state.mResultForRealCaller, state); 783 } 784 abortLaunch(BalState state)785 private BalVerdict abortLaunch(BalState state) { 786 Slog.wtf(TAG, "Background activity launch blocked! " + state); 787 if (balShowToastsBlocked() 788 && (state.mResultForCaller.allows() || state.mResultForRealCaller.allows())) { 789 // only show a toast if either caller or real caller could launch if they opted in 790 showToast("BAL blocked. goo.gle/android-bal"); 791 } 792 return statsLog(BalVerdict.BLOCK, state); 793 } 794 795 /** 796 * @return A code denoting which BAL rule allows an activity to be started, 797 * or {@link #BAL_BLOCK} if the launch should be blocked 798 */ checkBackgroundActivityStartAllowedByCaller(BalState state)799 BalVerdict checkBackgroundActivityStartAllowedByCaller(BalState state) { 800 // This is used to block background activity launch even if the app is still 801 // visible to user after user clicking home button. 802 803 // Normal apps with visible app window will be allowed to start activity if app switching 804 // is allowed, or apps like live wallpaper with non app visible window will be allowed. 805 final boolean appSwitchAllowedOrFg = state.mAppSwitchState == APP_SWITCH_ALLOW 806 || state.mAppSwitchState == APP_SWITCH_FG_ONLY; 807 if (appSwitchAllowedOrFg && state.mCallingUidHasAnyVisibleWindow) { 808 return new BalVerdict(BAL_ALLOW_VISIBLE_WINDOW, 809 /*background*/ false, "callingUid has visible window"); 810 } 811 if (mService.mActiveUids.hasNonAppVisibleWindow(state.mCallingUid)) { 812 return new BalVerdict(BAL_ALLOW_NON_APP_VISIBLE_WINDOW, 813 /*background*/ false, "callingUid has non-app visible window"); 814 } 815 816 // don't abort for the most important UIDs 817 final int callingAppId = UserHandle.getAppId(state.mCallingUid); 818 if (state.mCallingUid == Process.ROOT_UID 819 || callingAppId == Process.SYSTEM_UID 820 || callingAppId == Process.NFC_UID) { 821 return new BalVerdict( 822 BAL_ALLOW_ALLOWLISTED_UID, /*background*/ false, 823 "Important callingUid"); 824 } 825 826 // Always allow home application to start activities. 827 if (isHomeApp(state.mCallingUid, state.mCallingPackage)) { 828 return new BalVerdict(BAL_ALLOW_ALLOWLISTED_COMPONENT, 829 /*background*/ false, 830 "Home app"); 831 } 832 833 // IME should always be allowed to start activity, like IME settings. 834 final WindowState imeWindow = 835 mService.mRootWindowContainer.getCurrentInputMethodWindow(); 836 if (imeWindow != null && callingAppId == imeWindow.mOwnerUid) { 837 return new BalVerdict(BAL_ALLOW_ALLOWLISTED_COMPONENT, 838 /*background*/ false, 839 "Active ime"); 840 } 841 842 // don't abort if the callingUid is a persistent system process 843 if (state.mIsCallingUidPersistentSystemProcess) { 844 return new BalVerdict(BAL_ALLOW_ALLOWLISTED_COMPONENT, 845 /*background*/ false, "callingUid is persistent system process"); 846 } 847 848 // don't abort if the callingUid has START_ACTIVITIES_FROM_BACKGROUND permission 849 if (hasBalPermission(state.mCallingUid, state.mCallingPid)) { 850 return new BalVerdict(BAL_ALLOW_PERMISSION, 851 /*background*/ true, 852 "START_ACTIVITIES_FROM_BACKGROUND permission granted"); 853 } 854 // don't abort if the caller has the same uid as the recents component 855 if (mSupervisor.mRecentTasks.isCallerRecents(state.mCallingUid)) { 856 return new BalVerdict(BAL_ALLOW_ALLOWLISTED_COMPONENT, 857 /*background*/ true, "Recents Component"); 858 } 859 // don't abort if the callingUid is the device owner 860 if (mService.isDeviceOwner(state.mCallingUid)) { 861 return new BalVerdict(BAL_ALLOW_ALLOWLISTED_COMPONENT, 862 /*background*/ true, "Device Owner"); 863 } 864 // don't abort if the callingUid is a affiliated profile owner 865 if (mService.isAffiliatedProfileOwner(state.mCallingUid)) { 866 return new BalVerdict(BAL_ALLOW_ALLOWLISTED_COMPONENT, 867 /*background*/ true, "Affiliated Profile Owner"); 868 } 869 // don't abort if the callingUid has companion device 870 final int callingUserId = UserHandle.getUserId(state.mCallingUid); 871 if (mService.isAssociatedCompanionApp(callingUserId, state.mCallingUid)) { 872 return new BalVerdict(BAL_ALLOW_ALLOWLISTED_COMPONENT, 873 /*background*/ true, "Companion App"); 874 } 875 // don't abort if the callingUid has SYSTEM_ALERT_WINDOW permission 876 if (mService.hasSystemAlertWindowPermission(state.mCallingUid, state.mCallingPid, 877 state.mCallingPackage)) { 878 Slog.w( 879 TAG, 880 "Background activity start for " 881 + state.mCallingPackage 882 + " allowed because SYSTEM_ALERT_WINDOW permission is granted."); 883 return new BalVerdict(BAL_ALLOW_SAW_PERMISSION, 884 /*background*/ true, "SYSTEM_ALERT_WINDOW permission is granted"); 885 } 886 // don't abort if the callingUid and callingPackage have the 887 // OP_SYSTEM_EXEMPT_FROM_ACTIVITY_BG_START_RESTRICTION appop 888 if (isSystemExemptFlagEnabled() && mService.getAppOpsManager().checkOpNoThrow( 889 AppOpsManager.OP_SYSTEM_EXEMPT_FROM_ACTIVITY_BG_START_RESTRICTION, 890 state.mCallingUid, state.mCallingPackage) == AppOpsManager.MODE_ALLOWED) { 891 return new BalVerdict(BAL_ALLOW_PERMISSION, /*background*/ true, 892 "OP_SYSTEM_EXEMPT_FROM_ACTIVITY_BG_START_RESTRICTION appop is granted"); 893 } 894 895 // If we don't have callerApp at this point, no caller was provided to startActivity(). 896 // That's the case for PendingIntent-based starts, since the creator's process might not be 897 // up and alive. 898 // Don't abort if the callerApp or other processes of that uid are allowed in any way. 899 BalVerdict callerAppAllowsBal = checkProcessAllowsBal(state.mCallerApp, state); 900 if (callerAppAllowsBal.allows()) { 901 return callerAppAllowsBal; 902 } 903 904 // If we are here, it means all exemptions based on the creator failed 905 return BalVerdict.BLOCK; 906 } 907 908 /** 909 * @return A code denoting which BAL rule allows an activity to be started, 910 * or {@link #BAL_BLOCK} if the launch should be blocked 911 */ checkBackgroundActivityStartAllowedBySender(BalState state)912 BalVerdict checkBackgroundActivityStartAllowedBySender(BalState state) { 913 914 // Normal apps with visible app window will be allowed to start activity if app switching 915 // is allowed, or apps like live wallpaper with non app visible window will be allowed. 916 // The home app can start apps even if app switches are usually disallowed. 917 final boolean appSwitchAllowedOrFg = state.mAppSwitchState == APP_SWITCH_ALLOW 918 || state.mAppSwitchState == APP_SWITCH_FG_ONLY 919 || isHomeApp(state.mRealCallingUid, state.mRealCallingPackage); 920 if (balImproveRealCallerVisibilityCheck()) { 921 if (appSwitchAllowedOrFg && state.mRealCallingUidHasAnyVisibleWindow) { 922 return new BalVerdict(BAL_ALLOW_VISIBLE_WINDOW, 923 /*background*/ false, "realCallingUid has visible window"); 924 } 925 if (mService.mActiveUids.hasNonAppVisibleWindow(state.mRealCallingUid)) { 926 return new BalVerdict(BAL_ALLOW_NON_APP_VISIBLE_WINDOW, 927 /*background*/ false, "realCallingUid has non-app visible window"); 928 } 929 } else { 930 // don't abort if the realCallingUid has a visible window 931 // TODO(b/171459802): We should check appSwitchAllowed also 932 if (state.mRealCallingUidHasAnyVisibleWindow) { 933 return new BalVerdict(BAL_ALLOW_VISIBLE_WINDOW, 934 /*background*/ false, 935 "realCallingUid has visible (non-toast) window."); 936 } 937 } 938 939 if (state.isPendingIntentBalAllowedByPermission() 940 && hasBalPermission(state.mRealCallingUid, state.mRealCallingPid)) { 941 return new BalVerdict(BAL_ALLOW_PERMISSION, 942 /*background*/ false, 943 "realCallingUid has BAL permission."); 944 } 945 946 // if the realCallingUid is a persistent system process, abort if the IntentSender 947 // wasn't allowed to start an activity 948 if (state.mForcedBalByPiSender.allowsBackgroundActivityStarts() 949 && state.mIsRealCallingUidPersistentSystemProcess) { 950 return new BalVerdict(BAL_ALLOW_ALLOWLISTED_UID, 951 /*background*/ false, 952 "realCallingUid is persistent system process AND intent " 953 + "sender forced to allow."); 954 } 955 // don't abort if the realCallingUid is an associated companion app 956 if (mService.isAssociatedCompanionApp( 957 UserHandle.getUserId(state.mRealCallingUid), state.mRealCallingUid)) { 958 return new BalVerdict(BAL_ALLOW_ALLOWLISTED_COMPONENT, 959 /*background*/ false, 960 "realCallingUid is a companion app."); 961 } 962 963 // don't abort if the callerApp or other processes of that uid are allowed in any way 964 BalVerdict realCallerAppAllowsBal = 965 checkProcessAllowsBal(state.mRealCallerApp, state); 966 if (realCallerAppAllowsBal.allows()) { 967 return realCallerAppAllowsBal; 968 } 969 970 // If we are here, it means all exemptions based on PI sender failed 971 return BalVerdict.BLOCK; 972 } 973 hasBalPermission(int uid, int pid)974 @VisibleForTesting boolean hasBalPermission(int uid, int pid) { 975 return ActivityTaskManagerService.checkPermission(START_ACTIVITIES_FROM_BACKGROUND, 976 pid, uid) == PERMISSION_GRANTED; 977 } 978 979 /** 980 * Check if the app allows BAL. 981 * <p> 982 * See {@link BackgroundLaunchProcessController#areBackgroundActivityStartsAllowed(int, int, 983 * String, int, boolean, boolean, boolean, long, long, long)} for details on the 984 * exceptions. 985 */ checkProcessAllowsBal(WindowProcessController app, BalState state)986 @VisibleForTesting BalVerdict checkProcessAllowsBal(WindowProcessController app, 987 BalState state) { 988 if (app == null) { 989 return BalVerdict.BLOCK; 990 } 991 // first check the original calling process 992 final BalVerdict balAllowedForCaller = app 993 .areBackgroundActivityStartsAllowed(state.mAppSwitchState); 994 if (balAllowedForCaller.allows()) { 995 return balAllowedForCaller.withProcessInfo("callerApp process", app); 996 } else { 997 // only if that one wasn't allowed, check the other ones 998 final ArraySet<WindowProcessController> uidProcesses = 999 mService.mProcessMap.getProcesses(app.mUid); 1000 if (uidProcesses != null) { 1001 for (int i = uidProcesses.size() - 1; i >= 0; i--) { 1002 final WindowProcessController proc = uidProcesses.valueAt(i); 1003 if (proc != app) { 1004 BalVerdict balAllowedForUid = proc.areBackgroundActivityStartsAllowed( 1005 state.mAppSwitchState); 1006 if (balAllowedForUid.allows()) { 1007 return balAllowedForUid.withProcessInfo("process", proc); 1008 } 1009 } 1010 } 1011 } 1012 } 1013 return BalVerdict.BLOCK; 1014 } 1015 1016 /** 1017 * Check activity starts which violate one of the following rules of the 1018 * activity security model (ASM): 1019 * See go/activity-security for rationale behind the rules. 1020 * 1. Within a task, only an activity matching a top UID of the task can start activities 1021 * 2. Only activities within a foreground task, which match a top UID of the task, can 1022 * create a new task or bring an existing one into the foreground 1023 */ checkActivityAllowedToStart(@ullable ActivityRecord sourceRecord, @NonNull ActivityRecord targetRecord, boolean newTask, boolean avoidMoveTaskToFront, @Nullable Task targetTask, int launchFlags, int balCode, int callingUid, int realCallingUid, TaskDisplayArea preferredTaskDisplayArea)1024 boolean checkActivityAllowedToStart(@Nullable ActivityRecord sourceRecord, 1025 @NonNull ActivityRecord targetRecord, boolean newTask, boolean avoidMoveTaskToFront, 1026 @Nullable Task targetTask, int launchFlags, int balCode, int callingUid, 1027 int realCallingUid, TaskDisplayArea preferredTaskDisplayArea) { 1028 // BAL Exception allowed in all cases 1029 if (balCode == BAL_ALLOW_ALLOWLISTED_UID) { 1030 return true; 1031 } 1032 1033 // Intents with FLAG_ACTIVITY_NEW_TASK will always be considered as creating a new task 1034 // even if the intent is delivered to an existing task. 1035 boolean taskToFront = newTask 1036 || (launchFlags & FLAG_ACTIVITY_NEW_TASK) == FLAG_ACTIVITY_NEW_TASK; 1037 1038 // BAL exception only allowed for new tasks 1039 if (taskToFront) { 1040 if (balCode == BAL_ALLOW_ALLOWLISTED_COMPONENT 1041 || balCode == BAL_ALLOW_PERMISSION 1042 || balCode == BAL_ALLOW_PENDING_INTENT 1043 || balCode == BAL_ALLOW_SAW_PERMISSION 1044 || balCode == BAL_ALLOW_VISIBLE_WINDOW 1045 || balCode == BAL_ALLOW_NON_APP_VISIBLE_WINDOW) { 1046 return true; 1047 } 1048 } 1049 1050 BlockActivityStart bas = new BlockActivityStart(); 1051 if (sourceRecord != null) { 1052 Task sourceTask = sourceRecord.getTask(); 1053 1054 Task taskToCheck = taskToFront ? sourceTask : targetTask; 1055 bas = checkTopActivityForAsm(taskToCheck, sourceRecord.getUid(), 1056 sourceRecord, bas); 1057 1058 // Allow launching into a new task (or a task matching the launched activity's 1059 // affinity) only if the current task is foreground or mutating its own task. 1060 // The latter can happen eg. if caller uses NEW_TASK flag and the activity being 1061 // launched matches affinity of source task. 1062 if (taskToFront && bas.mTopActivityMatchesSource) { 1063 bas.mTopActivityMatchesSource = (sourceTask != null 1064 && (sourceTask.isVisible() || sourceTask == targetTask)); 1065 } 1066 } else if (targetTask != null && (!taskToFront || avoidMoveTaskToFront)) { 1067 // We don't have a sourceRecord, and we're launching into an existing task. 1068 // Allow if callingUid is top of stack. 1069 bas = checkTopActivityForAsm(targetTask, callingUid, 1070 /*sourceRecord*/null, bas); 1071 } else { 1072 // We're launching from a non-visible activity. Has any visible app opted in? 1073 TaskDisplayArea displayArea = targetTask != null && targetTask.getDisplayArea() != null 1074 ? targetTask.getDisplayArea() 1075 : preferredTaskDisplayArea; 1076 if (displayArea != null) { 1077 ArrayList<Task> visibleTasks = displayArea.getVisibleTasks(); 1078 for (int i = 0; i < visibleTasks.size(); i++) { 1079 Task task = visibleTasks.get(i); 1080 if (visibleTasks.size() == 1 && task.isActivityTypeHomeOrRecents()) { 1081 bas.optedIn(task.getTopMostActivity()); 1082 } else { 1083 bas = checkTopActivityForAsm(task, callingUid, /*sourceRecord*/null, bas); 1084 } 1085 } 1086 } 1087 } 1088 1089 if (bas.mTopActivityMatchesSource) { 1090 return true; 1091 } 1092 1093 // ASM rules have failed. Log why 1094 return logAsmFailureAndCheckFeatureEnabled(sourceRecord, callingUid, realCallingUid, 1095 newTask, avoidMoveTaskToFront, targetTask, targetRecord, balCode, launchFlags, 1096 bas, taskToFront); 1097 } 1098 logAsmFailureAndCheckFeatureEnabled(ActivityRecord sourceRecord, int callingUid, int realCallingUid, boolean newTask, boolean avoidMoveTaskToFront, Task targetTask, ActivityRecord targetRecord, @BalCode int balCode, int launchFlags, BlockActivityStart bas, boolean taskToFront)1099 private boolean logAsmFailureAndCheckFeatureEnabled(ActivityRecord sourceRecord, int callingUid, 1100 int realCallingUid, boolean newTask, boolean avoidMoveTaskToFront, Task targetTask, 1101 ActivityRecord targetRecord, @BalCode int balCode, int launchFlags, 1102 BlockActivityStart bas, boolean taskToFront) { 1103 1104 ActivityRecord targetTopActivity = targetTask == null ? null 1105 : targetTask.getActivity(ar -> !ar.finishing && !ar.isAlwaysOnTop()); 1106 1107 int action = newTask || sourceRecord == null 1108 ? FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED__ACTION__ACTIVITY_START_NEW_TASK 1109 : (sourceRecord.getTask().equals(targetTask) 1110 ? FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED__ACTION__ACTIVITY_START_SAME_TASK 1111 : FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED__ACTION__ACTIVITY_START_DIFFERENT_TASK); 1112 1113 boolean enforceBlock = bas.mTopActivityOptedIn 1114 && ActivitySecurityModelFeatureFlags.shouldRestrictActivitySwitch(callingUid); 1115 1116 boolean allowedByGracePeriod = allowedByAsmGracePeriod(callingUid, sourceRecord, targetTask, 1117 balCode, taskToFront, avoidMoveTaskToFront); 1118 1119 String asmDebugInfo = getDebugInfoForActivitySecurity("Launch", sourceRecord, 1120 targetRecord, targetTask, targetTopActivity, realCallingUid, balCode, 1121 enforceBlock, taskToFront, avoidMoveTaskToFront, allowedByGracePeriod, 1122 bas.mActivityOptedIn); 1123 1124 FrameworkStatsLog.write(FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED, 1125 /* caller_uid */ 1126 sourceRecord != null ? sourceRecord.getUid() : callingUid, 1127 /* caller_activity_class_name */ 1128 sourceRecord != null ? sourceRecord.info.name : null, 1129 /* target_task_top_activity_uid */ 1130 targetTopActivity != null ? targetTopActivity.getUid() : NO_PROCESS_UID, 1131 /* target_task_top_activity_class_name */ 1132 targetTopActivity != null ? targetTopActivity.info.name : null, 1133 /* target_task_is_different */ 1134 newTask || sourceRecord == null || targetTask == null 1135 || !targetTask.equals(sourceRecord.getTask()), 1136 /* target_activity_uid */ 1137 targetRecord.getUid(), 1138 /* target_activity_class_name */ 1139 targetRecord.info.name, 1140 /* target_intent_action */ 1141 targetRecord.intent.getAction(), 1142 /* target_intent_flags */ 1143 launchFlags, 1144 /* action */ 1145 action, 1146 /* version */ 1147 ActivitySecurityModelFeatureFlags.ASM_VERSION, 1148 /* multi_window - we have our source not in the target task, but both are visible */ 1149 targetTask != null && sourceRecord != null 1150 && !targetTask.equals(sourceRecord.getTask()) && targetTask.isVisible(), 1151 /* bal_code */ 1152 balCode, 1153 /* debug_info */ 1154 asmDebugInfo 1155 ); 1156 1157 String launchedFromPackageName = targetRecord.launchedFromPackage; 1158 if (ActivitySecurityModelFeatureFlags.shouldShowToast(callingUid)) { 1159 String toastText = ActivitySecurityModelFeatureFlags.DOC_LINK 1160 + (enforceBlock ? " blocked " : " would block ") 1161 + getApplicationLabel(mService.mContext.getPackageManager(), 1162 launchedFromPackageName); 1163 showToast(toastText); 1164 1165 Slog.i(TAG, asmDebugInfo); 1166 } 1167 1168 if (enforceBlock) { 1169 Slog.e(TAG, "[ASM] Abort Launching r: " + targetRecord 1170 + " as source: " 1171 + (sourceRecord != null ? sourceRecord : launchedFromPackageName) 1172 + " is in background. New task: " + newTask 1173 + ". Top activity: " + targetTopActivity 1174 + ". BAL Code: " + balCodeToString(balCode)); 1175 1176 return false; 1177 } 1178 1179 return true; 1180 } 1181 showToast(String toastText)1182 @VisibleForTesting void showToast(String toastText) { 1183 UiThread.getHandler().post(() -> Toast.makeText(mService.mContext, 1184 toastText, Toast.LENGTH_LONG).show()); 1185 } 1186 1187 /** 1188 * If the top activity uid does not match the launching or launched activity, and the launch was 1189 * not requested from the top uid, we want to clear out all non matching activities to prevent 1190 * the top activity being sandwiched. 1191 * Both creator and sender UID are considered for the launching activity. 1192 */ clearTopIfNeeded(@onNull Task targetTask, @Nullable ActivityRecord sourceRecord, @NonNull ActivityRecord targetRecord, int callingUid, int realCallingUid, int launchFlags, @BalCode int balCode)1193 void clearTopIfNeeded(@NonNull Task targetTask, @Nullable ActivityRecord sourceRecord, 1194 @NonNull ActivityRecord targetRecord, int callingUid, int realCallingUid, 1195 int launchFlags, @BalCode int balCode) { 1196 if ((launchFlags & FLAG_ACTIVITY_NEW_TASK) != FLAG_ACTIVITY_NEW_TASK 1197 || balCode == BAL_ALLOW_ALLOWLISTED_UID) { 1198 // Launch is from the same task, (a top or privileged UID), or is directly privileged. 1199 return; 1200 } 1201 1202 int startingUid = targetRecord.getUid(); 1203 Predicate<ActivityRecord> isLaunchingOrLaunched = ar -> 1204 ar.isUid(startingUid) || ar.isUid(callingUid) || ar.isUid(realCallingUid); 1205 1206 // Return early if we know for sure we won't need to clear any activities by just checking 1207 // the top activity. 1208 ActivityRecord targetTaskTop = targetTask.getTopMostActivity(); 1209 if (targetTaskTop == null || isLaunchingOrLaunched.test(targetTaskTop)) { 1210 return; 1211 } 1212 1213 // Find the first activity which matches a safe UID and is not finishing. Clear everything 1214 // above it 1215 int[] finishCount = new int[1]; 1216 boolean shouldBlockActivityStart = ActivitySecurityModelFeatureFlags 1217 .shouldRestrictActivitySwitch(callingUid); 1218 BlockActivityStart bas = checkCrossUidActivitySwitchFromBelow( 1219 targetTaskTop, callingUid, new BlockActivityStart()); 1220 if (shouldBlockActivityStart && bas.mTopActivityOptedIn) { 1221 ActivityRecord activity = targetTask.getActivity(isLaunchingOrLaunched); 1222 if (activity == null) { 1223 // mStartActivity is not in task, so clear everything 1224 activity = targetRecord; 1225 } 1226 1227 targetTask.performClearTop(activity, launchFlags, finishCount); 1228 if (finishCount[0] > 0) { 1229 Slog.w(TAG, "Cleared top n: " + finishCount[0] + " activities from task t: " 1230 + targetTask + " not matching top uid: " + callingUid); 1231 } 1232 } 1233 1234 if (ActivitySecurityModelFeatureFlags.shouldShowToast(callingUid) 1235 && (!shouldBlockActivityStart || finishCount[0] > 0)) { 1236 showToast((shouldBlockActivityStart 1237 ? "Top activities cleared by " 1238 : "Top activities would be cleared by ") 1239 + ActivitySecurityModelFeatureFlags.DOC_LINK); 1240 1241 Slog.i(TAG, getDebugInfoForActivitySecurity("Clear Top", sourceRecord, targetRecord, 1242 targetTask, targetTaskTop, realCallingUid, balCode, shouldBlockActivityStart, 1243 /* taskToFront */ true, /* avoidMoveTaskToFront */ false, 1244 /* allowedByAsmGracePeriod */ false, bas.mActivityOptedIn)); 1245 } 1246 } 1247 1248 /** 1249 * Returns home if the passed in callingUid is not top of the stack, rather than returning to 1250 * previous task. 1251 */ checkActivityAllowedToClearTask(@onNull Task task, int callingUid, int callingPid, @NonNull String callerActivityClassName)1252 void checkActivityAllowedToClearTask(@NonNull Task task, int callingUid, int callingPid, 1253 @NonNull String callerActivityClassName) { 1254 // We may have already checked that the callingUid has additional clearTask privileges, and 1255 // cleared the calling identify. If so, we infer we do not need further restrictions here. 1256 if (callingUid == SYSTEM_UID || !task.isVisible() || task.inMultiWindowMode()) { 1257 return; 1258 } 1259 1260 String packageName = mService.mContext.getPackageManager().getNameForUid(callingUid); 1261 BalState state = new BalState(callingUid, callingPid, packageName, INVALID_UID, 1262 INVALID_PID, null, null, null, null, null, ActivityOptions.makeBasic()); 1263 @BalCode int balCode = checkBackgroundActivityStartAllowedByCaller(state).mCode; 1264 if (balCode == BAL_ALLOW_ALLOWLISTED_UID 1265 || balCode == BAL_ALLOW_ALLOWLISTED_COMPONENT 1266 || balCode == BAL_ALLOW_PERMISSION 1267 || balCode == BAL_ALLOW_SAW_PERMISSION 1268 || balCode == BAL_ALLOW_VISIBLE_WINDOW 1269 || balCode == BAL_ALLOW_NON_APP_VISIBLE_WINDOW) { 1270 return; 1271 } 1272 1273 TaskDisplayArea displayArea = task.getTaskDisplayArea(); 1274 if (displayArea == null) { 1275 // If there is no associated display area, we can not return home. 1276 return; 1277 } 1278 1279 BlockActivityStart bas = checkTopActivityForAsm(task, callingUid, null, 1280 new BlockActivityStart()); 1281 if (bas.mTopActivityMatchesSource) { 1282 return; 1283 } 1284 1285 ActivityRecord topActivity = task.getActivity(ar -> !ar.finishing && !ar.isAlwaysOnTop()); 1286 FrameworkStatsLog.write(FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED, 1287 /* caller_uid */ 1288 callingUid, 1289 /* caller_activity_class_name */ 1290 callerActivityClassName, 1291 /* target_task_top_activity_uid */ 1292 topActivity == null ? NO_PROCESS_UID : topActivity.getUid(), 1293 /* target_task_top_activity_class_name */ 1294 topActivity == null ? null : topActivity.info.name, 1295 /* target_task_is_different */ 1296 false, 1297 /* target_activity_uid */ 1298 NO_PROCESS_UID, 1299 /* target_activity_class_name */ 1300 null, 1301 /* target_intent_action */ 1302 null, 1303 /* target_intent_flags */ 1304 0, 1305 /* action */ 1306 FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED__ACTION__FINISH_TASK, 1307 /* version */ 1308 ActivitySecurityModelFeatureFlags.ASM_VERSION, 1309 /* multi_window */ 1310 false, 1311 /* bal_code */ 1312 -1, 1313 /* debug_info */ 1314 null 1315 ); 1316 1317 boolean restrictActivitySwitch = ActivitySecurityModelFeatureFlags 1318 .shouldRestrictActivitySwitch(callingUid) && bas.mTopActivityOptedIn; 1319 1320 PackageManager pm = mService.mContext.getPackageManager(); 1321 String callingPackage = pm.getNameForUid(callingUid); 1322 final CharSequence callingLabel; 1323 if (callingPackage == null) { 1324 callingPackage = String.valueOf(callingUid); 1325 callingLabel = callingPackage; 1326 } else { 1327 callingLabel = getApplicationLabel(pm, callingPackage); 1328 } 1329 1330 if (ActivitySecurityModelFeatureFlags.shouldShowToast(callingUid)) { 1331 showToast((ActivitySecurityModelFeatureFlags.DOC_LINK 1332 + (restrictActivitySwitch ? " returned home due to " 1333 : " would return home due to ") 1334 + callingLabel)); 1335 } 1336 1337 // If the activity switch should be restricted, return home rather than the 1338 // previously top task, to prevent users from being confused which app they're 1339 // viewing 1340 if (restrictActivitySwitch) { 1341 Slog.w(TAG, "[ASM] Return to home as source: " + callingPackage 1342 + " is not on top of task t: " + task); 1343 displayArea.moveHomeActivityToTop("taskRemoved"); 1344 } else { 1345 Slog.i(TAG, "[ASM] Would return to home as source: " + callingPackage 1346 + " is not on top of task t: " + task); 1347 } 1348 } 1349 1350 /** 1351 * For the purpose of ASM, ‘Top UID” for a task is defined as an activity UID 1352 * 1. Which is top of the stack in z-order 1353 * a. Excluding any activities with the flag ‘isAlwaysOnTop’ and 1354 * b. Excluding any activities which are `finishing` 1355 * 2. Or top of an adjacent task fragment to (1) 1356 * <p> 1357 * The 'sourceRecord' can be considered top even if it is 'finishing' 1358 * <p> 1359 */ checkTopActivityForAsm(@onNull Task task, int uid, @Nullable ActivityRecord sourceRecord, BlockActivityStart bas)1360 private BlockActivityStart checkTopActivityForAsm(@NonNull Task task, 1361 int uid, @Nullable ActivityRecord sourceRecord, BlockActivityStart bas) { 1362 // If the source is visible, consider it 'top'. 1363 if (sourceRecord != null && sourceRecord.isVisibleRequested()) { 1364 return bas.matchesSource(); 1365 } 1366 1367 // Always allow actual top activity 1368 ActivityRecord topActivity = task.getTopMostActivity(); 1369 if (topActivity == null) { 1370 Slog.wtf(TAG, "Activities for task: " + task + " not found."); 1371 return bas.optedIn(topActivity); 1372 } 1373 1374 bas = checkCrossUidActivitySwitchFromBelow(topActivity, uid, bas); 1375 if (bas.mTopActivityMatchesSource) { 1376 return bas; 1377 } 1378 1379 // If UID is visible in target task, allow launch 1380 if (task.forAllActivities((Predicate<ActivityRecord>) 1381 ar -> ar.isUid(uid) && ar.isVisibleRequested())) { 1382 return bas.matchesSource(); 1383 } 1384 1385 // Consider the source activity, whether or not it is finishing. Do not consider any other 1386 // finishing activity. 1387 Predicate<ActivityRecord> topOfStackPredicate = (ar) -> ar.equals(sourceRecord) 1388 || (!ar.finishing && !ar.isAlwaysOnTop()); 1389 1390 // Check top of stack (or the first task fragment for embedding). 1391 topActivity = task.getActivity(topOfStackPredicate); 1392 if (topActivity == null) { 1393 return bas; 1394 } 1395 1396 bas = checkCrossUidActivitySwitchFromBelow(topActivity, uid, bas); 1397 if (bas.mTopActivityMatchesSource) { 1398 return bas; 1399 } 1400 1401 // Even if the top activity is not a match, we may be in an embedded activity scenario with 1402 // an adjacent task fragment. Get the second fragment. 1403 TaskFragment taskFragment = topActivity.getTaskFragment(); 1404 if (taskFragment == null) { 1405 return bas; 1406 } 1407 1408 TaskFragment adjacentTaskFragment = taskFragment.getAdjacentTaskFragment(); 1409 if (adjacentTaskFragment == null) { 1410 return bas; 1411 } 1412 1413 // Check the second fragment. 1414 topActivity = adjacentTaskFragment.getActivity(topOfStackPredicate); 1415 if (topActivity == null) { 1416 return bas; 1417 } 1418 1419 return checkCrossUidActivitySwitchFromBelow(topActivity, uid, bas); 1420 } 1421 1422 /** 1423 * Determines if a source is allowed to add or remove activities from the task, 1424 * if the current ActivityRecord is above it in the stack 1425 * <p> 1426 * A transition is blocked if all of the following are met: 1427 * <pre> 1428 * 1. The source activity and the current activity record belong to different apps 1429 * (i.e, have different UIDs). 1430 * 2. The current activity target V+ 1431 * 3. The current app has set 1432 * {@link R.styleable#AndroidManifestApplication_allowCrossUidActivitySwitchFromBelow} 1433 * to {@code false} 1434 * 4. The current activity has not set 1435 * {@link ActivityRecord#setAllowCrossUidActivitySwitchFromBelow(boolean)} to {@code true} 1436 * </pre> 1437 * 1438 * 1439 * @param sourceUid The source (s) activity performing the state change 1440 */ checkCrossUidActivitySwitchFromBelow(ActivityRecord ar, int sourceUid, BlockActivityStart bas)1441 private BlockActivityStart checkCrossUidActivitySwitchFromBelow(ActivityRecord ar, 1442 int sourceUid, BlockActivityStart bas) { 1443 if (ar.isUid(sourceUid)) { 1444 return bas.matchesSource(); 1445 } 1446 1447 // We don't need to check package level if activity has opted out. 1448 if (ar.mAllowCrossUidActivitySwitchFromBelow) { 1449 bas.mTopActivityOptedIn = false; 1450 return bas.matchesSource(); 1451 } 1452 1453 if (ar.isUid(SYSTEM_UID)) { 1454 if (asmOptSystemIntoEnforcement()) { 1455 return bas.optedIn(ar); 1456 } else { 1457 return bas; 1458 } 1459 } 1460 1461 if (!CompatChanges.isChangeEnabled(ASM_RESTRICTIONS, ar.getUid())) { 1462 return bas; 1463 } 1464 1465 1466 String packageName = ar.packageName; 1467 if (packageName == null) { 1468 Slog.wtf(TAG, "Package name: " + ar + " not found."); 1469 return bas.optedIn(ar); 1470 } 1471 1472 PackageManager pm = mService.mContext.getPackageManager(); 1473 ApplicationInfo applicationInfo; 1474 1475 try { 1476 applicationInfo = pm.getApplicationInfo(packageName, 0); 1477 } catch (PackageManager.NameNotFoundException e) { 1478 Slog.wtf(TAG, "Package name: " + packageName + " not found."); 1479 return bas.optedIn(ar); 1480 } 1481 1482 return applicationInfo.allowCrossUidActivitySwitchFromBelow ? bas : bas.optedIn(ar); 1483 } 1484 1485 /** 1486 * Only called when an activity launch may be blocked, which should happen very rarely 1487 */ getDebugInfoForActivitySecurity(@onNull String action, @Nullable ActivityRecord sourceRecord, @NonNull ActivityRecord targetRecord, @Nullable Task targetTask, @Nullable ActivityRecord targetTopActivity, int realCallingUid, @BalCode int balCode, boolean enforceBlock, boolean taskToFront, boolean avoidMoveTaskToFront, boolean allowedByGracePeriod, ActivityRecord activityOptedIn)1488 private String getDebugInfoForActivitySecurity(@NonNull String action, 1489 @Nullable ActivityRecord sourceRecord, @NonNull ActivityRecord targetRecord, 1490 @Nullable Task targetTask, @Nullable ActivityRecord targetTopActivity, 1491 int realCallingUid, @BalCode int balCode, 1492 boolean enforceBlock, boolean taskToFront, 1493 boolean avoidMoveTaskToFront, boolean allowedByGracePeriod, 1494 ActivityRecord activityOptedIn) { 1495 final String prefix = "[ASM] "; 1496 Function<ActivityRecord, String> recordToString = (ar) -> { 1497 if (ar == null) { 1498 return null; 1499 } 1500 1501 return (ar == sourceRecord ? " [source]=> " 1502 : ar == targetTopActivity ? " [ top ]=> " 1503 : ar == targetRecord ? " [target]=> " 1504 : " => ") 1505 + getDebugStringForActivityRecord(ar); 1506 }; 1507 1508 StringJoiner joiner = new StringJoiner("\n"); 1509 joiner.add(prefix + "------ Activity Security " + action + " Debug Logging Start ------"); 1510 joiner.add(prefix + "Block Enabled: " + enforceBlock); 1511 if (!enforceBlock) { 1512 joiner.add(prefix + "Feature Flag Enabled: " + android.security 1513 .Flags.asmRestrictionsEnabled()); 1514 joiner.add(prefix + "Mendel Override: " + ActivitySecurityModelFeatureFlags 1515 .asmRestrictionsEnabledForAll()); 1516 } 1517 joiner.add(prefix + "ASM Version: " + ActivitySecurityModelFeatureFlags.ASM_VERSION); 1518 joiner.add(prefix + "System Time: " + SystemClock.uptimeMillis()); 1519 joiner.add(prefix + "Activity Opted In: " + recordToString.apply(activityOptedIn)); 1520 1521 boolean targetTaskMatchesSourceTask = targetTask != null 1522 && sourceRecord != null && sourceRecord.getTask() == targetTask; 1523 1524 if (sourceRecord == null) { 1525 joiner.add(prefix + "Source Package: " + targetRecord.launchedFromPackage); 1526 String realCallingPackage = mService.mContext.getPackageManager().getNameForUid( 1527 realCallingUid); 1528 joiner.add(prefix + "Real Calling Uid Package: " + realCallingPackage); 1529 } else { 1530 joiner.add(prefix + "Source Record: " + recordToString.apply(sourceRecord)); 1531 joiner.add(prefix + "Source Launch Package: " + sourceRecord.launchedFromPackage); 1532 joiner.add(prefix + "Source Launch Intent: " + sourceRecord.intent); 1533 if (targetTaskMatchesSourceTask) { 1534 joiner.add(prefix + "Source/Target Task: " + sourceRecord.getTask()); 1535 joiner.add(prefix + "Source/Target Task Stack: "); 1536 } else { 1537 joiner.add(prefix + "Source Task: " + sourceRecord.getTask()); 1538 joiner.add(prefix + "Source Task Stack: "); 1539 } 1540 sourceRecord.getTask().forAllActivities((Consumer<ActivityRecord>) 1541 ar -> joiner.add(prefix + recordToString.apply(ar))); 1542 } 1543 1544 joiner.add(prefix + "Target Task Top: " + recordToString.apply(targetTopActivity)); 1545 if (!targetTaskMatchesSourceTask) { 1546 joiner.add(prefix + "Target Task: " + targetTask); 1547 if (targetTask != null) { 1548 joiner.add(prefix + "Target Task Stack: "); 1549 targetTask.forAllActivities((Consumer<ActivityRecord>) 1550 ar -> joiner.add(prefix + recordToString.apply(ar))); 1551 } 1552 } 1553 1554 joiner.add(prefix + "Target Record: " + recordToString.apply(targetRecord)); 1555 joiner.add(prefix + "Intent: " + targetRecord.intent); 1556 joiner.add(prefix + "TaskToFront: " + taskToFront); 1557 joiner.add(prefix + "AvoidMoveToFront: " + avoidMoveTaskToFront); 1558 joiner.add(prefix + "BalCode: " + balCodeToString(balCode)); 1559 joiner.add(prefix + "Allowed By Grace Period: " + allowedByGracePeriod); 1560 joiner.add(prefix + "LastResumedActivity: " 1561 + recordToString.apply(mService.mLastResumedActivity)); 1562 joiner.add(prefix + "System opted into enforcement: " + asmOptSystemIntoEnforcement()); 1563 1564 if (mTopFinishedActivity != null) { 1565 joiner.add(prefix + "TopFinishedActivity: " + mTopFinishedActivity.mDebugInfo); 1566 } 1567 1568 if (!mTaskIdToFinishedActivity.isEmpty()) { 1569 joiner.add(prefix + "TaskIdToFinishedActivity: "); 1570 mTaskIdToFinishedActivity.values().forEach( 1571 (fae) -> joiner.add(prefix + " " + fae.mDebugInfo)); 1572 } 1573 1574 if (balCode == BAL_ALLOW_VISIBLE_WINDOW || balCode == BAL_ALLOW_NON_APP_VISIBLE_WINDOW 1575 || balCode == BAL_ALLOW_FOREGROUND) { 1576 Task task = sourceRecord != null ? sourceRecord.getTask() : targetTask; 1577 if (task != null && task.getDisplayArea() != null) { 1578 joiner.add(prefix + "Tasks: "); 1579 task.getDisplayArea().forAllTasks((Consumer<Task>) 1580 t -> joiner.add(prefix + " T: " + t.toFullString())); 1581 } 1582 } 1583 1584 joiner.add(prefix + "------ Activity Security " + action + " Debug Logging End ------"); 1585 return joiner.toString(); 1586 } 1587 allowedByAsmGracePeriod(int callingUid, @Nullable ActivityRecord sourceRecord, @Nullable Task targetTask, @BalCode int balCode, boolean taskToFront, boolean avoidMoveTaskToFront)1588 private boolean allowedByAsmGracePeriod(int callingUid, @Nullable ActivityRecord sourceRecord, 1589 @Nullable Task targetTask, @BalCode int balCode, boolean taskToFront, 1590 boolean avoidMoveTaskToFront) { 1591 if (balCode == BAL_ALLOW_GRACE_PERIOD) { 1592 // Allow if launching into new task, and caller matches most recently finished activity 1593 if (taskToFront && mTopFinishedActivity != null 1594 && mTopFinishedActivity.mUid == callingUid) { 1595 return true; 1596 } 1597 1598 // Launching into existing task - allow if matches most recently finished activity 1599 // within the task. 1600 // We can reach here multiple ways: 1601 // 1. activity in fg fires intent (taskToFront = false, sourceRecord is available) 1602 // 2. activity in bg fires intent (taskToFront = false, sourceRecord is available) 1603 // 3. activity in bg fires intent with NEW_FLAG (taskToFront = true, 1604 // avoidMoveTaskToFront = true, sourceRecord is available) 1605 // 4. activity in bg fires PI (taskToFront = true, avoidMoveTaskToFront = true, 1606 // sourceRecord is not available, targetTask may be available) 1607 if (!taskToFront || avoidMoveTaskToFront) { 1608 if (targetTask != null) { 1609 FinishedActivityEntry finishedEntry = 1610 mTaskIdToFinishedActivity.get(targetTask.mTaskId); 1611 if (finishedEntry != null && finishedEntry.mUid == callingUid) { 1612 return true; 1613 } 1614 } 1615 1616 if (sourceRecord != null) { 1617 FinishedActivityEntry finishedEntry = 1618 mTaskIdToFinishedActivity.get(sourceRecord.getTask().mTaskId); 1619 return finishedEntry != null && finishedEntry.mUid == callingUid; 1620 } 1621 } 1622 } 1623 return false; 1624 } 1625 isSystemExemptFlagEnabled()1626 private static boolean isSystemExemptFlagEnabled() { 1627 return DeviceConfig.getBoolean( 1628 NAMESPACE_WINDOW_MANAGER, 1629 /* name= */ "system_exempt_from_activity_bg_start_restriction_enabled", 1630 /* defaultValue= */ true); 1631 } 1632 statsLog(BalVerdict finalVerdict, BalState state)1633 private BalVerdict statsLog(BalVerdict finalVerdict, BalState state) { 1634 if (finalVerdict.blocks() && mService.isActivityStartsLoggingEnabled()) { 1635 // log aborted activity start to TRON 1636 mSupervisor 1637 .getActivityMetricsLogger() 1638 .logAbortedBgActivityStart( 1639 state.mIntent, 1640 state.mCallerApp, 1641 state.mCallingUid, 1642 state.mCallingPackage, 1643 state.mCallingUidProcState, 1644 state.mCallingUidHasAnyVisibleWindow, 1645 state.mRealCallingUid, 1646 state.mRealCallingUidProcState, 1647 state.mRealCallingUidHasAnyVisibleWindow, 1648 (state.mOriginatingPendingIntent != null)); 1649 } 1650 1651 if (balImprovedMetrics()) { 1652 if (shouldLogStats(finalVerdict, state)) { 1653 String activityName; 1654 if (shouldLogIntentActivity(finalVerdict, state)) { 1655 Intent intent = state.mIntent; 1656 activityName = intent == null ? "noIntent" // should never happen 1657 : requireNonNull(intent.getComponent()).flattenToShortString(); 1658 } else { 1659 activityName = ""; 1660 } 1661 writeBalAllowedLog(activityName, finalVerdict.getCode(), state); 1662 } 1663 } else { 1664 @BalCode int code = finalVerdict.getCode(); 1665 int callingUid = state.mCallingUid; 1666 int realCallingUid = state.mRealCallingUid; 1667 Intent intent = state.mIntent; 1668 1669 if (code == BAL_ALLOW_PENDING_INTENT 1670 && (callingUid < Process.FIRST_APPLICATION_UID 1671 || realCallingUid < Process.FIRST_APPLICATION_UID)) { 1672 String activityName = intent != null 1673 ? requireNonNull(intent.getComponent()).flattenToShortString() : ""; 1674 writeBalAllowedLog(activityName, BAL_ALLOW_PENDING_INTENT, 1675 state); 1676 } 1677 if (code == BAL_ALLOW_PERMISSION || code == BAL_ALLOW_FOREGROUND 1678 || code == BAL_ALLOW_SAW_PERMISSION) { 1679 // We don't need to know which activity in this case. 1680 writeBalAllowedLog("", code, state); 1681 } 1682 } 1683 return finalVerdict; 1684 } 1685 1686 @VisibleForTesting shouldLogStats(BalVerdict finalVerdict, BalState state)1687 boolean shouldLogStats(BalVerdict finalVerdict, BalState state) { 1688 if (finalVerdict.getRawCode() == BAL_ALLOW_VISIBLE_WINDOW) { 1689 if (!state.isPendingIntent()) { 1690 // regular activity start by visible app 1691 return false; 1692 } 1693 if (finalVerdict.mBasedOnRealCaller) { 1694 // PendingIntent started by visible app 1695 return false; 1696 } 1697 } 1698 return true; 1699 } 1700 1701 @VisibleForTesting shouldLogIntentActivity(BalVerdict finalVerdict, BalState state)1702 boolean shouldLogIntentActivity(BalVerdict finalVerdict, BalState state) { 1703 return finalVerdict.mBasedOnRealCaller 1704 ? state.mRealCallingUid < Process.FIRST_APPLICATION_UID 1705 : state.mCallingUid < Process.FIRST_APPLICATION_UID; 1706 } 1707 writeBalAllowedLog(String activityName, int code, BalState state)1708 @VisibleForTesting void writeBalAllowedLog(String activityName, int code, BalState state) { 1709 FrameworkStatsLog.write(FrameworkStatsLog.BAL_ALLOWED, 1710 activityName, 1711 code, 1712 state.mCallingUid, 1713 state.mRealCallingUid, 1714 state.mResultForCaller == null ? BAL_BLOCK : state.mResultForCaller.getRawCode(), 1715 state.mBalAllowedByPiCreator.allowsBackgroundActivityStarts(), 1716 state.callerExplicitOptInOrOut(), 1717 state.mResultForRealCaller == null ? BAL_BLOCK 1718 : state.mResultForRealCaller.getRawCode(), 1719 state.mBalAllowedByPiSender.allowsBackgroundActivityStarts(), 1720 state.realCallerExplicitOptInOrOut(), 1721 getTargetSdk(state.mCallingPackage), 1722 getTargetSdk(state.mRealCallingPackage) 1723 ); 1724 } 1725 1726 /** 1727 * Called whenever an activity finishes. Stores the record, so it can be used by ASM grace 1728 * period checks. 1729 */ onActivityRequestedFinishing(@onNull ActivityRecord finishActivity)1730 void onActivityRequestedFinishing(@NonNull ActivityRecord finishActivity) { 1731 // We only update the entry if the passed in activity 1732 // 1. Has been chained less than a set max AND 1733 // 2. Is visible or top 1734 FinishedActivityEntry entry = 1735 mTaskIdToFinishedActivity.get(finishActivity.getTask().mTaskId); 1736 if (entry != null && finishActivity.isUid(entry.mUid) 1737 && entry.mLaunchCount > ASM_GRACEPERIOD_MAX_REPEATS) { 1738 return; 1739 } 1740 1741 if (!finishActivity.isVisibleRequested() 1742 && finishActivity != finishActivity.getTask().getTopMostActivity()) { 1743 return; 1744 } 1745 1746 FinishedActivityEntry newEntry = new FinishedActivityEntry(finishActivity); 1747 mTaskIdToFinishedActivity.put(finishActivity.getTask().mTaskId, newEntry); 1748 if (finishActivity.getTask().mVisibleRequested) { 1749 mTopFinishedActivity = newEntry; 1750 } 1751 } 1752 1753 /** 1754 * Called whenever an activity starts. Updates the record so the activity is no longer 1755 * considered for ASM grace period checks 1756 */ onNewActivityLaunched(ActivityRecord activityStarted)1757 void onNewActivityLaunched(ActivityRecord activityStarted) { 1758 if (activityStarted.getTask() == null) { 1759 return; 1760 } 1761 1762 if (activityStarted.getTask().mVisibleRequested) { 1763 mTopFinishedActivity = null; 1764 } 1765 1766 FinishedActivityEntry entry = 1767 mTaskIdToFinishedActivity.get(activityStarted.getTask().mTaskId); 1768 if (entry != null && activityStarted.getTask().isTaskId(entry.mTaskId)) { 1769 mTaskIdToFinishedActivity.remove(entry.mTaskId); 1770 } 1771 } 1772 1773 private static class BlockActivityStart { 1774 private boolean mTopActivityOptedIn; 1775 private boolean mTopActivityMatchesSource; 1776 private ActivityRecord mActivityOptedIn; 1777 optedIn(ActivityRecord activity)1778 BlockActivityStart optedIn(ActivityRecord activity) { 1779 mTopActivityOptedIn = true; 1780 if (mActivityOptedIn == null) { 1781 mActivityOptedIn = activity; 1782 } 1783 return this; 1784 } 1785 matchesSource()1786 BlockActivityStart matchesSource() { 1787 mTopActivityMatchesSource = true; 1788 return this; 1789 } 1790 } 1791 getDebugStringForActivityRecord(ActivityRecord ar)1792 private static String getDebugStringForActivityRecord(ActivityRecord ar) { 1793 return ar 1794 + " :: visible=" + ar.isVisible() 1795 + ", visibleRequested=" + ar.isVisibleRequested() 1796 + ", finishing=" + ar.finishing 1797 + ", alwaysOnTop=" + ar.isAlwaysOnTop() 1798 + ", lastLaunchTime=" + ar.lastLaunchTime 1799 + ", lastVisibleTime=" + ar.lastVisibleTime 1800 + ", taskFragment=" + ar.getTaskFragment(); 1801 } 1802 1803 /** @return valid targetSdk or <code>-1</code> */ getTargetSdk(String packageName)1804 private int getTargetSdk(String packageName) { 1805 if (packageName == null) { 1806 return -1; 1807 } 1808 try { 1809 PackageManager pm = mService.mContext.getPackageManager(); 1810 return pm.getTargetSdkVersion(packageName); 1811 } catch (Exception e) { 1812 return -1; 1813 } 1814 } 1815 1816 private class FinishedActivityEntry { 1817 int mUid; 1818 int mTaskId; 1819 int mLaunchCount; 1820 String mDebugInfo; 1821 FinishedActivityEntry(ActivityRecord ar)1822 FinishedActivityEntry(ActivityRecord ar) { 1823 FinishedActivityEntry entry = mTaskIdToFinishedActivity.get(ar.getTask().mTaskId); 1824 int taskId = ar.getTask().mTaskId; 1825 this.mUid = ar.getUid(); 1826 this.mTaskId = taskId; 1827 this.mLaunchCount = entry == null || !ar.isUid(entry.mUid) ? 1 : entry.mLaunchCount + 1; 1828 this.mDebugInfo = getDebugStringForActivityRecord(ar); 1829 1830 mService.mH.postDelayed(() -> { 1831 synchronized (mService.mGlobalLock) { 1832 if (mTaskIdToFinishedActivity.get(taskId) == this) { 1833 mTaskIdToFinishedActivity.remove(taskId); 1834 } 1835 1836 if (mTopFinishedActivity == this) { 1837 mTopFinishedActivity = null; 1838 } 1839 } 1840 }, ASM_GRACEPERIOD_TIMEOUT_MS); 1841 } 1842 } 1843 } 1844