diff options
| author | 2020-03-19 20:28:09 +0100 | |
|---|---|---|
| committer | 2020-03-30 16:34:20 +0000 | |
| commit | ed401cc16d27d90c78b9744b580f00529e391e9a (patch) | |
| tree | 837bf26bf71ee45d1e9d19e2dc3a6f1df6cf472e | |
| parent | 480275a1977bcace74963d83c70c4c9e53d3a029 (diff) | |
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
4 files changed, 47 insertions, 47 deletions
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java index c9be1c1fabb2..4aae3da7e8cf 100644 --- a/core/java/android/service/dreams/DreamService.java +++ b/core/java/android/service/dreams/DreamService.java @@ -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); diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index da1c045dba16..d63dc192b58e 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -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); diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index e83ac7be8985..a75420e2a84d 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -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; } diff --git a/services/core/java/com/android/server/wm/AppTaskImpl.java b/services/core/java/com/android/server/wm/AppTaskImpl.java index 4cce212cb779..8fa811915fc2 100644 --- a/services/core/java/com/android/server/wm/AppTaskImpl.java +++ b/services/core/java/com/android/server/wm/AppTaskImpl.java @@ -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; } |