Introduce security checks to startDreamActivity
This CL checks that the caller is the dream package and that the device is dreaming when the activity is started. isDream was instroduced in order to exempt the DreamActivity from background start check. setAllowBackgroundActivityStart does that more cleanly. Bug: 152281628 Test: m && flashall && verify dream works Change-Id: Id6161f923f3350d482b3452a78a792a541dcf1a1
This commit is contained in:
@@ -1049,6 +1049,7 @@ public class DreamService extends Service implements Window.Callback {
|
||||
// DreamServiceWrapper.onActivityCreated.
|
||||
if (!mWindowless) {
|
||||
Intent i = new Intent(this, DreamActivity.class);
|
||||
i.setPackage(getApplicationContext().getPackageName());
|
||||
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
i.putExtra(DreamActivity.EXTRA_CALLBACK, mDreamServiceWrapper);
|
||||
|
||||
|
||||
@@ -341,7 +341,6 @@ class ActivityStarter {
|
||||
int filterCallingUid;
|
||||
PendingIntentRecord originatingPendingIntent;
|
||||
boolean allowBackgroundActivityStart;
|
||||
boolean isDream;
|
||||
|
||||
/**
|
||||
* If set to {@code true}, allows this activity start to look into
|
||||
@@ -393,7 +392,6 @@ class ActivityStarter {
|
||||
filterCallingUid = UserHandle.USER_NULL;
|
||||
originatingPendingIntent = null;
|
||||
allowBackgroundActivityStart = false;
|
||||
isDream = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -434,7 +432,6 @@ class ActivityStarter {
|
||||
filterCallingUid = request.filterCallingUid;
|
||||
originatingPendingIntent = request.originatingPendingIntent;
|
||||
allowBackgroundActivityStart = request.allowBackgroundActivityStart;
|
||||
isDream = request.isDream;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -985,7 +982,7 @@ class ActivityStarter {
|
||||
restrictedBgActivity = shouldAbortBackgroundActivityStart(callingUid,
|
||||
callingPid, callingPackage, realCallingUid, realCallingPid, callerApp,
|
||||
request.originatingPendingIntent, request.allowBackgroundActivityStart,
|
||||
request.isDream, intent);
|
||||
intent);
|
||||
} finally {
|
||||
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
|
||||
}
|
||||
@@ -1195,7 +1192,7 @@ class ActivityStarter {
|
||||
boolean shouldAbortBackgroundActivityStart(int callingUid, int callingPid,
|
||||
final String callingPackage, int realCallingUid, int realCallingPid,
|
||||
WindowProcessController callerApp, PendingIntentRecord originatingPendingIntent,
|
||||
boolean allowBackgroundActivityStart, boolean isDream, Intent intent) {
|
||||
boolean allowBackgroundActivityStart, Intent intent) {
|
||||
// don't abort for the most important UIDs
|
||||
final int callingAppId = UserHandle.getAppId(callingUid);
|
||||
if (callingUid == Process.ROOT_UID || callingAppId == Process.SYSTEM_UID
|
||||
@@ -1203,10 +1200,6 @@ class ActivityStarter {
|
||||
return false;
|
||||
}
|
||||
|
||||
// don't abort if this is the dream activity
|
||||
if (isDream) {
|
||||
return false;
|
||||
}
|
||||
// don't abort if the callingUid has a visible window or is a persistent system process
|
||||
final int callingUidProcState = mService.getUidState(callingUid);
|
||||
final boolean callingUidHasAnyVisibleWindow =
|
||||
@@ -2717,11 +2710,6 @@ class ActivityStarter {
|
||||
return this;
|
||||
}
|
||||
|
||||
ActivityStarter setIsDream(boolean isDream) {
|
||||
mRequest.isDream = isDream;
|
||||
return this;
|
||||
}
|
||||
|
||||
void dump(PrintWriter pw, String prefix) {
|
||||
prefix = prefix + " ";
|
||||
pw.print(prefix);
|
||||
|
||||
@@ -212,7 +212,6 @@ import android.os.storage.IStorageManager;
|
||||
import android.os.storage.StorageManager;
|
||||
import android.provider.Settings;
|
||||
import android.service.dreams.DreamActivity;
|
||||
import android.service.dreams.DreamManagerInternal;
|
||||
import android.service.voice.IVoiceInteractionSession;
|
||||
import android.service.voice.VoiceInteractionManagerInternal;
|
||||
import android.sysprop.DisplayProperties;
|
||||
@@ -1245,36 +1244,29 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startDreamActivity(Intent intent) {
|
||||
final WindowProcessController process = mProcessMap.getProcess(Binder.getCallingPid());
|
||||
private void enforceCallerIsDream(String callerPackageName) {
|
||||
final long origId = Binder.clearCallingIdentity();
|
||||
|
||||
// The dream activity is only called for non-doze dreams.
|
||||
final ComponentName currentDream = LocalServices.getService(DreamManagerInternal.class)
|
||||
.getActiveDreamComponent(/* doze= */ false);
|
||||
|
||||
if (currentDream == null || currentDream.getPackageName() == null
|
||||
|| !currentDream.getPackageName().equals(process.mInfo.packageName)) {
|
||||
Slog.e(TAG, "Calling package is not the current dream package. "
|
||||
+ "Aborting startDreamActivity...");
|
||||
return false;
|
||||
try {
|
||||
if (!ActivityRecord.canLaunchDreamActivity(callerPackageName)) {
|
||||
throw new SecurityException("The dream activity can be started only when the device"
|
||||
+ " is dreaming and only by the active dream package.");
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(origId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startDreamActivity(@NonNull Intent intent) {
|
||||
assertPackageMatchesCallingUid(intent.getPackage());
|
||||
enforceCallerIsDream(intent.getPackage());
|
||||
|
||||
final ActivityInfo a = new ActivityInfo();
|
||||
a.theme = com.android.internal.R.style.Theme_Dream;
|
||||
a.exported = true;
|
||||
a.name = DreamActivity.class.getName();
|
||||
|
||||
|
||||
a.packageName = process.mInfo.packageName;
|
||||
a.applicationInfo = process.mInfo;
|
||||
a.processName = process.mInfo.processName;
|
||||
a.uiOptions = process.mInfo.uiOptions;
|
||||
a.taskAffinity = "android:" + a.packageName + "/dream";
|
||||
a.enabled = true;
|
||||
a.launchMode = ActivityInfo.LAUNCH_SINGLE_INSTANCE;
|
||||
|
||||
a.persistableMode = ActivityInfo.PERSIST_NEVER;
|
||||
a.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
|
||||
a.colorMode = ActivityInfo.COLOR_MODE_DEFAULT;
|
||||
@@ -1283,15 +1275,34 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
||||
final ActivityOptions options = ActivityOptions.makeBasic();
|
||||
options.setLaunchActivityType(ACTIVITY_TYPE_DREAM);
|
||||
|
||||
try {
|
||||
getActivityStartController().obtainStarter(intent, "dream")
|
||||
.setActivityInfo(a)
|
||||
.setActivityOptions(options.toBundle())
|
||||
.setIsDream(true)
|
||||
.execute();
|
||||
return true;
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(origId);
|
||||
synchronized (mGlobalLock) {
|
||||
final WindowProcessController process = mProcessMap.getProcess(Binder.getCallingPid());
|
||||
|
||||
a.packageName = process.mInfo.packageName;
|
||||
a.applicationInfo = process.mInfo;
|
||||
a.processName = process.mInfo.processName;
|
||||
a.uiOptions = process.mInfo.uiOptions;
|
||||
a.taskAffinity = "android:" + a.packageName + "/dream";
|
||||
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
final int callingPid = Binder.getCallingPid();
|
||||
|
||||
final long origId = Binder.clearCallingIdentity();
|
||||
try {
|
||||
getActivityStartController().obtainStarter(intent, "dream")
|
||||
.setCallingUid(callingUid)
|
||||
.setCallingPid(callingPid)
|
||||
.setActivityInfo(a)
|
||||
.setActivityOptions(options.toBundle())
|
||||
// To start the dream from background, we need to start it from a persistent
|
||||
// system process. Here we set the real calling uid to the system server uid
|
||||
.setRealCallingUid(Binder.getCallingUid())
|
||||
.setAllowBackgroundActivityStart(true)
|
||||
.execute();
|
||||
return true;
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(origId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2478,7 +2489,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
||||
final ActivityStarter starter = getActivityStartController().obtainStarter(
|
||||
null /* intent */, "moveTaskToFront");
|
||||
if (starter.shouldAbortBackgroundActivityStart(callingUid, callingPid, callingPackage, -1,
|
||||
-1, callerApp, null, false, false, null)) {
|
||||
-1, callerApp, null, false, null)) {
|
||||
if (!isBackgroundActivityStartsEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ class AppTaskImpl extends IAppTask.Stub {
|
||||
final ActivityStarter starter = mService.getActivityStartController().obtainStarter(
|
||||
null /* intent */, "moveToFront");
|
||||
if (starter.shouldAbortBackgroundActivityStart(callingUid, callingPid,
|
||||
callingPackage, -1, -1, callerApp, null, false, false, null)) {
|
||||
callingPackage, -1, -1, callerApp, null, false, null)) {
|
||||
if (!mService.isBackgroundActivityStartsEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user