Merge "Only allow system or sysui to set launch activity type" into sc-dev

This commit is contained in:
Louis Chang
2021-05-24 06:08:58 +00:00
committed by Android (Google) Code Review
2 changed files with 71 additions and 14 deletions

View File

@@ -1638,15 +1638,20 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()"); mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
userId = handleIncomingUser(callingPid, callingUid, userId, "startAssistantActivity"); userId = handleIncomingUser(callingPid, callingUid, userId, "startAssistantActivity");
return getActivityStartController().obtainStarter(intent, "startAssistantActivity") final long origId = Binder.clearCallingIdentity();
.setCallingUid(callingUid) try {
.setCallingPackage(callingPackage) return getActivityStartController().obtainStarter(intent, "startAssistantActivity")
.setCallingFeatureId(callingFeatureId) .setCallingUid(callingUid)
.setResolvedType(resolvedType) .setCallingPackage(callingPackage)
.setActivityOptions(bOptions) .setCallingFeatureId(callingFeatureId)
.setUserId(userId) .setResolvedType(resolvedType)
.setAllowBackgroundActivityStart(true) .setActivityOptions(bOptions)
.execute(); .setUserId(userId)
.setAllowBackgroundActivityStart(true)
.execute();
} finally {
Binder.restoreCallingIdentity(origId);
}
} }
/** /**

View File

@@ -20,6 +20,9 @@ import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIO
import static android.Manifest.permission.START_TASKS_FROM_RECENTS; import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
import static android.Manifest.permission.STATUS_BAR_SERVICE; import static android.Manifest.permission.STATUS_BAR_SERVICE;
import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.activityTypeToString;
import static android.content.pm.PackageManager.PERMISSION_DENIED; import static android.content.pm.PackageManager.PERMISSION_DENIED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.view.Display.INVALID_DISPLAY; import static android.view.Display.INVALID_DISPLAY;
@@ -29,12 +32,15 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLAS
import android.annotation.Nullable; import android.annotation.Nullable;
import android.app.ActivityOptions; import android.app.ActivityOptions;
import android.app.AppGlobals;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.Intent; import android.content.Intent;
import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.os.Binder; import android.os.Binder;
import android.os.Bundle; import android.os.Bundle;
import android.os.Process; import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle; import android.os.UserHandle;
import android.util.Slog; import android.util.Slog;
import android.view.RemoteAnimationAdapter; import android.view.RemoteAnimationAdapter;
@@ -281,19 +287,65 @@ public class SafeActivityOptions {
} }
// If launched from bubble is specified, then ensure that the caller is system or sysui. // If launched from bubble is specified, then ensure that the caller is system or sysui.
if (options.getLaunchedFromBubble() && callingUid != Process.SYSTEM_UID) { if (options.getLaunchedFromBubble() && !isSystemOrSystemUI(callingPid, callingUid)) {
final int statusBarPerm = ActivityTaskManagerService.checkPermission( final String msg = "Permission Denial: starting " + getIntentString(intent)
STATUS_BAR_SERVICE, callingPid, callingUid); + " from " + callerApp + " (pid=" + callingPid
if (statusBarPerm == PERMISSION_DENIED) { + ", uid=" + callingUid + ") with launchedFromBubble=true";
Slog.w(TAG, msg);
throw new SecurityException(msg);
}
final int activityType = options.getLaunchActivityType();
if (activityType != ACTIVITY_TYPE_UNDEFINED
&& !isSystemOrSystemUI(callingPid, callingUid)) {
// Granted if it is assistant type and the calling uid is assistant.
boolean activityTypeGranted = false;
if (activityType == ACTIVITY_TYPE_ASSISTANT
&& isAssistant(supervisor.mService, callingUid)) {
activityTypeGranted = true;
}
if (!activityTypeGranted) {
final String msg = "Permission Denial: starting " + getIntentString(intent) final String msg = "Permission Denial: starting " + getIntentString(intent)
+ " from " + callerApp + " (pid=" + callingPid + " from " + callerApp + " (pid=" + callingPid
+ ", uid=" + callingUid + ") with launchedFromBubble=true"; + ", uid=" + callingUid + ") with launchActivityType="
+ activityTypeToString(options.getLaunchActivityType());
Slog.w(TAG, msg); Slog.w(TAG, msg);
throw new SecurityException(msg); throw new SecurityException(msg);
} }
} }
} }
private boolean isAssistant(ActivityTaskManagerService atmService, int callingUid) {
if (atmService.mActiveVoiceInteractionServiceComponent == null) {
return false;
}
final String assistantPackage =
atmService.mActiveVoiceInteractionServiceComponent.getPackageName();
try {
final int uid = AppGlobals.getPackageManager().getPackageUid(assistantPackage,
PackageManager.MATCH_DIRECT_BOOT_AUTO,
UserHandle.getUserId(callingUid));
if (uid == callingUid) {
return true;
}
} catch (RemoteException e) {
// Should not happen
}
return false;
}
private boolean isSystemOrSystemUI(int callingPid, int callingUid) {
if (callingUid == Process.SYSTEM_UID) {
return true;
}
final int statusBarPerm = ActivityTaskManagerService.checkPermission(
STATUS_BAR_SERVICE, callingPid, callingUid);
return statusBarPerm == PERMISSION_GRANTED;
}
private String getIntentString(Intent intent) { private String getIntentString(Intent intent) {
return intent != null ? intent.toString() : "(no intent)"; return intent != null ? intent.toString() : "(no intent)";
} }