Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 34ac6bbd authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Ensure policy has no absurdly long strings" into sc-dev

parents 16c2a334 12c20150
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -11262,7 +11262,8 @@ public class DevicePolicyManager {
    /**
    /**
     * Called by a device admin to set the long support message. This will be displayed to the user
     * Called by a device admin to set the long support message. This will be displayed to the user
     * in the device administators settings screen.
     * in the device administrators settings screen. If the message is longer than 20000 characters
     * it may be truncated.
     * <p>
     * <p>
     * If the long support message needs to be localized, it is the responsibility of the
     * If the long support message needs to be localized, it is the responsibility of the
     * {@link DeviceAdminReceiver} to listen to the {@link Intent#ACTION_LOCALE_CHANGED} broadcast
     * {@link DeviceAdminReceiver} to listen to the {@link Intent#ACTION_LOCALE_CHANGED} broadcast
+90 −3
Original line number Original line Diff line number Diff line
@@ -360,6 +360,7 @@ import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.cert.X509Certificate;
import java.text.DateFormat;
import java.text.DateFormat;
import java.time.LocalDate;
import java.time.LocalDate;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collection;
@@ -371,6 +372,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Locale;
import java.util.Map;
import java.util.Map;
import java.util.Objects;
import java.util.Objects;
import java.util.Queue;
import java.util.Set;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.function.Function;
@@ -399,6 +401,15 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
    private static final int REQUEST_PROFILE_OFF_DEADLINE = 5572;
    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_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 MS_PER_DAY = TimeUnit.DAYS.toMillis(1);
    private static final long EXPIRATION_GRACE_PERIOD_MS = 5 * MS_PER_DAY; // 5 days, in ms
    private static final long EXPIRATION_GRACE_PERIOD_MS = 5 * MS_PER_DAY; // 5 days, in ms
@@ -9866,6 +9877,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        }
        }
        Objects.requireNonNull(admin, "admin is null");
        Objects.requireNonNull(admin, "admin is null");
        Objects.requireNonNull(agent, "agent is null");
        Objects.requireNonNull(agent, "agent is null");
        enforceMaxPackageNameLength(agent.getPackageName());
        final String agentAsString = agent.flattenToString();
        enforceMaxStringLength(agentAsString, "agent name");
        if (args != null) {
            enforceMaxStringLength(args, "args");
        }
        final int userHandle = UserHandle.getCallingUserId();
        final int userHandle = UserHandle.getCallingUserId();
        synchronized (getLockObject()) {
        synchronized (getLockObject()) {
            ActiveAdmin ap = getActiveAdminForCallerLocked(admin,
            ActiveAdmin ap = getActiveAdminForCallerLocked(admin,
@@ -10104,6 +10121,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        final CallerIdentity caller = getCallerIdentity(who);
        final CallerIdentity caller = getCallerIdentity(who);
        if (packageList != null) {
        if (packageList != null) {
            for (String pkg : (List<String>) packageList) {
                enforceMaxPackageNameLength(pkg);
            }
            int userId = caller.getUserId();
            int userId = caller.getUserId();
            final List<AccessibilityServiceInfo> enabledServices;
            final List<AccessibilityServiceInfo> enabledServices;
            long id = mInjector.binderClearCallingIdentity();
            long id = mInjector.binderClearCallingIdentity();
@@ -10270,6 +10291,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        }
        }
        if (packageList != null) {
        if (packageList != null) {
            for (String pkg : (List<String>) packageList) {
                enforceMaxPackageNameLength(pkg);
            }
            List<InputMethodInfo> enabledImes = mInjector.binderWithCleanCallingIdentity(() ->
            List<InputMethodInfo> enabledImes = mInjector.binderWithCleanCallingIdentity(() ->
                    InputMethodManagerInternal.get().getEnabledInputMethodListAsUser(userId));
                    InputMethodManagerInternal.get().getEnabledInputMethodListAsUser(userId));
            if (enabledImes != null) {
            if (enabledImes != null) {
@@ -11494,6 +11519,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
            return;
            return;
        }
        }
        Objects.requireNonNull(who, "ComponentName is null");
        Objects.requireNonNull(who, "ComponentName is null");
        enforceMaxStringLength(accountType, "account type");
        final CallerIdentity caller = getCallerIdentity(who);
        final CallerIdentity caller = getCallerIdentity(who);
        synchronized (getLockObject()) {
        synchronized (getLockObject()) {
            /*
            /*
@@ -11912,6 +11939,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
            throws SecurityException {
            throws SecurityException {
        Objects.requireNonNull(who, "ComponentName is null");
        Objects.requireNonNull(who, "ComponentName is null");
        Objects.requireNonNull(packages, "packages is null");
        Objects.requireNonNull(packages, "packages is null");
        for (String pkg : packages) {
            enforceMaxPackageNameLength(pkg);
        }
        final CallerIdentity caller = getCallerIdentity(who);
        final CallerIdentity caller = getCallerIdentity(who);
        synchronized (getLockObject()) {
        synchronized (getLockObject()) {
@@ -13869,6 +13900,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
            return;
            return;
        }
        }
        Objects.requireNonNull(who, "ComponentName is null");
        Objects.requireNonNull(who, "ComponentName is null");
        message = truncateIfLonger(message, MAX_SHORT_SUPPORT_MESSAGE_LENGTH);
        final CallerIdentity caller = getCallerIdentity(who);
        final CallerIdentity caller = getCallerIdentity(who);
        synchronized (getLockObject()) {
        synchronized (getLockObject()) {
            ActiveAdmin admin = getActiveAdminForUidLocked(who, caller.getUid());
            ActiveAdmin admin = getActiveAdminForUidLocked(who, caller.getUid());
@@ -13901,6 +13934,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        if (!mHasFeature) {
        if (!mHasFeature) {
            return;
            return;
        }
        }
        message = truncateIfLonger(message, MAX_LONG_SUPPORT_MESSAGE_LENGTH);
        Objects.requireNonNull(who, "ComponentName is null");
        Objects.requireNonNull(who, "ComponentName is null");
        final CallerIdentity caller = getCallerIdentity(who);
        final CallerIdentity caller = getCallerIdentity(who);
        synchronized (getLockObject()) {
        synchronized (getLockObject()) {
@@ -14050,6 +14086,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        Objects.requireNonNull(who, "ComponentName is null");
        Objects.requireNonNull(who, "ComponentName is null");
        final CallerIdentity caller = getCallerIdentity(who);
        final CallerIdentity caller = getCallerIdentity(who);
        text = truncateIfLonger(text, MAX_ORG_NAME_LENGTH);
        synchronized (getLockObject()) {
        synchronized (getLockObject()) {
            ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(caller);
            ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(caller);
            if (!TextUtils.equals(admin.organizationName, text)) {
            if (!TextUtils.equals(admin.organizationName, text)) {
@@ -14298,9 +14336,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
            throw new IllegalArgumentException("ids must not be null");
            throw new IllegalArgumentException("ids must not be null");
        }
        }
        for (String id : ids) {
        for (String id : ids) {
            if (TextUtils.isEmpty(id)) {
            Preconditions.checkArgument(!TextUtils.isEmpty(id), "ids must not have empty string");
                throw new IllegalArgumentException("ids must not contain empty string");
            enforceMaxStringLength(id, "affiliation id");
            }
        }
        }
        final Set<String> affiliationIds = new ArraySet<>(ids);
        final Set<String> affiliationIds = new ArraySet<>(ids);
@@ -15557,6 +15594,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
                "Provided administrator and target are the same object.");
                "Provided administrator and target are the same object.");
        Preconditions.checkArgument(!admin.getPackageName().equals(target.getPackageName()),
        Preconditions.checkArgument(!admin.getPackageName().equals(target.getPackageName()),
                "Provided administrator and target have the same package name.");
                "Provided administrator and target have the same package name.");
        if (bundle != null) {
            enforceMaxStringLength(bundle, "bundle");
        }
        final CallerIdentity caller = getCallerIdentity(admin);
        final CallerIdentity caller = getCallerIdentity(admin);
        Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller));
        Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller));
@@ -17641,4 +17681,51 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
                        && mInjector.getUsbManager().getUsbHalVersion() >= UsbManager.USB_HAL_V1_3
                        && mInjector.getUsbManager().getUsbHalVersion() >= UsbManager.USB_HAL_V1_3
        );
        );
    }
    }
    /**
     * 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);
                }
            }
        }
    }
}
}