diff options
9 files changed, 87 insertions, 20 deletions
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 8472144a92cf..8de5c8db6bc3 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -242,6 +242,7 @@ public abstract class Context { BIND_IMPORTANT, BIND_ADJUST_WITH_ACTIVITY, BIND_NOT_PERCEPTIBLE, + BIND_DENY_ACTIVITY_STARTS, BIND_INCLUDE_CAPABILITIES }) @Retention(RetentionPolicy.SOURCE) @@ -356,6 +357,14 @@ public abstract class Context { /*********** Hidden flags below this line ***********/ /** + * Flag for {@link #bindService}: If binding from an app that is visible, the bound service is + * allowed to start an activity from background. Add a flag so that this behavior can be opted + * out. + * @hide + */ + public static final int BIND_DENY_ACTIVITY_STARTS = 0X000004000; + + /** * Flag for {@link #bindService}: This flag is intended to be used only by the system to adjust * the scheduling policy for IMEs (and any other out-of-process user-visible components that * work closely with the top app) so that UI hosted in such services can have the same diff --git a/core/proto/android/server/activitymanagerservice.proto b/core/proto/android/server/activitymanagerservice.proto index 2d2ead455a4d..a2a33c844de8 100644 --- a/core/proto/android/server/activitymanagerservice.proto +++ b/core/proto/android/server/activitymanagerservice.proto @@ -524,6 +524,7 @@ message ConnectionRecordProto { DEAD = 15; NOT_PERCEPTIBLE = 16; INCLUDE_CAPABILITIES = 17; + DENY_ACTIVITY_STARTS = 18; } repeated Flag flags = 3; optional string service_name = 4; diff --git a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java index ab7b54d98285..beadd821957b 100644 --- a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java +++ b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java @@ -351,7 +351,17 @@ public class DreamBackend { if (cn != null && cn.indexOf('/') < 0) { cn = resolveInfo.serviceInfo.packageName + "/" + cn; } - return cn == null ? null : ComponentName.unflattenFromString(cn); + // Ensure that the component is from the same package as the dream service. If not, + // treat the component as invalid and return null instead. + final ComponentName result = cn != null ? ComponentName.unflattenFromString(cn) : null; + if (result != null + && !result.getPackageName().equals(resolveInfo.serviceInfo.packageName)) { + Log.w(TAG, + "Inconsistent package name in component: " + result.getPackageName() + + ", should be: " + resolveInfo.serviceInfo.packageName); + return null; + } + return result; } private static void logd(String msg, Object... args) { diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 26c34aa1b103..1e8d339d3759 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -162,7 +162,6 @@ import android.app.AppOpsManagerInternal.CheckOpsDelegate; import android.app.ApplicationErrorReport; import android.app.ApplicationExitInfo; import android.app.ApplicationThreadConstants; -import android.app.AppOpsManager; import android.app.BroadcastOptions; import android.app.ContentProviderHolder; import android.app.IActivityController; @@ -5780,12 +5779,12 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override - public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code, + public int sendIntentSender(IIntentSender target, IBinder allowlistToken, int code, Intent intent, String resolvedType, IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) { if (target instanceof PendingIntentRecord) { return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType, - whitelistToken, finishedReceiver, requiredPermission, options); + allowlistToken, finishedReceiver, requiredPermission, options); } else { if (intent == null) { // Weird case: someone has given us their own custom IIntentSender, and now @@ -5797,7 +5796,20 @@ public class ActivityManagerService extends IActivityManager.Stub intent = new Intent(Intent.ACTION_MAIN); } try { - target.send(code, intent, resolvedType, whitelistToken, null, + if (allowlistToken != null) { + final int callingUid = Binder.getCallingUid(); + final String packageName; + final long token = Binder.clearCallingIdentity(); + try { + packageName = AppGlobals.getPackageManager().getNameForUid(callingUid); + } finally { + Binder.restoreCallingIdentity(token); + } + Slog.wtf(TAG, "Send a non-null allowlistToken to a non-PI target." + + " Calling package: " + packageName + "; intent: " + intent + + "; options: " + options); + } + target.send(code, intent, resolvedType, null, null, requiredPermission, options); } catch (RemoteException e) { } diff --git a/services/core/java/com/android/server/am/ConnectionRecord.java b/services/core/java/com/android/server/am/ConnectionRecord.java index 6d9d3fbe41bd..cf9e3ce1eadb 100644 --- a/services/core/java/com/android/server/am/ConnectionRecord.java +++ b/services/core/java/com/android/server/am/ConnectionRecord.java @@ -67,6 +67,7 @@ final class ConnectionRecord { Context.BIND_NOT_VISIBLE, Context.BIND_NOT_PERCEPTIBLE, Context.BIND_INCLUDE_CAPABILITIES, + Context.BIND_DENY_ACTIVITY_STARTS, }; private static final int[] BIND_PROTO_ENUMS = new int[] { ConnectionRecordProto.AUTO_CREATE, @@ -86,6 +87,7 @@ final class ConnectionRecord { ConnectionRecordProto.NOT_VISIBLE, ConnectionRecordProto.NOT_PERCEPTIBLE, ConnectionRecordProto.INCLUDE_CAPABILITIES, + ConnectionRecordProto.DENY_ACTIVITY_STARTS, }; void dump(PrintWriter pw, String prefix) { @@ -219,6 +221,9 @@ final class ConnectionRecord { if ((flags & Context.BIND_NOT_PERCEPTIBLE) != 0) { sb.append("!PRCP "); } + if ((flags & Context.BIND_DENY_ACTIVITY_STARTS) != 0) { + sb.append("BALFD "); + } if ((flags & Context.BIND_INCLUDE_CAPABILITIES) != 0) { sb.append("CAPS "); } diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index c5152c081e70..85b210515b8c 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -1341,14 +1341,14 @@ class ProcessRecord implements WindowProcessListener { !mAllowBackgroundActivityStartsTokens.isEmpty()); } - void addBoundClientUid(int clientUid) { + void addBoundClientUid(int clientUid, String clientPackageName, int bindFlags) { mBoundClientUids.add(clientUid); - mWindowProcessController.setBoundClientUids(mBoundClientUids); + mWindowProcessController.addBoundClientUid(clientUid, clientPackageName, bindFlags); } void updateBoundClientUids() { + clearBoundClientUids(); if (mServices.isEmpty()) { - clearBoundClientUids(); return; } // grab a set of clientUids of all connections of all services @@ -1361,12 +1361,14 @@ class ProcessRecord implements WindowProcessListener { for (int conni = 0; conni < N; conni++) { ArrayList<ConnectionRecord> c = conns.valueAt(conni); for (int i = 0; i < c.size(); i++) { - boundClientUids.add(c.get(i).clientUid); + ConnectionRecord cr = c.get(i); + boundClientUids.add(cr.clientUid); + mWindowProcessController + .addBoundClientUid(cr.clientUid, cr.clientPackageName, cr.flags); } } } mBoundClientUids = boundClientUids; - mWindowProcessController.setBoundClientUids(mBoundClientUids); } void addBoundClientUidsOfNewService(ServiceRecord sr) { @@ -1377,15 +1379,17 @@ class ProcessRecord implements WindowProcessListener { for (int conni = conns.size() - 1; conni >= 0; conni--) { ArrayList<ConnectionRecord> c = conns.valueAt(conni); for (int i = 0; i < c.size(); i++) { - mBoundClientUids.add(c.get(i).clientUid); + ConnectionRecord cr = c.get(i); + mBoundClientUids.add(cr.clientUid); + mWindowProcessController + .addBoundClientUid(cr.clientUid, cr.clientPackageName, cr.flags); } } - mWindowProcessController.setBoundClientUids(mBoundClientUids); } void clearBoundClientUids() { mBoundClientUids.clear(); - mWindowProcessController.setBoundClientUids(mBoundClientUids); + mWindowProcessController.clearBoundClientUids(); } void setActiveInstrumentation(ActiveInstrumentation instr) { diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java index 5583c5129287..9ded778f866c 100644 --- a/services/core/java/com/android/server/am/ServiceRecord.java +++ b/services/core/java/com/android/server/am/ServiceRecord.java @@ -627,7 +627,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN // if we have a process attached, add bound client uid of this connection to it if (app != null) { - app.addBoundClientUid(c.clientUid); + app.addBoundClientUid(c.clientUid, c.clientPackageName, c.flags); } } diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java index 31fbaff17e78..ee27730f1664 100644 --- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java +++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java @@ -2747,7 +2747,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub if (!mContext.bindServiceAsUser(intent, newConn, Context.BIND_AUTO_CREATE | Context.BIND_SHOWING_UI | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE - | Context.BIND_INCLUDE_CAPABILITIES, + | Context.BIND_INCLUDE_CAPABILITIES + | Context.BIND_DENY_ACTIVITY_STARTS, new UserHandle(serviceUserId))) { String msg = "Unable to bind service: " + componentName; diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java index 29cf1776df9c..161936f358d1 100644 --- a/services/core/java/com/android/server/wm/WindowProcessController.java +++ b/services/core/java/com/android/server/wm/WindowProcessController.java @@ -514,16 +514,41 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio } private boolean isBoundByForegroundUid() { - for (int i = mBoundClientUids.size() - 1; i >= 0; --i) { - if (mAtm.isUidForeground(mBoundClientUids.valueAt(i))) { - return true; + synchronized (this) { + if (mBoundClientUids != null) { + for (int i = mBoundClientUids.size() - 1; i >= 0; --i) { + if (mAtm.isUidForeground(mBoundClientUids.valueAt(i))) { + return true; + } + } } } return false; } - public void setBoundClientUids(ArraySet<Integer> boundClientUids) { - mBoundClientUids = boundClientUids; + /** + * Clear all bound client Uids. + */ + public void clearBoundClientUids() { + synchronized (this) { + if (mBoundClientUids == null) { + mBoundClientUids = new ArraySet<>(); + } else { + mBoundClientUids.clear(); + } + } + } + + /** + * Add bound client Uid. + */ + public void addBoundClientUid(int clientUid, String clientPackageName, int bindFlags) { + if ((bindFlags & Context.BIND_DENY_ACTIVITY_STARTS) == 0) { + if (mBoundClientUids == null) { + mBoundClientUids = new ArraySet<>(); + } + mBoundClientUids.add(clientUid); + } } public void setInstrumenting(boolean instrumenting, |