Merge "Ensure policy has no absurdly long strings" into tm-dev am: ddf587b218
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/23031226 Change-Id: Icdb2a24329031c8e3d6d07d84a105f5a02d72c74 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -12391,7 +12391,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
|
||||||
|
|||||||
@@ -397,6 +397,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;
|
||||||
@@ -408,6 +409,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.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@@ -439,6 +441,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
|
||||||
@@ -10042,6 +10053,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,
|
||||||
@@ -10283,6 +10300,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 : 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();
|
||||||
@@ -10452,6 +10473,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (packageList != null) {
|
if (packageList != null) {
|
||||||
|
for (String pkg : 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) {
|
||||||
@@ -11782,6 +11807,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()) {
|
||||||
/*
|
/*
|
||||||
@@ -12203,6 +12230,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()) {
|
||||||
@@ -14322,6 +14353,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());
|
||||||
@@ -14354,6 +14387,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()) {
|
||||||
@@ -14503,6 +14539,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)) {
|
||||||
@@ -14775,9 +14813,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);
|
||||||
@@ -16088,6 +16125,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(
|
Preconditions.checkCallAuthorization(
|
||||||
@@ -18889,4 +18929,51 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
|||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user