Moving CrossProfileIntentFilter property from UserTypeDetails to

UserProperties

Bug: 241532322
Test: atest CtsAppCloningDeviceTestCase
Test: atest com.android.server.pm.UserManagerTest
Test: atest UserManagerServiceUserTypeTest
Test: atest UserManagerServiceUserPropertiesTest
Test: atest CtsAppCloningHostTest:com.android.cts.appcloning.IntentRedirectionTest
Change-Id: I2d53af3877b60291012972abcd8019dad0d10358
This commit is contained in:
Sarup Dalwani
2022-11-15 17:08:40 +00:00
parent 29c944cd5a
commit 7c2f50d4ff
8 changed files with 137 additions and 43 deletions

View File

@@ -48,6 +48,8 @@ public final class UserProperties implements Parcelable {
private static final String ATTR_USE_PARENTS_CONTACTS = "useParentsContacts";
private static final String ATTR_UPDATE_CROSS_PROFILE_INTENT_FILTERS_ON_OTA =
"updateCrossProfileIntentFiltersOnOTA";
private static final String ATTR_CROSS_PROFILE_INTENT_FILTER_ACCESS_CONTROL =
"crossProfileIntentFilterAccessControl";
/** Index values of each property (to indicate whether they are present in this object). */
@IntDef(prefix = "INDEX_", value = {
@@ -56,7 +58,8 @@ public final class UserProperties implements Parcelable {
INDEX_SHOW_IN_SETTINGS,
INDEX_INHERIT_DEVICE_POLICY,
INDEX_USE_PARENTS_CONTACTS,
INDEX_UPDATE_CROSS_PROFILE_INTENT_FILTERS_ON_OTA
INDEX_UPDATE_CROSS_PROFILE_INTENT_FILTERS_ON_OTA,
INDEX_CROSS_PROFILE_INTENT_FILTER_ACCESS_CONTROL
})
@Retention(RetentionPolicy.SOURCE)
private @interface PropertyIndex {
@@ -67,6 +70,7 @@ public final class UserProperties implements Parcelable {
private static final int INDEX_INHERIT_DEVICE_POLICY = 3;
private static final int INDEX_USE_PARENTS_CONTACTS = 4;
private static final int INDEX_UPDATE_CROSS_PROFILE_INTENT_FILTERS_ON_OTA = 5;
private static final int INDEX_CROSS_PROFILE_INTENT_FILTER_ACCESS_CONTROL = 6;
/** A bit set, mapping each PropertyIndex to whether it is present (1) or absent (0). */
private long mPropertiesPresent = 0;
@@ -169,6 +173,51 @@ public final class UserProperties implements Parcelable {
*/
private final @Nullable UserProperties mDefaultProperties;
/**
* CrossProfileIntentFilterAccessControlLevel provides level of access for user to create/modify
* {@link CrossProfileIntentFilter}. Each level have value assigned, the higher the value
* implies higher restriction for creation/modification.
* CrossProfileIntentFilterAccessControlLevel allows us to protect against malicious changes in
* user's {@link CrossProfileIntentFilter}s, which might add/remove
* {@link CrossProfileIntentFilter} leading to unprecedented results.
*
* @hide
*/
@IntDef(prefix = {"CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_"}, value = {
CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_ALL,
CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_SYSTEM,
CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_SYSTEM_ADD_ONLY,
})
@Retention(RetentionPolicy.SOURCE)
public @interface CrossProfileIntentFilterAccessControlLevel {
}
/**
* CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_ALL signifies that irrespective of user we would
* allow access (addition/modification/removal) for CrossProfileIntentFilter.
* This is the default access control level.
*
* @hide
*/
public static final int CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_ALL = 0;
/**
* CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_SYSTEM signifies that only system/root user would
* be able to access (addition/modification/removal) CrossProfileIntentFilter.
*
* @hide
*/
public static final int CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_SYSTEM = 10;
/**
* CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_SYSTEM_ADD_ONLY signifies that only system/root
* user would be able to add CrossProfileIntentFilter but not modify/remove. Once added, it
* cannot be modified or removed.
*
* @hide
*/
public static final int CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_SYSTEM_ADD_ONLY = 20;
/**
* Creates a UserProperties (intended for the SystemServer) that stores a reference to the given
* default properties, which it uses for any property not subsequently set.
@@ -204,6 +253,8 @@ public final class UserProperties implements Parcelable {
setStartWithParent(orig.getStartWithParent());
setInheritDevicePolicy(orig.getInheritDevicePolicy());
setUpdateCrossProfileIntentFiltersOnOTA(orig.getUpdateCrossProfileIntentFiltersOnOTA());
setCrossProfileIntentFilterAccessControl(
orig.getCrossProfileIntentFilterAccessControl());
}
if (hasManagePermission) {
// Add items that require MANAGE_USERS or stronger.
@@ -387,6 +438,34 @@ public final class UserProperties implements Parcelable {
*/
private boolean mUpdateCrossProfileIntentFiltersOnOTA;
/**
* Returns the user's {@link CrossProfileIntentFilterAccessControlLevel}.
* @hide
*/
public @CrossProfileIntentFilterAccessControlLevel int
getCrossProfileIntentFilterAccessControl() {
if (isPresent(INDEX_CROSS_PROFILE_INTENT_FILTER_ACCESS_CONTROL)) {
return mCrossProfileIntentFilterAccessControl;
}
if (mDefaultProperties != null) {
return mDefaultProperties.mCrossProfileIntentFilterAccessControl;
}
throw new SecurityException("You don't have permission to query "
+ "crossProfileIntentFilterAccessControl");
}
/**
* Sets {@link CrossProfileIntentFilterAccessControlLevel} for the user.
* @param val access control for user
* @hide
*/
public void setCrossProfileIntentFilterAccessControl(
@CrossProfileIntentFilterAccessControlLevel int val) {
this.mCrossProfileIntentFilterAccessControl = val;
setPresent(INDEX_CROSS_PROFILE_INTENT_FILTER_ACCESS_CONTROL);
}
private @CrossProfileIntentFilterAccessControlLevel int mCrossProfileIntentFilterAccessControl;
@Override
public String toString() {
// Please print in increasing order of PropertyIndex.
@@ -399,6 +478,8 @@ public final class UserProperties implements Parcelable {
+ ", mUseParentsContacts=" + getUseParentsContacts()
+ ", mUpdateCrossProfileIntentFiltersOnOTA="
+ getUpdateCrossProfileIntentFiltersOnOTA()
+ ", mCrossProfileIntentFilterAccessControl="
+ getCrossProfileIntentFilterAccessControl()
+ "}";
}
@@ -417,6 +498,8 @@ public final class UserProperties implements Parcelable {
pw.println(prefix + " mUseParentsContacts=" + getUseParentsContacts());
pw.println(prefix + " mUpdateCrossProfileIntentFiltersOnOTA="
+ getUpdateCrossProfileIntentFiltersOnOTA());
pw.println(prefix + " mCrossProfileIntentFilterAccessControl="
+ getCrossProfileIntentFilterAccessControl());
}
/**
@@ -468,6 +551,9 @@ public final class UserProperties implements Parcelable {
case ATTR_UPDATE_CROSS_PROFILE_INTENT_FILTERS_ON_OTA:
setUpdateCrossProfileIntentFiltersOnOTA(parser.getAttributeBoolean(i));
break;
case ATTR_CROSS_PROFILE_INTENT_FILTER_ACCESS_CONTROL:
setCrossProfileIntentFilterAccessControl(parser.getAttributeInt(i));
break;
default:
Slog.w(LOG_TAG, "Skipping unknown property " + attributeName);
}
@@ -507,6 +593,10 @@ public final class UserProperties implements Parcelable {
ATTR_UPDATE_CROSS_PROFILE_INTENT_FILTERS_ON_OTA,
mUpdateCrossProfileIntentFiltersOnOTA);
}
if (isPresent(INDEX_CROSS_PROFILE_INTENT_FILTER_ACCESS_CONTROL)) {
serializer.attributeInt(null, ATTR_CROSS_PROFILE_INTENT_FILTER_ACCESS_CONTROL,
mCrossProfileIntentFilterAccessControl);
}
}
// For use only with an object that has already had any permission-lacking fields stripped out.
@@ -519,6 +609,7 @@ public final class UserProperties implements Parcelable {
dest.writeInt(mInheritDevicePolicy);
dest.writeBoolean(mUseParentsContacts);
dest.writeBoolean(mUpdateCrossProfileIntentFiltersOnOTA);
dest.writeInt(mCrossProfileIntentFilterAccessControl);
}
/**
@@ -535,6 +626,7 @@ public final class UserProperties implements Parcelable {
mInheritDevicePolicy = source.readInt();
mUseParentsContacts = source.readBoolean();
mUpdateCrossProfileIntentFiltersOnOTA = source.readBoolean();
mCrossProfileIntentFilterAccessControl = source.readInt();
}
@Override
@@ -565,6 +657,9 @@ public final class UserProperties implements Parcelable {
private @InheritDevicePolicy int mInheritDevicePolicy = INHERIT_DEVICE_POLICY_NO;
private boolean mUseParentsContacts = false;
private boolean mUpdateCrossProfileIntentFiltersOnOTA = false;
private @CrossProfileIntentFilterAccessControlLevel int
mCrossProfileIntentFilterAccessControl =
CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_ALL;
public Builder setShowInLauncher(@ShowInLauncher int showInLauncher) {
mShowInLauncher = showInLauncher;
@@ -601,6 +696,14 @@ public final class UserProperties implements Parcelable {
return this;
}
/** Sets the value for {@link #mCrossProfileIntentFilterAccessControl} */
public Builder setCrossProfileIntentFilterAccessControl(
@CrossProfileIntentFilterAccessControlLevel int
crossProfileIntentFilterAccessControl) {
mCrossProfileIntentFilterAccessControl = crossProfileIntentFilterAccessControl;
return this;
}
/** Builds a UserProperties object with *all* values populated. */
public UserProperties build() {
return new UserProperties(
@@ -609,7 +712,8 @@ public final class UserProperties implements Parcelable {
mShowInSettings,
mInheritDevicePolicy,
mUseParentsContacts,
mUpdateCrossProfileIntentFiltersOnOTA);
mUpdateCrossProfileIntentFiltersOnOTA,
mCrossProfileIntentFilterAccessControl);
}
} // end Builder
@@ -619,7 +723,8 @@ public final class UserProperties implements Parcelable {
boolean startWithParent,
@ShowInSettings int showInSettings,
@InheritDevicePolicy int inheritDevicePolicy,
boolean useParentsContacts, boolean updateCrossProfileIntentFiltersOnOTA) {
boolean useParentsContacts, boolean updateCrossProfileIntentFiltersOnOTA,
@CrossProfileIntentFilterAccessControlLevel int crossProfileIntentFilterAccessControl) {
mDefaultProperties = null;
setShowInLauncher(showInLauncher);
@@ -628,5 +733,6 @@ public final class UserProperties implements Parcelable {
setInheritDevicePolicy(inheritDevicePolicy);
setUseParentsContacts(useParentsContacts);
setUpdateCrossProfileIntentFiltersOnOTA(updateCrossProfileIntentFiltersOnOTA);
setCrossProfileIntentFilterAccessControl(crossProfileIntentFilterAccessControl);
}
}

View File

@@ -2170,9 +2170,9 @@ public class UserManagerService extends IUserManager.Stub {
*/
private @CrossProfileIntentFilter.AccessControlLevel int
getCrossProfileIntentFilterAccessControl(@UserIdInt int userId) {
final UserTypeDetails userTypeDetails = getUserTypeDetailsNoChecks(userId);
return userTypeDetails != null ? userTypeDetails.getCrossProfileIntentFilterAccessControl()
: CrossProfileIntentFilter.ACCESS_LEVEL_ALL;
final UserProperties userProperties = getUserPropertiesInternal(userId);
return userProperties != null ? userProperties.getCrossProfileIntentFilterAccessControl() :
CrossProfileIntentFilter.ACCESS_LEVEL_ALL;
}
/**

View File

@@ -164,14 +164,6 @@ public final class UserTypeDetails {
*/
private final boolean mIsCredentialSharableWithParent;
/**
* Denotes the default access control for {@link CrossProfileIntentFilter} of user profile.
*
* <p> Default value is {@link CrossProfileIntentFilter#ACCESS_LEVEL_ALL}
*/
private final @CrossProfileIntentFilter.AccessControlLevel int
mCrossProfileIntentFilterAccessControl;
/**
* The default {@link UserProperties} for the user type.
* <p> The uninitialized value of each property is implied by {@link UserProperties.Builder}.
@@ -190,7 +182,6 @@ public final class UserTypeDetails {
@Nullable List<DefaultCrossProfileIntentFilter> defaultCrossProfileIntentFilters,
boolean isMediaSharedWithParent,
boolean isCredentialSharableWithParent,
@CrossProfileIntentFilter.AccessControlLevel int accessControlLevel,
@NonNull UserProperties defaultUserProperties) {
this.mName = name;
this.mEnabled = enabled;
@@ -212,7 +203,6 @@ public final class UserTypeDetails {
this.mDarkThemeBadgeColors = darkThemeBadgeColors;
this.mIsMediaSharedWithParent = isMediaSharedWithParent;
this.mIsCredentialSharableWithParent = isCredentialSharableWithParent;
this.mCrossProfileIntentFilterAccessControl = accessControlLevel;
this.mDefaultUserProperties = defaultUserProperties;
}
@@ -334,15 +324,6 @@ public final class UserTypeDetails {
return mIsCredentialSharableWithParent;
}
/**
* Returning user's {@link CrossProfileIntentFilter.AccessControlLevel}. If not explicitly
* configured, default value is {@link CrossProfileIntentFilter#ACCESS_LEVEL_ALL}
* @return user's {@link CrossProfileIntentFilter.AccessControlLevel}
*/
public @CrossProfileIntentFilter.AccessControlLevel int
getCrossProfileIntentFilterAccessControl() {
return mCrossProfileIntentFilterAccessControl;
}
/**
* Returns the reference to the default {@link UserProperties} for this type of user.
@@ -458,8 +439,6 @@ public final class UserTypeDetails {
private @DrawableRes int mBadgeNoBackground = Resources.ID_NULL;
private boolean mIsMediaSharedWithParent = false;
private boolean mIsCredentialSharableWithParent = false;
private @CrossProfileIntentFilter.AccessControlLevel int
mCrossProfileIntentFilterAccessControl = CrossProfileIntentFilter.ACCESS_LEVEL_ALL;
// Default UserProperties cannot be null but for efficiency we don't initialize it now.
// If it isn't set explicitly, {@link UserProperties.Builder#build()} will be used.
private @Nullable UserProperties mDefaultUserProperties = null;
@@ -562,16 +541,6 @@ public final class UserTypeDetails {
return this;
}
/**
* Sets {@link CrossProfileIntentFilter.AccessControlLevel} for the user.
* @param accessControlLevel default access control for user
*/
public Builder setCrossProfileIntentFilterAccessControl(
@CrossProfileIntentFilter.AccessControlLevel int accessControlLevel) {
mCrossProfileIntentFilterAccessControl = accessControlLevel;
return this;
}
/**
* Sets shared media property for the user.
* @param isCredentialSharableWithParent the value to be set, true or false
@@ -642,7 +611,6 @@ public final class UserTypeDetails {
mDefaultCrossProfileIntentFilters,
mIsMediaSharedWithParent,
mIsCredentialSharableWithParent,
mCrossProfileIntentFilterAccessControl,
getDefaultUserProperties());
}

View File

@@ -123,8 +123,6 @@ public final class UserTypeFactory {
.setLabel(0)
.setDefaultRestrictions(null)
.setIsMediaSharedWithParent(true)
.setCrossProfileIntentFilterAccessControl(
CrossProfileIntentFilter.ACCESS_LEVEL_SYSTEM)
.setIsCredentialSharableWithParent(true)
.setDefaultCrossProfileIntentFilters(getDefaultCloneCrossProfileIntentFilter())
.setDefaultUserProperties(new UserProperties.Builder()
@@ -133,7 +131,9 @@ public final class UserTypeFactory {
.setShowInSettings(UserProperties.SHOW_IN_SETTINGS_WITH_PARENT)
.setInheritDevicePolicy(UserProperties.INHERIT_DEVICE_POLICY_FROM_PARENT)
.setUseParentsContacts(true)
.setUpdateCrossProfileIntentFiltersOnOTA(true));
.setUpdateCrossProfileIntentFiltersOnOTA(true)
.setCrossProfileIntentFilterAccessControl(
UserProperties.CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_SYSTEM));
}
/**

View File

@@ -34,6 +34,7 @@
showInLauncher='2020'
startWithParent='false'
useParentsContacts='false'
crossProfileIntentFilterAccessControl='20'
/>
</profile-type>
<profile-type name='custom.test.1' max-allowed-per-parent='14' />

View File

@@ -62,12 +62,14 @@ public class UserManagerServiceUserPropertiesTest {
.setShowInSettings(45)
.setInheritDevicePolicy(67)
.setUseParentsContacts(false)
.setCrossProfileIntentFilterAccessControl(10)
.build();
final UserProperties actualProps = new UserProperties(defaultProps);
actualProps.setShowInLauncher(14);
actualProps.setShowInSettings(32);
actualProps.setInheritDevicePolicy(51);
actualProps.setUseParentsContacts(true);
actualProps.setCrossProfileIntentFilterAccessControl(20);
// Write the properties to xml.
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -150,6 +152,8 @@ public class UserManagerServiceUserPropertiesTest {
assertEqualGetterOrThrows(orig::getStartWithParent, copy::getStartWithParent, exposeAll);
assertEqualGetterOrThrows(orig::getInheritDevicePolicy,
copy::getInheritDevicePolicy, exposeAll);
assertEqualGetterOrThrows(orig::getCrossProfileIntentFilterAccessControl,
copy::getCrossProfileIntentFilterAccessControl, exposeAll);
// Items requiring hasManagePermission - put them here using hasManagePermission.
assertEqualGetterOrThrows(orig::getShowInSettings, copy::getShowInSettings,
@@ -203,5 +207,7 @@ public class UserManagerServiceUserPropertiesTest {
assertThat(expected.getShowInSettings()).isEqualTo(actual.getShowInSettings());
assertThat(expected.getInheritDevicePolicy()).isEqualTo(actual.getInheritDevicePolicy());
assertThat(expected.getUseParentsContacts()).isEqualTo(actual.getUseParentsContacts());
assertThat(expected.getCrossProfileIntentFilterAccessControl())
.isEqualTo(actual.getCrossProfileIntentFilterAccessControl());
}
}

View File

@@ -84,7 +84,8 @@ public class UserManagerServiceUserTypeTest {
/* letsPersonalDataIntoProfile= */false).build());
final UserProperties.Builder userProps = new UserProperties.Builder()
.setShowInLauncher(17)
.setUseParentsContacts(true);
.setUseParentsContacts(true)
.setCrossProfileIntentFilterAccessControl(10);
final UserTypeDetails type = new UserTypeDetails.Builder()
.setName("a.name")
.setEnabled(1)
@@ -142,6 +143,8 @@ public class UserManagerServiceUserTypeTest {
assertEquals(17, type.getDefaultUserPropertiesReference().getShowInLauncher());
assertTrue(type.getDefaultUserPropertiesReference().getUseParentsContacts());
assertEquals(10, type.getDefaultUserPropertiesReference()
.getCrossProfileIntentFilterAccessControl());
assertEquals(23, type.getBadgeLabel(0));
assertEquals(24, type.getBadgeLabel(1));
@@ -185,6 +188,8 @@ public class UserManagerServiceUserTypeTest {
assertNotNull(props);
assertFalse(props.getStartWithParent());
assertFalse(props.getUseParentsContacts());
assertEquals(UserProperties.CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_ALL,
props.getCrossProfileIntentFilterAccessControl());
assertEquals(UserProperties.SHOW_IN_LAUNCHER_WITH_PARENT, props.getShowInLauncher());
assertFalse(type.hasBadge());
@@ -267,7 +272,8 @@ public class UserManagerServiceUserTypeTest {
final UserProperties.Builder props = new UserProperties.Builder()
.setShowInLauncher(19)
.setStartWithParent(true)
.setUseParentsContacts(true);
.setUseParentsContacts(true)
.setCrossProfileIntentFilterAccessControl(10);
final ArrayMap<String, UserTypeDetails.Builder> builders = new ArrayMap<>();
builders.put(userTypeAosp1, new UserTypeDetails.Builder()
.setName(userTypeAosp1)
@@ -293,6 +299,8 @@ public class UserManagerServiceUserTypeTest {
assertEquals(Resources.ID_NULL, aospType.getIconBadge());
assertTrue(UserRestrictionsUtils.areEqual(restrictions, aospType.getDefaultRestrictions()));
assertEquals(19, aospType.getDefaultUserPropertiesReference().getShowInLauncher());
assertEquals(10, aospType.getDefaultUserPropertiesReference()
.getCrossProfileIntentFilterAccessControl());
assertTrue(aospType.getDefaultUserPropertiesReference().getStartWithParent());
assertTrue(aospType.getDefaultUserPropertiesReference()
.getUseParentsContacts());
@@ -325,6 +333,8 @@ public class UserManagerServiceUserTypeTest {
makeRestrictionsBundle("no_remove_user", "no_bluetooth"),
aospType.getDefaultRestrictions()));
assertEquals(2020, aospType.getDefaultUserPropertiesReference().getShowInLauncher());
assertEquals(20, aospType.getDefaultUserPropertiesReference()
.getCrossProfileIntentFilterAccessControl());
assertFalse(aospType.getDefaultUserPropertiesReference().getStartWithParent());
assertFalse(aospType.getDefaultUserPropertiesReference()
.getUseParentsContacts());

View File

@@ -205,6 +205,8 @@ public final class UserManagerTest {
assertThat(typeProps.getShowInLauncher())
.isEqualTo(cloneUserProperties.getShowInLauncher());
assertThrows(SecurityException.class, cloneUserProperties::getStartWithParent);
assertThrows(SecurityException.class,
cloneUserProperties::getCrossProfileIntentFilterAccessControl);
// Verify clone user parent
assertThat(mUserManager.getProfileParent(primaryUserId)).isNull();
@@ -620,6 +622,7 @@ public final class UserManagerTest {
assertThat(userProps.getShowInLauncher()).isEqualTo(typeProps.getShowInLauncher());
assertThat(userProps.getShowInSettings()).isEqualTo(typeProps.getShowInSettings());
assertFalse(userProps.getUseParentsContacts());
assertThrows(SecurityException.class, userProps::getCrossProfileIntentFilterAccessControl);
assertThrows(SecurityException.class, userProps::getStartWithParent);
assertThrows(SecurityException.class, userProps::getInheritDevicePolicy);
}