summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/ApplicationPackageManager.java6
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java5
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl6
-rw-r--r--core/java/android/content/pm/PackageManager.java18
-rw-r--r--services/core/java/com/android/server/pm/CrossProfileIntentFilter.java62
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java41
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java14
7 files changed, 103 insertions, 49 deletions
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 68d4cf108891..2fef250228b1 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -1583,7 +1583,8 @@ final class ApplicationPackageManager extends PackageManager {
public void addCrossProfileIntentFilter(IntentFilter filter, int sourceUserId, int targetUserId,
int flags) {
try {
- mPM.addCrossProfileIntentFilter(filter, sourceUserId, targetUserId, flags);
+ mPM.addCrossProfileIntentFilter(filter, mContext.getOpPackageName(),
+ mContext.getUserId(), sourceUserId, targetUserId, flags);
} catch (RemoteException e) {
// Should never happen!
}
@@ -1607,7 +1608,8 @@ final class ApplicationPackageManager extends PackageManager {
@Override
public void clearCrossProfileIntentFilters(int sourceUserId) {
try {
- mPM.clearCrossProfileIntentFilters(sourceUserId);
+ mPM.clearCrossProfileIntentFilters(sourceUserId, mContext.getOpPackageName(),
+ mContext.getUserId());
} catch (RemoteException e) {
// Should never happen!
}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 1f2f18a23f02..70cbd471b30f 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -2391,8 +2391,9 @@ public class DevicePolicyManager {
}
/**
- * Called by a profile owner to remove the cross-profile intent filters from the managed profile
- * and from the parent.
+ * Called by a profile owner to remove the cross-profile intent filters that go from the
+ * managed profile to the parent, or from the parent to the managed profile.
+ * Only removes those that have been set by the profile owner.
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
*/
public void clearCrossProfileIntentFilters(ComponentName admin) {
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 72c85ee62fbf..7196372edf4f 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -244,13 +244,13 @@ interface IPackageManager {
void clearPackagePersistentPreferredActivities(String packageName, int userId);
- void addCrossProfileIntentFilter(in IntentFilter intentFilter, int sourceUserId, int targetUserId,
- int flags);
+ void addCrossProfileIntentFilter(in IntentFilter intentFilter, String ownerPackage,
+ int ownerUserId, int sourceUserId, int targetUserId, int flags);
void addCrossProfileIntentsForPackage(in String packageName, int sourceUserId,
int targetUserId);
- void clearCrossProfileIntentFilters(int sourceUserId);
+ void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage, int ownerUserId);
/**
* Report the set of 'Home' activity candidates, plus (if any) which of them
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 62611efa5db0..c5dcd8ea5786 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -205,13 +205,6 @@ public abstract class PackageManager {
public static final int NO_CROSS_PROFILE = 0x00020000;
/**
- * Flag for {@link addCrossProfileIntentFilter}: if the cross-profile intent has been set by the
- * profile owner.
- * @hide
- */
- public static final int SET_BY_PROFILE_OWNER= 0x00000001;
-
- /**
* Flag for {@link addCrossProfileIntentFilter}: if this flag is set:
* when resolving an intent that matches the {@link CrossProfileIntentFilter}, the current
* profile will be skipped.
@@ -3744,9 +3737,10 @@ public abstract class PackageManager {
* Adds a {@link CrossProfileIntentFilter}. After calling this method all intents sent from the
* user with id sourceUserId can also be be resolved by activities in the user with id
* targetUserId if they match the specified intent filter.
- * @param filter the {@link IntentFilter} the intent has to match
- * @param removable if set to false, {@link clearCrossProfileIntentFilters} will not remove this
- * {@link CrossProfileIntentFilter}
+ * @param filter The {@link IntentFilter} the intent has to match
+ * @param sourceUserId The source user id.
+ * @param targetUserId The target user id.
+ * @param flags The only possible value is {@link SKIP_CURRENT_PROFILE}
* @hide
*/
public abstract void addCrossProfileIntentFilter(IntentFilter filter, int sourceUserId,
@@ -3754,8 +3748,8 @@ public abstract class PackageManager {
/**
* Clearing {@link CrossProfileIntentFilter}s which have the specified user as their
- * source, and have been set by the profile owner
- * @param sourceUserId
+ * source, and have been set by the app calling this method.
+ * @param sourceUserId The source user id.
* @hide
*/
public abstract void clearCrossProfileIntentFilters(int sourceUserId);
diff --git a/services/core/java/com/android/server/pm/CrossProfileIntentFilter.java b/services/core/java/com/android/server/pm/CrossProfileIntentFilter.java
index 3ce19c1fe43a..c61d344f48e6 100644
--- a/services/core/java/com/android/server/pm/CrossProfileIntentFilter.java
+++ b/services/core/java/com/android/server/pm/CrossProfileIntentFilter.java
@@ -33,17 +33,24 @@ import android.os.UserHandle;
class CrossProfileIntentFilter extends IntentFilter {
private static final String ATTR_TARGET_USER_ID = "targetUserId";
private static final String ATTR_FLAGS = "flags";
+ private static final String ATTR_OWNER_USER_ID = "ownerUserId";
+ private static final String ATTR_OWNER_PACKAGE = "ownerPackage";
private static final String ATTR_FILTER = "filter";
private static final String TAG = "CrossProfileIntentFilter";
// If the intent matches the IntentFilter, then it can be forwarded to this userId.
final int mTargetUserId;
+ final int mOwnerUserId; // userId of the app which has set this CrossProfileIntentFilter.
+ final String mOwnerPackage; // packageName of the app.
final int mFlags;
- CrossProfileIntentFilter(IntentFilter filter, int targetUserId, int flags) {
+ CrossProfileIntentFilter(IntentFilter filter, String ownerPackage, int ownerUserId,
+ int targetUserId, int flags) {
super(filter);
mTargetUserId = targetUserId;
+ mOwnerUserId = ownerUserId;
+ mOwnerPackage = ownerPackage;
mFlags = flags;
}
@@ -55,25 +62,20 @@ class CrossProfileIntentFilter extends IntentFilter {
return mFlags;
}
+ public int getOwnerUserId() {
+ return mOwnerUserId;
+ }
+
+ public String getOwnerPackage() {
+ return mOwnerPackage;
+ }
+
CrossProfileIntentFilter(XmlPullParser parser) throws XmlPullParserException, IOException {
- String targetUserIdString = parser.getAttributeValue(null, ATTR_TARGET_USER_ID);
- if (targetUserIdString == null) {
- String msg = "Missing element under " + TAG +": " + ATTR_TARGET_USER_ID + " at " +
- parser.getPositionDescription();
- PackageManagerService.reportSettingsProblem(Log.WARN, msg);
- mTargetUserId = UserHandle.USER_NULL;
- } else {
- mTargetUserId = Integer.parseInt(targetUserIdString);
- }
- String flagsString = parser.getAttributeValue(null, ATTR_FLAGS);
- if (flagsString == null) {
- String msg = "Missing element under " + TAG +": " + ATTR_FLAGS + " at " +
- parser.getPositionDescription();
- PackageManagerService.reportSettingsProblem(Log.WARN, msg);
- mFlags = 0;
- } else {
- mFlags = Integer.parseInt(flagsString);
- }
+ mTargetUserId = getIntFromXml(parser, ATTR_TARGET_USER_ID, UserHandle.USER_NULL);
+ mOwnerUserId = getIntFromXml(parser, ATTR_OWNER_USER_ID, UserHandle.USER_NULL);
+ mOwnerPackage = getStringFromXml(parser, ATTR_OWNER_PACKAGE, "");
+ mFlags = getIntFromXml(parser, ATTR_FLAGS, 0);
+
int outerDepth = parser.getDepth();
String tagName = parser.getName();
int type;
@@ -103,9 +105,31 @@ class CrossProfileIntentFilter extends IntentFilter {
}
}
+ String getStringFromXml(XmlPullParser parser, String attribute, String defaultValue) {
+ String value = parser.getAttributeValue(null, attribute);
+ if (value == null) {
+ String msg = "Missing element under " + TAG +": " + attribute + " at " +
+ parser.getPositionDescription();
+ PackageManagerService.reportSettingsProblem(Log.WARN, msg);
+ return defaultValue;
+ } else {
+ return value;
+ }
+ }
+
+ int getIntFromXml(XmlPullParser parser, String attribute, int defaultValue) {
+ String stringValue = getStringFromXml(parser, attribute, null);
+ if (stringValue != null) {
+ return Integer.parseInt(stringValue);
+ }
+ return defaultValue;
+ }
+
public void writeToXml(XmlSerializer serializer) throws IOException {
serializer.attribute(null, ATTR_TARGET_USER_ID, Integer.toString(mTargetUserId));
serializer.attribute(null, ATTR_FLAGS, Integer.toString(mFlags));
+ serializer.attribute(null, ATTR_OWNER_USER_ID, Integer.toString(mOwnerUserId));
+ serializer.attribute(null, ATTR_OWNER_PACKAGE, mOwnerPackage);
serializer.startTag(null, ATTR_FILTER);
super.writeToXml(serializer);
serializer.endTag(null, ATTR_FILTER);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index a07eb7e75d2c..68ae6ff65c91 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -11635,22 +11635,25 @@ public class PackageManagerService extends IPackageManager.Stub {
}
@Override
- public void addCrossProfileIntentFilter(IntentFilter intentFilter, int sourceUserId,
- int targetUserId, int flags) {
+ public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
+ int ownerUserId, int sourceUserId, int targetUserId, int flags) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
+ int callingUid = Binder.getCallingUid();
+ enforceOwnerRights(ownerPackage, ownerUserId, callingUid);
if (intentFilter.countActions() == 0) {
Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
return;
}
synchronized (mPackages) {
CrossProfileIntentFilter filter = new CrossProfileIntentFilter(intentFilter,
- targetUserId, flags);
+ ownerPackage, UserHandle.getUserId(callingUid), targetUserId, flags);
mSettings.editCrossProfileIntentResolverLPw(sourceUserId).addFilter(filter);
mSettings.writePackageRestrictionsLPr(sourceUserId);
}
}
+ @Override
public void addCrossProfileIntentsForPackage(String packageName,
int sourceUserId, int targetUserId) {
mContext.enforceCallingOrSelfPermission(
@@ -11668,16 +11671,21 @@ public class PackageManagerService extends IPackageManager.Stub {
}
@Override
- public void clearCrossProfileIntentFilters(int sourceUserId) {
+ public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage,
+ int ownerUserId) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
+ int callingUid = Binder.getCallingUid();
+ enforceOwnerRights(ownerPackage, ownerUserId, callingUid);
+ int callingUserId = UserHandle.getUserId(callingUid);
synchronized (mPackages) {
CrossProfileIntentResolver resolver =
mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
HashSet<CrossProfileIntentFilter> set =
new HashSet<CrossProfileIntentFilter>(resolver.filterSet());
for (CrossProfileIntentFilter filter : set) {
- if ((filter.getFlags() & PackageManager.SET_BY_PROFILE_OWNER) != 0) {
+ if (filter.getOwnerPackage().equals(ownerPackage)
+ && filter.getOwnerUserId() == callingUserId) {
resolver.removeFilter(filter);
}
}
@@ -11685,6 +11693,29 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ // Enforcing that callingUid is owning pkg on userId
+ private void enforceOwnerRights(String pkg, int userId, int callingUid) {
+ // The system owns everything.
+ if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
+ return;
+ }
+ int callingUserId = UserHandle.getUserId(callingUid);
+ if (callingUserId != userId) {
+ throw new SecurityException("calling uid " + callingUid
+ + " pretends to own " + pkg + " on user " + userId + " but belongs to user "
+ + callingUserId);
+ }
+ PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
+ if (pi == null) {
+ throw new IllegalArgumentException("Unknown package " + pkg + " on user "
+ + callingUserId);
+ }
+ if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
+ throw new SecurityException("Calling uid " + callingUid
+ + " does not own package " + pkg);
+ }
+ }
+
@Override
public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
Intent intent = new Intent(Intent.ACTION_MAIN);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index dc55e6d5bbba..c54c4fb65ccb 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -3606,12 +3606,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
long id = Binder.clearCallingIdentity();
try {
if ((flags & DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED) != 0) {
- pm.addCrossProfileIntentFilter(filter, callingUserId, UserHandle.USER_OWNER,
- PackageManager.SET_BY_PROFILE_OWNER);
+ pm.addCrossProfileIntentFilter(filter, who.getPackageName(),
+ mContext.getUserId(), callingUserId, UserHandle.USER_OWNER, 0);
}
if ((flags & DevicePolicyManager.FLAG_MANAGED_CAN_ACCESS_PARENT) != 0) {
- pm.addCrossProfileIntentFilter(filter, UserHandle.USER_OWNER, callingUserId,
- PackageManager.SET_BY_PROFILE_OWNER);
+ pm.addCrossProfileIntentFilter(filter, who.getPackageName(),
+ mContext.getUserId(), UserHandle.USER_OWNER, callingUserId, 0);
}
} catch (RemoteException re) {
// Shouldn't happen
@@ -3631,10 +3631,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
IPackageManager pm = AppGlobals.getPackageManager();
long id = Binder.clearCallingIdentity();
try {
- pm.clearCrossProfileIntentFilters(callingUserId);
+ pm.clearCrossProfileIntentFilters(callingUserId, who.getPackageName(),
+ callingUserId);
// If we want to support multiple managed profiles, we will have to only remove
// those that have callingUserId as their target.
- pm.clearCrossProfileIntentFilters(UserHandle.USER_OWNER);
+ pm.clearCrossProfileIntentFilters(UserHandle.USER_OWNER, who.getPackageName(),
+ callingUserId);
} catch (RemoteException re) {
// Shouldn't happen
} finally {