Loading core/java/android/content/pm/PackageParser.java +5 −6 Original line number Diff line number Diff line Loading @@ -2174,7 +2174,6 @@ public class PackageParser { } final int innerDepth = parser.getDepth(); int type; while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) { Loading Loading @@ -2548,14 +2547,14 @@ public class PackageParser { com.android.internal.R.styleable.AndroidManifestActivity_singleUser, false)) { a.info.flags |= ActivityInfo.FLAG_SINGLE_USER; if (a.info.exported) { if (a.info.exported && (flags & PARSE_IS_PRIVILEGED) == 0) { Slog.w(TAG, "Activity exported request ignored due to singleUser: " + a.className + " at " + mArchiveSourcePath + " " + parser.getPositionDescription()); a.info.exported = false; } setExported = true; } } if (sa.getBoolean( com.android.internal.R.styleable.AndroidManifestActivity_primaryUserOnly, false)) { Loading Loading @@ -2907,7 +2906,7 @@ public class PackageParser { com.android.internal.R.styleable.AndroidManifestProvider_singleUser, false)) { p.info.flags |= ProviderInfo.FLAG_SINGLE_USER; if (p.info.exported) { if (p.info.exported && (flags & PARSE_IS_PRIVILEGED) == 0) { Slog.w(TAG, "Provider exported request ignored due to singleUser: " + p.className + " at " + mArchiveSourcePath + " " + parser.getPositionDescription()); Loading Loading @@ -3181,14 +3180,14 @@ public class PackageParser { com.android.internal.R.styleable.AndroidManifestService_singleUser, false)) { s.info.flags |= ServiceInfo.FLAG_SINGLE_USER; if (s.info.exported) { if (s.info.exported && (flags & PARSE_IS_PRIVILEGED) == 0) { Slog.w(TAG, "Service exported request ignored due to singleUser: " + s.className + " at " + mArchiveSourcePath + " " + parser.getPositionDescription()); s.info.exported = false; } setExported = true; } } sa.recycle(); Loading services/core/java/com/android/server/am/ActiveServices.java +2 −1 Original line number Diff line number Diff line Loading @@ -988,7 +988,8 @@ public final class ActiveServices { sInfo.applicationInfo.packageName, sInfo.name); if (userId > 0) { if (mAm.isSingleton(sInfo.processName, sInfo.applicationInfo, sInfo.name, sInfo.flags)) { sInfo.name, sInfo.flags) && mAm.isValidSingletonCall(callingUid, sInfo.applicationInfo.uid)) { userId = 0; smap = getServiceMap(0); } Loading services/core/java/com/android/server/am/ActivityManagerService.java +72 −27 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.am; import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static com.android.internal.util.XmlUtils.readBooleanAttribute; import static com.android.internal.util.XmlUtils.readIntAttribute; Loading Loading @@ -2189,7 +2190,7 @@ public final class ActivityManagerService extends ActivityManagerNative mBatteryStatsService.publish(mContext); mUsageStatsService.publish(mContext); mAppOpsService.publish(mContext); Slog.d("AppOps", "AppOpsService published"); LocalServices.addService(ActivityManagerInternal.class, new LocalService()); } Loading Loading @@ -7737,7 +7738,7 @@ public final class ActivityManagerService extends ActivityManagerNative * in {@link ContentProvider}. */ private final String checkContentProviderPermissionLocked( ProviderInfo cpi, ProcessRecord r, int userId) { ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); Loading @@ -7754,8 +7755,10 @@ public final class ActivityManagerService extends ActivityManagerNative } } } if (checkUser) { userId = handleIncomingUser(callingPid, callingUid, userId, false, true, "checkContentProviderPermissionLocked", null); false, true, "checkContentProviderPermissionLocked " + cpi.authority, null); } if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, cpi.applicationInfo.uid, cpi.exported) == PackageManager.PERMISSION_GRANTED) { Loading Loading @@ -7890,13 +7893,34 @@ public final class ActivityManagerService extends ActivityManagerNative } } boolean checkCrossUser = true; // First check if this content provider has been published... cpr = mProviderMap.getProviderByName(name, userId); // If that didn't work, check if it exists for user 0 and then // verify that it's a singleton provider before using it. if (cpr == null && userId != UserHandle.USER_OWNER) { cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); if (cpr != null) { cpi = cpr.info; if (isSingleton(cpi.processName, cpi.applicationInfo, cpi.name, cpi.flags) && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { userId = UserHandle.USER_OWNER; checkCrossUser = false; } else { cpr = null; cpi = null; } } } boolean providerRunning = cpr != null; if (providerRunning) { cpi = cpr.info; String msg; if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) { if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) != null) { throw new SecurityException(msg); } Loading Loading @@ -7976,15 +8000,21 @@ public final class ActivityManagerService extends ActivityManagerNative if (cpi == null) { return null; } // If the provider is a singleton AND // (it's a call within the same user || the provider is a // privileged app) // Then allow connecting to the singleton provider singleton = isSingleton(cpi.processName, cpi.applicationInfo, cpi.name, cpi.flags); cpi.name, cpi.flags) && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); if (singleton) { userId = 0; userId = UserHandle.USER_OWNER; } cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); String msg; if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) { if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) != null) { throw new SecurityException(msg); } Loading Loading @@ -10563,8 +10593,7 @@ public final class ActivityManagerService extends ActivityManagerNative // assume our apps are happy - lazy create the list List<ActivityManager.ProcessErrorStateInfo> errList = null; final boolean allUsers = ActivityManager.checkUidPermission( android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; int userId = UserHandle.getUserId(Binder.getCallingUid()); Loading Loading @@ -10653,8 +10682,7 @@ public final class ActivityManagerService extends ActivityManagerNative enforceNotIsolatedCaller("getRunningAppProcesses"); // Lazy instantiation of list List<ActivityManager.RunningAppProcessInfo> runList = null; final boolean allUsers = ActivityManager.checkUidPermission( android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; int userId = UserHandle.getUserId(Binder.getCallingUid()); synchronized (this) { Loading Loading @@ -13094,8 +13122,7 @@ public final class ActivityManagerService extends ActivityManagerNative if ((requireFull || checkComponentPermission( android.Manifest.permission.INTERACT_ACROSS_USERS, callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) && checkComponentPermission( android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, && checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { if (userId == UserHandle.USER_CURRENT_OR_SELF) { Loading @@ -13115,7 +13142,7 @@ public final class ActivityManagerService extends ActivityManagerNative builder.append(" but is calling from user "); builder.append(UserHandle.getUserId(callingUid)); builder.append("; this requires "); builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); builder.append(INTERACT_ACROSS_USERS_FULL); if (!requireFull) { builder.append(" or "); builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); Loading Loading @@ -13145,6 +13172,7 @@ public final class ActivityManagerService extends ActivityManagerNative boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, String className, int flags) { boolean result = false; // For apps that don't have pre-defined UIDs, check for permission if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { if (ActivityManager.checkUidPermission( Loading @@ -13157,12 +13185,14 @@ public final class ActivityManagerService extends ActivityManagerNative Slog.w(TAG, msg); throw new SecurityException(msg); } // Permission passed result = true; } } else if (componentProcessName == aInfo.packageName) { result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; } else if ("system".equals(componentProcessName)) { result = true; } else { // App with pre-defined UID, check if it's a persistent app result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; } if (DEBUG_MU) { Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo Loading @@ -13171,6 +13201,21 @@ public final class ActivityManagerService extends ActivityManagerNative return result; } /** * Checks to see if the caller is in the same app as the singleton * component, or the component is in a special app. It allows special apps * to export singleton components but prevents exporting singleton * components for regular apps. */ boolean isValidSingletonCall(int callingUid, int componentUid) { int componentAppId = UserHandle.getAppId(componentUid); return UserHandle.isSameApp(callingUid, componentUid) || componentAppId == Process.SYSTEM_UID || componentAppId == Process.PHONE_UID || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) == PackageManager.PERMISSION_GRANTED; } public int bindService(IApplicationThread caller, IBinder token, Intent service, String resolvedType, IServiceConnection connection, int flags, int userId) { Loading Loading @@ -13717,8 +13762,8 @@ public final class ActivityManagerService extends ActivityManagerNative */ int callingAppId = UserHandle.getAppId(callingUid); if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || callingUid == 0) { || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || callingUid == 0) { // Always okay. } else if (callerApp == null || !callerApp.persistent) { try { Loading Loading @@ -16528,12 +16573,12 @@ public final class ActivityManagerService extends ActivityManagerNative } private boolean startUser(final int userId, boolean foreground) { if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) != PackageManager.PERMISSION_GRANTED) { String msg = "Permission Denial: switchUser() from pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; + " requires " + INTERACT_ACROSS_USERS_FULL; Slog.w(TAG, msg); throw new SecurityException(msg); } Loading Loading @@ -16899,12 +16944,12 @@ public final class ActivityManagerService extends ActivityManagerNative @Override public int stopUser(final int userId, final IStopUserCallback callback) { if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) != PackageManager.PERMISSION_GRANTED) { String msg = "Permission Denial: switchUser() from pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; + " requires " + INTERACT_ACROSS_USERS_FULL; Slog.w(TAG, msg); throw new SecurityException(msg); } Loading Loading @@ -17042,7 +17087,7 @@ public final class ActivityManagerService extends ActivityManagerNative public UserInfo getCurrentUser() { if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) && ( checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) checkCallingPermission(INTERACT_ACROSS_USERS_FULL) != PackageManager.PERMISSION_GRANTED)) { String msg = "Permission Denial: getCurrentUser() from pid=" + Binder.getCallingPid() Loading Loading @@ -17128,12 +17173,12 @@ public final class ActivityManagerService extends ActivityManagerNative @Override public void registerUserSwitchObserver(IUserSwitchObserver observer) { if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) != PackageManager.PERMISSION_GRANTED) { String msg = "Permission Denial: registerUserSwitchObserver() from pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; + " requires " + INTERACT_ACROSS_USERS_FULL; Slog.w(TAG, msg); throw new SecurityException(msg); } services/core/java/com/android/server/am/BroadcastQueue.java +5 −1 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.content.ComponentName; import android.content.IIntentReceiver; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; Loading Loading @@ -858,7 +859,10 @@ public final class BroadcastQueue { r.state = BroadcastRecord.APP_RECEIVE; String targetProcess = info.activityInfo.processName; r.curComponent = component; if (r.callingUid != Process.SYSTEM_UID && isSingleton) { final int receiverUid = info.activityInfo.applicationInfo.uid; // If it's a singleton, it needs to be the same app or a special app if (r.callingUid != Process.SYSTEM_UID && isSingleton && mService.isValidSingletonCall(r.callingUid, receiverUid)) { info.activityInfo = mService.getActivityInfoForUser(info.activityInfo, 0); } r.curReceiver = info.activityInfo; Loading services/core/java/com/android/server/content/ContentService.java +1 −1 Original line number Diff line number Diff line Loading @@ -230,7 +230,7 @@ public final class ContentService extends IContentService.Stub { // Notify for any user other than the caller's own requires permission. final int callingUserHandle = UserHandle.getCallingUserId(); if (userHandle != callingUserHandle) { mContext.enforceCallingOrSelfPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL, mContext.enforceCallingOrSelfPermission(Manifest.permission.INTERACT_ACROSS_USERS, "no permission to notify other users"); } Loading Loading
core/java/android/content/pm/PackageParser.java +5 −6 Original line number Diff line number Diff line Loading @@ -2174,7 +2174,6 @@ public class PackageParser { } final int innerDepth = parser.getDepth(); int type; while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) { Loading Loading @@ -2548,14 +2547,14 @@ public class PackageParser { com.android.internal.R.styleable.AndroidManifestActivity_singleUser, false)) { a.info.flags |= ActivityInfo.FLAG_SINGLE_USER; if (a.info.exported) { if (a.info.exported && (flags & PARSE_IS_PRIVILEGED) == 0) { Slog.w(TAG, "Activity exported request ignored due to singleUser: " + a.className + " at " + mArchiveSourcePath + " " + parser.getPositionDescription()); a.info.exported = false; } setExported = true; } } if (sa.getBoolean( com.android.internal.R.styleable.AndroidManifestActivity_primaryUserOnly, false)) { Loading Loading @@ -2907,7 +2906,7 @@ public class PackageParser { com.android.internal.R.styleable.AndroidManifestProvider_singleUser, false)) { p.info.flags |= ProviderInfo.FLAG_SINGLE_USER; if (p.info.exported) { if (p.info.exported && (flags & PARSE_IS_PRIVILEGED) == 0) { Slog.w(TAG, "Provider exported request ignored due to singleUser: " + p.className + " at " + mArchiveSourcePath + " " + parser.getPositionDescription()); Loading Loading @@ -3181,14 +3180,14 @@ public class PackageParser { com.android.internal.R.styleable.AndroidManifestService_singleUser, false)) { s.info.flags |= ServiceInfo.FLAG_SINGLE_USER; if (s.info.exported) { if (s.info.exported && (flags & PARSE_IS_PRIVILEGED) == 0) { Slog.w(TAG, "Service exported request ignored due to singleUser: " + s.className + " at " + mArchiveSourcePath + " " + parser.getPositionDescription()); s.info.exported = false; } setExported = true; } } sa.recycle(); Loading
services/core/java/com/android/server/am/ActiveServices.java +2 −1 Original line number Diff line number Diff line Loading @@ -988,7 +988,8 @@ public final class ActiveServices { sInfo.applicationInfo.packageName, sInfo.name); if (userId > 0) { if (mAm.isSingleton(sInfo.processName, sInfo.applicationInfo, sInfo.name, sInfo.flags)) { sInfo.name, sInfo.flags) && mAm.isValidSingletonCall(callingUid, sInfo.applicationInfo.uid)) { userId = 0; smap = getServiceMap(0); } Loading
services/core/java/com/android/server/am/ActivityManagerService.java +72 −27 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.am; import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static com.android.internal.util.XmlUtils.readBooleanAttribute; import static com.android.internal.util.XmlUtils.readIntAttribute; Loading Loading @@ -2189,7 +2190,7 @@ public final class ActivityManagerService extends ActivityManagerNative mBatteryStatsService.publish(mContext); mUsageStatsService.publish(mContext); mAppOpsService.publish(mContext); Slog.d("AppOps", "AppOpsService published"); LocalServices.addService(ActivityManagerInternal.class, new LocalService()); } Loading Loading @@ -7737,7 +7738,7 @@ public final class ActivityManagerService extends ActivityManagerNative * in {@link ContentProvider}. */ private final String checkContentProviderPermissionLocked( ProviderInfo cpi, ProcessRecord r, int userId) { ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); Loading @@ -7754,8 +7755,10 @@ public final class ActivityManagerService extends ActivityManagerNative } } } if (checkUser) { userId = handleIncomingUser(callingPid, callingUid, userId, false, true, "checkContentProviderPermissionLocked", null); false, true, "checkContentProviderPermissionLocked " + cpi.authority, null); } if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, cpi.applicationInfo.uid, cpi.exported) == PackageManager.PERMISSION_GRANTED) { Loading Loading @@ -7890,13 +7893,34 @@ public final class ActivityManagerService extends ActivityManagerNative } } boolean checkCrossUser = true; // First check if this content provider has been published... cpr = mProviderMap.getProviderByName(name, userId); // If that didn't work, check if it exists for user 0 and then // verify that it's a singleton provider before using it. if (cpr == null && userId != UserHandle.USER_OWNER) { cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); if (cpr != null) { cpi = cpr.info; if (isSingleton(cpi.processName, cpi.applicationInfo, cpi.name, cpi.flags) && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { userId = UserHandle.USER_OWNER; checkCrossUser = false; } else { cpr = null; cpi = null; } } } boolean providerRunning = cpr != null; if (providerRunning) { cpi = cpr.info; String msg; if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) { if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) != null) { throw new SecurityException(msg); } Loading Loading @@ -7976,15 +8000,21 @@ public final class ActivityManagerService extends ActivityManagerNative if (cpi == null) { return null; } // If the provider is a singleton AND // (it's a call within the same user || the provider is a // privileged app) // Then allow connecting to the singleton provider singleton = isSingleton(cpi.processName, cpi.applicationInfo, cpi.name, cpi.flags); cpi.name, cpi.flags) && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); if (singleton) { userId = 0; userId = UserHandle.USER_OWNER; } cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); String msg; if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) { if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) != null) { throw new SecurityException(msg); } Loading Loading @@ -10563,8 +10593,7 @@ public final class ActivityManagerService extends ActivityManagerNative // assume our apps are happy - lazy create the list List<ActivityManager.ProcessErrorStateInfo> errList = null; final boolean allUsers = ActivityManager.checkUidPermission( android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; int userId = UserHandle.getUserId(Binder.getCallingUid()); Loading Loading @@ -10653,8 +10682,7 @@ public final class ActivityManagerService extends ActivityManagerNative enforceNotIsolatedCaller("getRunningAppProcesses"); // Lazy instantiation of list List<ActivityManager.RunningAppProcessInfo> runList = null; final boolean allUsers = ActivityManager.checkUidPermission( android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; int userId = UserHandle.getUserId(Binder.getCallingUid()); synchronized (this) { Loading Loading @@ -13094,8 +13122,7 @@ public final class ActivityManagerService extends ActivityManagerNative if ((requireFull || checkComponentPermission( android.Manifest.permission.INTERACT_ACROSS_USERS, callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) && checkComponentPermission( android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, && checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { if (userId == UserHandle.USER_CURRENT_OR_SELF) { Loading @@ -13115,7 +13142,7 @@ public final class ActivityManagerService extends ActivityManagerNative builder.append(" but is calling from user "); builder.append(UserHandle.getUserId(callingUid)); builder.append("; this requires "); builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); builder.append(INTERACT_ACROSS_USERS_FULL); if (!requireFull) { builder.append(" or "); builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); Loading Loading @@ -13145,6 +13172,7 @@ public final class ActivityManagerService extends ActivityManagerNative boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, String className, int flags) { boolean result = false; // For apps that don't have pre-defined UIDs, check for permission if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { if (ActivityManager.checkUidPermission( Loading @@ -13157,12 +13185,14 @@ public final class ActivityManagerService extends ActivityManagerNative Slog.w(TAG, msg); throw new SecurityException(msg); } // Permission passed result = true; } } else if (componentProcessName == aInfo.packageName) { result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; } else if ("system".equals(componentProcessName)) { result = true; } else { // App with pre-defined UID, check if it's a persistent app result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; } if (DEBUG_MU) { Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo Loading @@ -13171,6 +13201,21 @@ public final class ActivityManagerService extends ActivityManagerNative return result; } /** * Checks to see if the caller is in the same app as the singleton * component, or the component is in a special app. It allows special apps * to export singleton components but prevents exporting singleton * components for regular apps. */ boolean isValidSingletonCall(int callingUid, int componentUid) { int componentAppId = UserHandle.getAppId(componentUid); return UserHandle.isSameApp(callingUid, componentUid) || componentAppId == Process.SYSTEM_UID || componentAppId == Process.PHONE_UID || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) == PackageManager.PERMISSION_GRANTED; } public int bindService(IApplicationThread caller, IBinder token, Intent service, String resolvedType, IServiceConnection connection, int flags, int userId) { Loading Loading @@ -13717,8 +13762,8 @@ public final class ActivityManagerService extends ActivityManagerNative */ int callingAppId = UserHandle.getAppId(callingUid); if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || callingUid == 0) { || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || callingUid == 0) { // Always okay. } else if (callerApp == null || !callerApp.persistent) { try { Loading Loading @@ -16528,12 +16573,12 @@ public final class ActivityManagerService extends ActivityManagerNative } private boolean startUser(final int userId, boolean foreground) { if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) != PackageManager.PERMISSION_GRANTED) { String msg = "Permission Denial: switchUser() from pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; + " requires " + INTERACT_ACROSS_USERS_FULL; Slog.w(TAG, msg); throw new SecurityException(msg); } Loading Loading @@ -16899,12 +16944,12 @@ public final class ActivityManagerService extends ActivityManagerNative @Override public int stopUser(final int userId, final IStopUserCallback callback) { if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) != PackageManager.PERMISSION_GRANTED) { String msg = "Permission Denial: switchUser() from pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; + " requires " + INTERACT_ACROSS_USERS_FULL; Slog.w(TAG, msg); throw new SecurityException(msg); } Loading Loading @@ -17042,7 +17087,7 @@ public final class ActivityManagerService extends ActivityManagerNative public UserInfo getCurrentUser() { if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) && ( checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) checkCallingPermission(INTERACT_ACROSS_USERS_FULL) != PackageManager.PERMISSION_GRANTED)) { String msg = "Permission Denial: getCurrentUser() from pid=" + Binder.getCallingPid() Loading Loading @@ -17128,12 +17173,12 @@ public final class ActivityManagerService extends ActivityManagerNative @Override public void registerUserSwitchObserver(IUserSwitchObserver observer) { if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) != PackageManager.PERMISSION_GRANTED) { String msg = "Permission Denial: registerUserSwitchObserver() from pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; + " requires " + INTERACT_ACROSS_USERS_FULL; Slog.w(TAG, msg); throw new SecurityException(msg); }
services/core/java/com/android/server/am/BroadcastQueue.java +5 −1 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.content.ComponentName; import android.content.IIntentReceiver; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; Loading Loading @@ -858,7 +859,10 @@ public final class BroadcastQueue { r.state = BroadcastRecord.APP_RECEIVE; String targetProcess = info.activityInfo.processName; r.curComponent = component; if (r.callingUid != Process.SYSTEM_UID && isSingleton) { final int receiverUid = info.activityInfo.applicationInfo.uid; // If it's a singleton, it needs to be the same app or a special app if (r.callingUid != Process.SYSTEM_UID && isSingleton && mService.isValidSingletonCall(r.callingUid, receiverUid)) { info.activityInfo = mService.getActivityInfoForUser(info.activityInfo, 0); } r.curReceiver = info.activityInfo; Loading
services/core/java/com/android/server/content/ContentService.java +1 −1 Original line number Diff line number Diff line Loading @@ -230,7 +230,7 @@ public final class ContentService extends IContentService.Stub { // Notify for any user other than the caller's own requires permission. final int callingUserHandle = UserHandle.getCallingUserId(); if (userHandle != callingUserHandle) { mContext.enforceCallingOrSelfPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL, mContext.enforceCallingOrSelfPermission(Manifest.permission.INTERACT_ACROSS_USERS, "no permission to notify other users"); } Loading