Enforce permissions for calls with specified userId
Fix a couple of places where incorrect userIds were being passed in.
Change-Id: I398c676e0488ff7e584be96e96c8b32652134238
diff --git a/services/java/com/android/server/AppWidgetServiceImpl.java b/services/java/com/android/server/AppWidgetServiceImpl.java
index 539e561..79dabee 100644
--- a/services/java/com/android/server/AppWidgetServiceImpl.java
+++ b/services/java/com/android/server/AppWidgetServiceImpl.java
@@ -1514,11 +1514,12 @@
String pkg = parser.getAttributeValue(null, "pkg");
String cl = parser.getAttributeValue(null, "cl");
- final PackageManager packageManager = mContext.getPackageManager();
+ final IPackageManager packageManager = AppGlobals.getPackageManager();
try {
- packageManager.getReceiverInfo(new ComponentName(pkg, cl), 0);
- } catch (PackageManager.NameNotFoundException e) {
- String[] pkgs = packageManager
+ packageManager.getReceiverInfo(new ComponentName(pkg, cl), 0,
+ UserHandle.getCallingUserId());
+ } catch (RemoteException e) {
+ String[] pkgs = mContext.getPackageManager()
.currentToCanonicalPackageNames(new String[] { pkg });
pkg = pkgs[0];
}
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 9b61ec4..e45cee3 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -21,6 +21,7 @@
import static org.xmlpull.v1.XmlPullParser.START_TAG;
import android.app.ActivityManagerNative;
+import android.app.AppGlobals;
import android.app.IActivityManager;
import android.app.INotificationManager;
import android.app.ITransientNotification;
@@ -1313,14 +1314,14 @@
return;
}
try {
- ApplicationInfo ai = mContext.getPackageManager().getApplicationInfo(
- pkg, 0);
+ ApplicationInfo ai = AppGlobals.getPackageManager().getApplicationInfo(
+ pkg, 0, UserHandle.getCallingUserId());
if (!UserHandle.isSameApp(ai.uid, uid)) {
throw new SecurityException("Calling uid " + uid + " gave package"
+ pkg + " which is owned by uid " + ai.uid);
}
- } catch (PackageManager.NameNotFoundException e) {
- throw new SecurityException("Unknown package " + pkg);
+ } catch (RemoteException re) {
+ throw new SecurityException("Unknown package " + pkg + "\n" + re);
}
}
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index eee818b..6c87252 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -8193,7 +8193,7 @@
for (String pkg : process.pkgList) {
sb.append("Package: ").append(pkg);
try {
- PackageInfo pi = pm.getPackageInfo(pkg, 0, 0);
+ PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
if (pi != null) {
sb.append(" v").append(pi.versionCode);
if (pi.versionName != null) {
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 48a4b74..5220a7d 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -1633,6 +1633,7 @@
@Override
public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
+ enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get package info");
// reader
synchronized (mPackages) {
PackageParser.Package p = mPackages.get(packageName);
@@ -1675,6 +1676,7 @@
@Override
public int getPackageUid(String packageName, int userId) {
if (!sUserManager.exists(userId)) return -1;
+ enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get package uid");
// reader
synchronized (mPackages) {
PackageParser.Package p = mPackages.get(packageName);
@@ -1831,6 +1833,7 @@
@Override
public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
+ enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get application info");
// writer
synchronized (mPackages) {
PackageParser.Package p = mPackages.get(packageName);
@@ -1910,6 +1913,7 @@
@Override
public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
+ enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get activity info");
synchronized (mPackages) {
PackageParser.Activity a = mActivities.mActivities.get(component);
@@ -1930,6 +1934,7 @@
@Override
public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
+ enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get receiver info");
synchronized (mPackages) {
PackageParser.Activity a = mReceivers.mActivities.get(component);
if (DEBUG_PACKAGE_INFO) Log.v(
@@ -1947,6 +1952,7 @@
@Override
public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
+ enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get service info");
synchronized (mPackages) {
PackageParser.Service s = mServices.mServices.get(component);
if (DEBUG_PACKAGE_INFO) Log.v(
@@ -1964,6 +1970,7 @@
@Override
public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
+ enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get provider info");
synchronized (mPackages) {
PackageParser.Provider p = mProvidersByComponent.get(component);
if (DEBUG_PACKAGE_INFO) Log.v(
@@ -2065,6 +2072,34 @@
return PackageManager.PERMISSION_DENIED;
}
+ /**
+ * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
+ * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
+ * @param message the message to log on security exception
+ * @return
+ */
+ private void enforceCrossUserPermission(int callingUid, int userId,
+ boolean requireFullPermission, String message) {
+ if (userId < 0) {
+ throw new IllegalArgumentException("Invalid userId " + userId);
+ }
+ if (userId == UserHandle.getUserId(callingUid)) return;
+ if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
+ if (requireFullPermission) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
+ } else {
+ try {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
+ } catch (SecurityException se) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.INTERACT_ACROSS_USERS, message);
+ }
+ }
+ }
+ }
+
private BasePermission findPermissionTreeLP(String permName) {
for(BasePermission bp : mSettings.mPermissionTrees.values()) {
if (permName.startsWith(bp.name) &&
@@ -2397,6 +2432,7 @@
public ResolveInfo resolveIntent(Intent intent, String resolvedType,
int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
+ enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "resolve intent");
List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
return chooseBestActivity(intent, resolvedType, flags, query, userId);
}
@@ -2538,6 +2574,7 @@
public List<ResolveInfo> queryIntentActivities(Intent intent,
String resolvedType, int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
+ enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "query intent activities");
ComponentName comp = intent.getComponent();
if (comp == null) {
if (intent.getSelector() != null) {
@@ -2577,6 +2614,8 @@
Intent[] specifics, String[] specificTypes, Intent intent,
String resolvedType, int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
+ enforceCrossUserPermission(Binder.getCallingUid(), userId, false,
+ "query intent activity options");
final String resultsAction = intent.getAction();
List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags
@@ -8230,7 +8269,7 @@
final IPackageDataObserver observer, final int userId) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.CLEAR_APP_USER_DATA, null);
- checkValidCaller(Binder.getCallingUid(), userId);
+ enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "clear application data");
// Queue up an async operation since the package deletion may take a little while.
mHandler.post(new Runnable() {
public void run() {
@@ -8462,7 +8501,7 @@
ComponentName[] set, ComponentName activity, int userId) {
// writer
int callingUid = Binder.getCallingUid();
- checkValidCaller(callingUid, userId);
+ enforceCrossUserPermission(callingUid, userId, true, "add preferred activity");
synchronized (mPackages) {
if (mContext.checkCallingOrSelfPermission(
android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
@@ -8652,7 +8691,7 @@
final int uid = Binder.getCallingUid();
final int permission = mContext.checkCallingPermission(
android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
- checkValidCaller(uid, userId);
+ enforceCrossUserPermission(uid, userId, false, "set enabled");
final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
boolean sendNow = false;
boolean isApp = (className == null);
@@ -8780,7 +8819,7 @@
final int permission = mContext.checkCallingOrSelfPermission(
android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
- checkValidCaller(uid, userId);
+ enforceCrossUserPermission(uid, userId, true, "stop package");
// writer
synchronized (mPackages) {
if (mSettings.setPackageStoppedStateLPw(packageName, stopped, allowedByPermission,
@@ -8801,7 +8840,7 @@
public int getApplicationEnabledSetting(String packageName, int userId) {
if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
int uid = Binder.getCallingUid();
- checkValidCaller(uid, userId);
+ enforceCrossUserPermission(uid, userId, false, "get enabled");
// reader
synchronized (mPackages) {
return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
@@ -8812,7 +8851,7 @@
public int getComponentEnabledSetting(ComponentName componentName, int userId) {
if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
int uid = Binder.getCallingUid();
- checkValidCaller(uid, userId);
+ enforceCrossUserPermission(uid, userId, false, "get component enabled");
// reader
synchronized (mPackages) {
return mSettings.getComponentEnabledSettingLPr(componentName, userId);