diff options
13 files changed, 224 insertions, 96 deletions
diff --git a/core/java/android/app/admin/AccountTypePolicyKey.java b/core/java/android/app/admin/AccountTypePolicyKey.java index 9e376a7e2bee..d81eb20512a2 100644 --- a/core/java/android/app/admin/AccountTypePolicyKey.java +++ b/core/java/android/app/admin/AccountTypePolicyKey.java @@ -19,6 +19,7 @@ package android.app.admin; import static android.app.admin.PolicyUpdateReceiver.EXTRA_ACCOUNT_TYPE; import static android.app.admin.PolicyUpdateReceiver.EXTRA_POLICY_BUNDLE_KEY; import static android.app.admin.PolicyUpdateReceiver.EXTRA_POLICY_KEY; +import static android.app.admin.flags.Flags.devicePolicySizeTrackingEnabled; import android.annotation.NonNull; import android.annotation.Nullable; @@ -53,6 +54,9 @@ public final class AccountTypePolicyKey extends PolicyKey { @TestApi public AccountTypePolicyKey(@NonNull String key, @NonNull String accountType) { super(key); + if (devicePolicySizeTrackingEnabled()) { + PolicySizeVerifier.enforceMaxStringLength(accountType, "accountType"); + } mAccountType = Objects.requireNonNull((accountType)); } diff --git a/core/java/android/app/admin/BundlePolicyValue.java b/core/java/android/app/admin/BundlePolicyValue.java index f9653a4e85b0..cc5e75fac0ea 100644 --- a/core/java/android/app/admin/BundlePolicyValue.java +++ b/core/java/android/app/admin/BundlePolicyValue.java @@ -16,6 +16,8 @@ package android.app.admin; +import static android.app.admin.flags.Flags.devicePolicySizeTrackingEnabled; + import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Bundle; @@ -30,6 +32,9 @@ public final class BundlePolicyValue extends PolicyValue<Bundle> { public BundlePolicyValue(Bundle value) { super(value); + if (devicePolicySizeTrackingEnabled()) { + PolicySizeVerifier.enforceMaxParcelableFieldsLength(value); + } } private BundlePolicyValue(Parcel source) { diff --git a/core/java/android/app/admin/ComponentNamePolicyValue.java b/core/java/android/app/admin/ComponentNamePolicyValue.java index 635e5826e0c5..4d36195613ad 100644 --- a/core/java/android/app/admin/ComponentNamePolicyValue.java +++ b/core/java/android/app/admin/ComponentNamePolicyValue.java @@ -16,6 +16,8 @@ package android.app.admin; +import static android.app.admin.flags.Flags.devicePolicySizeTrackingEnabled; + import android.annotation.NonNull; import android.annotation.Nullable; import android.content.ComponentName; @@ -30,6 +32,9 @@ public final class ComponentNamePolicyValue extends PolicyValue<ComponentName> { public ComponentNamePolicyValue(@NonNull ComponentName value) { super(value); + if (devicePolicySizeTrackingEnabled()) { + PolicySizeVerifier.enforceMaxComponentNameLength(value); + } } private ComponentNamePolicyValue(Parcel source) { diff --git a/core/java/android/app/admin/IntentFilterPolicyKey.java b/core/java/android/app/admin/IntentFilterPolicyKey.java index 7526a7b2c934..de7ff9f0ad0f 100644 --- a/core/java/android/app/admin/IntentFilterPolicyKey.java +++ b/core/java/android/app/admin/IntentFilterPolicyKey.java @@ -19,6 +19,7 @@ package android.app.admin; import static android.app.admin.PolicyUpdateReceiver.EXTRA_INTENT_FILTER; import static android.app.admin.PolicyUpdateReceiver.EXTRA_POLICY_BUNDLE_KEY; import static android.app.admin.PolicyUpdateReceiver.EXTRA_POLICY_KEY; +import static android.app.admin.flags.Flags.devicePolicySizeTrackingEnabled; import android.annotation.NonNull; import android.annotation.Nullable; @@ -59,6 +60,9 @@ public final class IntentFilterPolicyKey extends PolicyKey { @TestApi public IntentFilterPolicyKey(@NonNull String identifier, @NonNull IntentFilter filter) { super(identifier); + if (devicePolicySizeTrackingEnabled()) { + PolicySizeVerifier.enforceMaxParcelableFieldsLength(filter); + } mFilter = Objects.requireNonNull(filter); } diff --git a/core/java/android/app/admin/LockTaskPolicy.java b/core/java/android/app/admin/LockTaskPolicy.java index b671d5793803..9d6ce243a19b 100644 --- a/core/java/android/app/admin/LockTaskPolicy.java +++ b/core/java/android/app/admin/LockTaskPolicy.java @@ -16,6 +16,8 @@ package android.app.admin; +import static android.app.admin.flags.Flags.devicePolicySizeTrackingEnabled; + import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; @@ -75,7 +77,7 @@ public final class LockTaskPolicy extends PolicyValue<LockTaskPolicy> { */ public LockTaskPolicy(@Nullable Set<String> packages) { if (packages != null) { - mPackages.addAll(packages); + setPackagesInternal(packages); } setValue(this); } @@ -93,7 +95,7 @@ public final class LockTaskPolicy extends PolicyValue<LockTaskPolicy> { */ public LockTaskPolicy(@Nullable Set<String> packages, int flags) { if (packages != null) { - mPackages.addAll(packages); + setPackagesInternal(packages); } mFlags = flags; setValue(this); @@ -123,7 +125,7 @@ public final class LockTaskPolicy extends PolicyValue<LockTaskPolicy> { */ public void setPackages(@NonNull Set<String> packages) { Objects.requireNonNull(packages); - mPackages = new HashSet<>(packages); + setPackagesInternal(packages); } /** @@ -133,6 +135,15 @@ public final class LockTaskPolicy extends PolicyValue<LockTaskPolicy> { mFlags = flags; } + private void setPackagesInternal(Set<String> packages) { + if (devicePolicySizeTrackingEnabled()) { + for (String p : packages) { + PolicySizeVerifier.enforceMaxPackageNameLength(p); + } + } + mPackages = new HashSet<>(packages); + } + @Override public boolean equals(@Nullable Object o) { if (this == o) return true; diff --git a/core/java/android/app/admin/PackagePermissionPolicyKey.java b/core/java/android/app/admin/PackagePermissionPolicyKey.java index 7fd514cebd7c..2241fddb7320 100644 --- a/core/java/android/app/admin/PackagePermissionPolicyKey.java +++ b/core/java/android/app/admin/PackagePermissionPolicyKey.java @@ -20,6 +20,7 @@ import static android.app.admin.PolicyUpdateReceiver.EXTRA_PACKAGE_NAME; import static android.app.admin.PolicyUpdateReceiver.EXTRA_PERMISSION_NAME; import static android.app.admin.PolicyUpdateReceiver.EXTRA_POLICY_BUNDLE_KEY; import static android.app.admin.PolicyUpdateReceiver.EXTRA_POLICY_KEY; +import static android.app.admin.flags.Flags.devicePolicySizeTrackingEnabled; import android.annotation.NonNull; import android.annotation.Nullable; @@ -58,6 +59,10 @@ public final class PackagePermissionPolicyKey extends PolicyKey { public PackagePermissionPolicyKey(@NonNull String identifier, @NonNull String packageName, @NonNull String permissionName) { super(identifier); + if (devicePolicySizeTrackingEnabled()) { + PolicySizeVerifier.enforceMaxPackageNameLength(packageName); + PolicySizeVerifier.enforceMaxStringLength(permissionName, "permissionName"); + } mPackageName = Objects.requireNonNull((packageName)); mPermissionName = Objects.requireNonNull((permissionName)); } diff --git a/core/java/android/app/admin/PackagePolicyKey.java b/core/java/android/app/admin/PackagePolicyKey.java index 2ab00bc3146c..2ea17a18f6a6 100644 --- a/core/java/android/app/admin/PackagePolicyKey.java +++ b/core/java/android/app/admin/PackagePolicyKey.java @@ -19,6 +19,7 @@ package android.app.admin; import static android.app.admin.PolicyUpdateReceiver.EXTRA_PACKAGE_NAME; import static android.app.admin.PolicyUpdateReceiver.EXTRA_POLICY_BUNDLE_KEY; import static android.app.admin.PolicyUpdateReceiver.EXTRA_POLICY_KEY; +import static android.app.admin.flags.Flags.devicePolicySizeTrackingEnabled; import android.annotation.NonNull; import android.annotation.Nullable; @@ -54,6 +55,9 @@ public final class PackagePolicyKey extends PolicyKey { @TestApi public PackagePolicyKey(@NonNull String key, @NonNull String packageName) { super(key); + if (devicePolicySizeTrackingEnabled()) { + PolicySizeVerifier.enforceMaxPackageNameLength(packageName); + } mPackageName = Objects.requireNonNull((packageName)); } diff --git a/core/java/android/app/admin/PolicySizeVerifier.java b/core/java/android/app/admin/PolicySizeVerifier.java new file mode 100644 index 000000000000..d5e8ea4525f3 --- /dev/null +++ b/core/java/android/app/admin/PolicySizeVerifier.java @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.app.admin; + +import android.content.ComponentName; +import android.os.Parcelable; +import android.os.PersistableBundle; + +import com.android.internal.util.Preconditions; + +import java.lang.reflect.Field; +import java.util.ArrayDeque; +import java.util.Queue; + +/** + * Utility class containing methods to verify the max allowed size of certain policy types. + * + * @hide + */ +public class PolicySizeVerifier { + + // Binary XML serializer doesn't support longer strings + public static final int MAX_POLICY_STRING_LENGTH = 65535; + // FrameworkParsingPackageUtils#MAX_FILE_NAME_SIZE, Android packages are used in dir names. + public static final int MAX_PACKAGE_NAME_LENGTH = 223; + + public static final int MAX_PROFILE_NAME_LENGTH = 200; + public static final int MAX_LONG_SUPPORT_MESSAGE_LENGTH = 20000; + public static final int MAX_SHORT_SUPPORT_MESSAGE_LENGTH = 200; + public static final int MAX_ORG_NAME_LENGTH = 200; + + /** + * Throw if string argument is too long to be serialized. + */ + public static void enforceMaxStringLength(String str, String argName) { + Preconditions.checkArgument( + str.length() <= MAX_POLICY_STRING_LENGTH, argName + " loo long"); + } + + /** + * Throw if package name exceeds max size allowed by the system. + */ + public static void enforceMaxPackageNameLength(String pkg) { + Preconditions.checkArgument( + pkg.length() <= MAX_PACKAGE_NAME_LENGTH, "Package name too long"); + } + + /** + * Throw if persistable bundle contains any string that's too long to be serialized. + */ + public static void enforceMaxStringLength(PersistableBundle bundle, String argName) { + // Persistable bundles can have other persistable bundles as values, traverse with a queue. + Queue<PersistableBundle> queue = new ArrayDeque<>(); + queue.add(bundle); + while (!queue.isEmpty()) { + PersistableBundle current = queue.remove(); + for (String key : current.keySet()) { + enforceMaxStringLength(key, "key in " + argName); + Object value = current.get(key); + if (value instanceof String) { + enforceMaxStringLength((String) value, "string value in " + argName); + } else if (value instanceof String[]) { + for (String str : (String[]) value) { + enforceMaxStringLength(str, "string value in " + argName); + } + } else if (value instanceof PersistableBundle) { + queue.add((PersistableBundle) value); + } + } + } + } + + /** + * Throw if Parcelable contains any string that's too long to be serialized. + */ + public static void enforceMaxParcelableFieldsLength(Parcelable parcelable) { + Class<?> clazz = parcelable.getClass(); + + Field[] fields = clazz.getDeclaredFields(); + for (Field field : fields) { + field.setAccessible(true); + try { + Object value = field.get(parcelable); + if (value instanceof String) { + String stringValue = (String) value; + enforceMaxStringLength(stringValue, field.getName()); + } + + if (value instanceof Parcelable) { + enforceMaxParcelableFieldsLength((Parcelable) value); + } + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + } + + /** + * Throw if ComponentName contains any string that's too long to be serialized. + */ + public static void enforceMaxComponentNameLength(ComponentName componentName) { + enforceMaxPackageNameLength(componentName.getPackageName()); + enforceMaxStringLength(componentName.flattenToString(), "componentName"); + } + + /** + * Truncates char sequence to maximum length, nulls are ignored. + */ + public static CharSequence truncateIfLonger(CharSequence input, int maxLength) { + return input == null || input.length() <= maxLength + ? input + : input.subSequence(0, maxLength); + } +} diff --git a/core/java/android/app/admin/StringPolicyValue.java b/core/java/android/app/admin/StringPolicyValue.java index 14b6dab2899e..f4d4adcfcedb 100644 --- a/core/java/android/app/admin/StringPolicyValue.java +++ b/core/java/android/app/admin/StringPolicyValue.java @@ -16,6 +16,8 @@ package android.app.admin; +import static android.app.admin.flags.Flags.devicePolicySizeTrackingEnabled; + import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcel; @@ -29,6 +31,9 @@ public final class StringPolicyValue extends PolicyValue<String> { public StringPolicyValue(@NonNull String value) { super(value); + if (devicePolicySizeTrackingEnabled()) { + PolicySizeVerifier.enforceMaxStringLength(value, "policyValue"); + } } private StringPolicyValue(Parcel source) { diff --git a/core/java/android/app/admin/StringSetPolicyValue.java b/core/java/android/app/admin/StringSetPolicyValue.java index cbfc60464467..82fe761a414f 100644 --- a/core/java/android/app/admin/StringSetPolicyValue.java +++ b/core/java/android/app/admin/StringSetPolicyValue.java @@ -16,6 +16,8 @@ package android.app.admin; +import static android.app.admin.flags.Flags.devicePolicySizeTrackingEnabled; + import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcel; @@ -31,6 +33,11 @@ public final class StringSetPolicyValue extends PolicyValue<Set<String>> { public StringSetPolicyValue(@NonNull Set<String> value) { super(value); + if (devicePolicySizeTrackingEnabled()) { + for (String str : value) { + PolicySizeVerifier.enforceMaxStringLength(str, "policyValue"); + } + } } public StringSetPolicyValue(Parcel source) { diff --git a/core/java/android/app/admin/UserRestrictionPolicyKey.java b/core/java/android/app/admin/UserRestrictionPolicyKey.java index aeb238041605..d69a5f08ce2e 100644 --- a/core/java/android/app/admin/UserRestrictionPolicyKey.java +++ b/core/java/android/app/admin/UserRestrictionPolicyKey.java @@ -17,6 +17,7 @@ package android.app.admin; import static android.app.admin.PolicyUpdateReceiver.EXTRA_POLICY_KEY; +import static android.app.admin.flags.Flags.devicePolicySizeTrackingEnabled; import android.annotation.NonNull; import android.annotation.SystemApi; @@ -44,6 +45,9 @@ public final class UserRestrictionPolicyKey extends PolicyKey { @TestApi public UserRestrictionPolicyKey(@NonNull String identifier, @NonNull String restriction) { super(identifier); + if (devicePolicySizeTrackingEnabled()) { + PolicySizeVerifier.enforceMaxStringLength(restriction, "restriction"); + } mRestriction = Objects.requireNonNull(restriction); } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java index 14dc0ebb8ad8..105dc880c9a7 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java @@ -126,7 +126,6 @@ final class DevicePolicyEngine { //TODO(b/295504706) : Speak to security team to decide what to set Policy_Size_Limit private static final int POLICY_SIZE_LIMIT = 99999; - private final DeviceAdminServiceController mDeviceAdminServiceController; DevicePolicyEngine( @@ -1385,7 +1384,6 @@ final class DevicePolicyEngine { } } - /** * Removes all local and global policies set by that admin. */ @@ -1546,10 +1544,17 @@ final class DevicePolicyEngine { return false; } + @NonNull + private Set<EnforcingAdmin> getEnforcingAdminsOnUser(int userId) { + synchronized (mLock) { + return mEnforcingAdmins.contains(userId) + ? mEnforcingAdmins.get(userId) : Collections.emptySet(); + } + } + /** * Calculate the size of a policy in bytes */ - private static <V> int sizeOf(PolicyValue<V> value) { try { Parcel parcel = Parcel.obtain(); @@ -1576,23 +1581,25 @@ final class DevicePolicyEngine { * * If the policy size limit is reached then send policy result to admin and return false. */ - private <V> boolean handleAdminPolicySizeLimit(PolicyState<V> policyState, EnforcingAdmin admin, - PolicyValue<V> value, PolicyDefinition policyDefinition, int userId) { - int currentSize = 0; + PolicyValue<V> value, PolicyDefinition<V> policyDefinition, int userId) { + int currentAdminPoliciesSize = 0; + int existingPolicySize = 0; if (mAdminPolicySize.contains(admin.getUserId()) && mAdminPolicySize.get( admin.getUserId()).containsKey(admin)) { - currentSize = mAdminPolicySize.get(admin.getUserId()).get(admin); + currentAdminPoliciesSize = mAdminPolicySize.get(admin.getUserId()).get(admin); } if (policyState.getPoliciesSetByAdmins().containsKey(admin)) { - currentSize -= sizeOf(policyState.getPoliciesSetByAdmins().get(admin)); + existingPolicySize = sizeOf(policyState.getPoliciesSetByAdmins().get(admin)); } int policySize = sizeOf(value); - if (currentSize + policySize < POLICY_SIZE_LIMIT) { - increasePolicySizeForAdmin(admin, policySize); + if (currentAdminPoliciesSize + policySize - existingPolicySize < POLICY_SIZE_LIMIT) { + increasePolicySizeForAdmin( + admin, /* policySizeDiff = */ policySize - existingPolicySize); return true; } else { + Log.w(TAG, "Admin " + admin + "reached max allowed storage limit."); sendPolicyResultToAdmin( admin, policyDefinition, @@ -1606,8 +1613,7 @@ final class DevicePolicyEngine { * Increase the int in mAdminPolicySize representing the size of the sum of all * active policies for that admin. */ - - private <V> void increasePolicySizeForAdmin(EnforcingAdmin admin, int policySize) { + private <V> void increasePolicySizeForAdmin(EnforcingAdmin admin, int policySizeDiff) { if (!mAdminPolicySize.contains(admin.getUserId())) { mAdminPolicySize.put(admin.getUserId(), new HashMap<>()); } @@ -1615,14 +1621,13 @@ final class DevicePolicyEngine { mAdminPolicySize.get(admin.getUserId()).put(admin, /* size= */ 0); } mAdminPolicySize.get(admin.getUserId()).put(admin, - mAdminPolicySize.get(admin.getUserId()).get(admin) + policySize); + mAdminPolicySize.get(admin.getUserId()).get(admin) + policySizeDiff); } /** * Decrease the int in mAdminPolicySize representing the size of the sum of all * active policies for that admin. */ - private <V> void decreasePolicySizeForAdmin(PolicyState<V> policyState, EnforcingAdmin admin) { if (policyState.getPoliciesSetByAdmins().containsKey(admin)) { mAdminPolicySize.get(admin.getUserId()).put(admin, @@ -1637,14 +1642,6 @@ final class DevicePolicyEngine { } } - @NonNull - private Set<EnforcingAdmin> getEnforcingAdminsOnUser(int userId) { - synchronized (mLock) { - return mEnforcingAdmins.contains(userId) - ? mEnforcingAdmins.get(userId) : Collections.emptySet(); - } - } - public void dump(IndentingPrintWriter pw) { synchronized (mLock) { pw.println("Local Policies: "); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index fad68ab4cea4..51eee64d12f2 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -220,6 +220,10 @@ import static android.app.admin.DevicePolicyResources.Strings.Core.WORK_PROFILE_ import static android.app.admin.DevicePolicyResources.Strings.Core.WORK_PROFILE_TELEPHONY_PAUSED_BODY; import static android.app.admin.DevicePolicyResources.Strings.Core.WORK_PROFILE_TELEPHONY_PAUSED_TITLE; import static android.app.admin.DevicePolicyResources.Strings.Core.WORK_PROFILE_TELEPHONY_PAUSED_TURN_ON_BUTTON; +import static android.app.admin.PolicySizeVerifier.MAX_LONG_SUPPORT_MESSAGE_LENGTH; +import static android.app.admin.PolicySizeVerifier.MAX_ORG_NAME_LENGTH; +import static android.app.admin.PolicySizeVerifier.MAX_PROFILE_NAME_LENGTH; +import static android.app.admin.PolicySizeVerifier.MAX_SHORT_SUPPORT_MESSAGE_LENGTH; import static android.app.admin.ProvisioningException.ERROR_ADMIN_PACKAGE_INSTALLATION_FAILED; import static android.app.admin.ProvisioningException.ERROR_PRE_CONDITION_FAILED; import static android.app.admin.ProvisioningException.ERROR_PROFILE_CREATION_FAILED; @@ -228,6 +232,7 @@ import static android.app.admin.ProvisioningException.ERROR_SETTING_PROFILE_OWNE import static android.app.admin.ProvisioningException.ERROR_SET_DEVICE_OWNER_FAILED; import static android.app.admin.ProvisioningException.ERROR_STARTING_PROFILE_FAILED; import static android.app.admin.flags.Flags.backupServiceSecurityLogEventEnabled; +import static android.app.admin.flags.Flags.devicePolicySizeTrackingEnabled; import static android.app.admin.flags.Flags.dumpsysPolicyEngineMigrationEnabled; import static android.app.admin.flags.Flags.headlessDeviceOwnerSingleUserEnabled; import static android.app.admin.flags.Flags.policyEngineMigrationV2Enabled; @@ -332,6 +337,7 @@ import android.app.admin.ParcelableResource; import android.app.admin.PasswordMetrics; import android.app.admin.PasswordPolicy; import android.app.admin.PolicyKey; +import android.app.admin.PolicySizeVerifier; import android.app.admin.PolicyValue; import android.app.admin.PreferentialNetworkServiceConfig; import android.app.admin.SecurityLog; @@ -537,7 +543,6 @@ import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.text.DateFormat; import java.time.LocalDate; -import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -550,7 +555,6 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Objects; -import java.util.Queue; import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; @@ -588,16 +592,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private static final int REQUEST_PROFILE_OFF_DEADLINE = 5572; - // Binary XML serializer doesn't support longer strings - private static final int MAX_POLICY_STRING_LENGTH = 65535; - // FrameworkParsingPackageUtils#MAX_FILE_NAME_SIZE, Android packages are used in dir names. - private static final int MAX_PACKAGE_NAME_LENGTH = 223; - - private static final int MAX_PROFILE_NAME_LENGTH = 200; - private static final int MAX_LONG_SUPPORT_MESSAGE_LENGTH = 20000; - private static final int MAX_SHORT_SUPPORT_MESSAGE_LENGTH = 200; - private static final int MAX_ORG_NAME_LENGTH = 200; - private static final long MS_PER_DAY = TimeUnit.DAYS.toMillis(1); private static final long EXPIRATION_GRACE_PERIOD_MS = 5 * MS_PER_DAY; // 5 days, in ms @@ -11537,11 +11531,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { Objects.requireNonNull(agent, "agent is null"); - enforceMaxPackageNameLength(agent.getPackageName()); + PolicySizeVerifier.enforceMaxPackageNameLength(agent.getPackageName()); final String agentAsString = agent.flattenToString(); - enforceMaxStringLength(agentAsString, "agent name"); + PolicySizeVerifier.enforceMaxStringLength(agentAsString, "agent name"); if (args != null) { - enforceMaxStringLength(args, "args"); + PolicySizeVerifier.enforceMaxStringLength(args, "args"); } int userHandle = mInjector.userHandleGetCallingUserId(); @@ -11833,7 +11827,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (packageList != null) { for (String pkg : packageList) { - enforceMaxPackageNameLength(pkg); + PolicySizeVerifier.enforceMaxPackageNameLength(pkg); } int userId = caller.getUserId(); @@ -12005,7 +11999,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (packageList != null) { for (String pkg : packageList) { - enforceMaxPackageNameLength(pkg); + PolicySizeVerifier.enforceMaxPackageNameLength(pkg); } List<InputMethodInfo> enabledImes = mInjector.binderWithCleanCallingIdentity(() -> @@ -13710,7 +13704,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return; } - enforceMaxStringLength(accountType, "account type"); + if (!devicePolicySizeTrackingEnabled()) { + PolicySizeVerifier.enforceMaxStringLength(accountType, "account type"); + } CallerIdentity caller = getCallerIdentity(who, callerPackageName); synchronized (getLockObject()) { @@ -14323,7 +14319,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { throws SecurityException { Objects.requireNonNull(packages, "packages is null"); for (String pkg : packages) { - enforceMaxPackageNameLength(pkg); + PolicySizeVerifier.enforceMaxPackageNameLength(pkg); } CallerIdentity caller = getCallerIdentity(who, callerPackageName); @@ -16932,7 +16928,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { CallerIdentity caller; ActiveAdmin admin; - message = truncateIfLonger(message, MAX_SHORT_SUPPORT_MESSAGE_LENGTH); + message = PolicySizeVerifier.truncateIfLonger(message, MAX_SHORT_SUPPORT_MESSAGE_LENGTH); if (isPermissionCheckFlagEnabled()) { caller = getCallerIdentity(who, callerPackageName); @@ -16995,7 +16991,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return; } - message = truncateIfLonger(message, MAX_LONG_SUPPORT_MESSAGE_LENGTH); + message = PolicySizeVerifier.truncateIfLonger(message, MAX_LONG_SUPPORT_MESSAGE_LENGTH); Objects.requireNonNull(who, "ComponentName is null"); final CallerIdentity caller = getCallerIdentity(who); @@ -17161,7 +17157,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); } - text = truncateIfLonger(text, MAX_ORG_NAME_LENGTH); + text = PolicySizeVerifier.truncateIfLonger(text, MAX_ORG_NAME_LENGTH); synchronized (getLockObject()) { if (!isPermissionCheckFlagEnabled()) { @@ -17447,7 +17443,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } for (String id : ids) { Preconditions.checkArgument(!TextUtils.isEmpty(id), "ids must not have empty string"); - enforceMaxStringLength(id, "affiliation id"); + PolicySizeVerifier.enforceMaxStringLength(id, "affiliation id"); } final Set<String> affiliationIds = new ArraySet<>(ids); @@ -18994,7 +18990,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { Preconditions.checkArgument(!admin.getPackageName().equals(target.getPackageName()), "Provided administrator and target have the same package name."); if (bundle != null) { - enforceMaxStringLength(bundle, "bundle"); + PolicySizeVerifier.enforceMaxStringLength(bundle, "bundle"); } final CallerIdentity caller = getCallerIdentity(admin); @@ -23875,53 +23871,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { }); } - /** - * Truncates char sequence to maximum length, nulls are ignored. - */ - private static CharSequence truncateIfLonger(CharSequence input, int maxLength) { - return input == null || input.length() <= maxLength - ? input - : input.subSequence(0, maxLength); - } - - /** - * Throw if string argument is too long to be serialized. - */ - private static void enforceMaxStringLength(String str, String argName) { - Preconditions.checkArgument( - str.length() <= MAX_POLICY_STRING_LENGTH, argName + " loo long"); - } - - private static void enforceMaxPackageNameLength(String pkg) { - Preconditions.checkArgument( - pkg.length() <= MAX_PACKAGE_NAME_LENGTH, "Package name too long"); - } - - /** - * Throw if persistable bundle contains any string that we can't serialize. - */ - private static void enforceMaxStringLength(PersistableBundle bundle, String argName) { - // Persistable bundles can have other persistable bundles as values, traverse with a queue. - Queue<PersistableBundle> queue = new ArrayDeque<>(); - queue.add(bundle); - while (!queue.isEmpty()) { - PersistableBundle current = queue.remove(); - for (String key : current.keySet()) { - enforceMaxStringLength(key, "key in " + argName); - Object value = current.get(key); - if (value instanceof String) { - enforceMaxStringLength((String) value, "string value in " + argName); - } else if (value instanceof String[]) { - for (String str : (String[]) value) { - enforceMaxStringLength(str, "string value in " + argName); - } - } else if (value instanceof PersistableBundle) { - queue.add((PersistableBundle) value); - } - } - } - } - private ActiveAdmin getActiveAdminForCaller(@Nullable ComponentName who, CallerIdentity caller) { synchronized (getLockObject()) { |