Merge "Add limits on BlobHandle label and lease expiry strings." into rvc-dev am: 7434322aef

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/12013588

Change-Id: I6116c382478eee1f5cd9d9b1405df3ae22ab59f4
This commit is contained in:
Sudheer Shanka
2020-06-29 21:47:48 +00:00
committed by Automerger Merge Worker
4 changed files with 41 additions and 4 deletions

View File

@@ -51,6 +51,7 @@ public final class BlobHandle implements Parcelable {
}; };
private static final int LIMIT_BLOB_TAG_LENGTH = 128; // characters private static final int LIMIT_BLOB_TAG_LENGTH = 128; // characters
private static final int LIMIT_BLOB_LABEL_LENGTH = 100; // characters
/** /**
* Cyrptographically secure hash algorithm used to generate hash of the blob this handle is * Cyrptographically secure hash algorithm used to generate hash of the blob this handle is
@@ -128,6 +129,9 @@ public final class BlobHandle implements Parcelable {
* *
* @param digest the SHA-256 hash of the blob this is representing. * @param digest the SHA-256 hash of the blob this is representing.
* @param label a label indicating what the blob is, that can be surfaced to the user. * @param label a label indicating what the blob is, that can be surfaced to the user.
* The length of the label cannot be more than 100 characters. It is recommended
* to keep this brief. This may be truncated and ellipsized if it is too long
* to be displayed to the user.
* @param expiryTimeMillis the time in secs after which the blob should be invalidated and not * @param expiryTimeMillis the time in secs after which the blob should be invalidated and not
* allowed to be accessed by any other app, * allowed to be accessed by any other app,
* in {@link System#currentTimeMillis()} timebase or {@code 0} to * in {@link System#currentTimeMillis()} timebase or {@code 0} to
@@ -205,9 +209,9 @@ public final class BlobHandle implements Parcelable {
final BlobHandle other = (BlobHandle) obj; final BlobHandle other = (BlobHandle) obj;
return this.algorithm.equals(other.algorithm) return this.algorithm.equals(other.algorithm)
&& Arrays.equals(this.digest, other.digest) && Arrays.equals(this.digest, other.digest)
&& this.label.equals(other.label) && this.label.toString().equals(other.label.toString())
&& this.expiryTimeMillis == other.expiryTimeMillis && this.expiryTimeMillis == other.expiryTimeMillis
&& this.tag.equals(tag); && this.tag.equals(other.tag);
} }
@Override @Override
@@ -233,6 +237,7 @@ public final class BlobHandle implements Parcelable {
Preconditions.checkArgumentIsSupported(SUPPORTED_ALGOS, algorithm); Preconditions.checkArgumentIsSupported(SUPPORTED_ALGOS, algorithm);
Preconditions.checkByteArrayNotEmpty(digest, "digest"); Preconditions.checkByteArrayNotEmpty(digest, "digest");
Preconditions.checkStringNotEmpty(label, "label must not be null"); Preconditions.checkStringNotEmpty(label, "label must not be null");
Preconditions.checkArgument(label.length() <= LIMIT_BLOB_LABEL_LENGTH, "label too long");
Preconditions.checkArgumentNonnegative(expiryTimeMillis, Preconditions.checkArgumentNonnegative(expiryTimeMillis,
"expiryTimeMillis must not be negative"); "expiryTimeMillis must not be negative");
Preconditions.checkStringNotEmpty(tag, "tag must not be null"); Preconditions.checkStringNotEmpty(tag, "tag must not be null");

View File

@@ -347,7 +347,9 @@ public class BlobStoreManager {
* @param blobHandle the {@link BlobHandle} representing the blob that the caller wants to * @param blobHandle the {@link BlobHandle} representing the blob that the caller wants to
* acquire a lease for. * acquire a lease for.
* @param description a short description string that can be surfaced * @param description a short description string that can be surfaced
* to the user explaining what the blob is used for. * to the user explaining what the blob is used for. It is recommended to
* keep this description brief. This may be truncated and ellipsized
* if it is too long to be displayed to the user.
* @param leaseExpiryTimeMillis the time in milliseconds after which the lease can be * @param leaseExpiryTimeMillis the time in milliseconds after which the lease can be
* automatically released, in {@link System#currentTimeMillis()} * automatically released, in {@link System#currentTimeMillis()}
* timebase. If its value is {@code 0}, then the behavior of this * timebase. If its value is {@code 0}, then the behavior of this
@@ -458,7 +460,9 @@ public class BlobStoreManager {
* @param blobHandle the {@link BlobHandle} representing the blob that the caller wants to * @param blobHandle the {@link BlobHandle} representing the blob that the caller wants to
* acquire a lease for. * acquire a lease for.
* @param description a short description string that can be surfaced * @param description a short description string that can be surfaced
* to the user explaining what the blob is used for. * to the user explaining what the blob is used for. It is recommended to
* keep this description brief. This may be truncated and
* ellipsized if it is too long to be displayed to the user.
* *
* @throws IOException when there is an I/O error while acquiring a lease to the blob. * @throws IOException when there is an I/O error while acquiring a lease to the blob.
* @throws SecurityException when the blob represented by the {@code blobHandle} does not * @throws SecurityException when the blob represented by the {@code blobHandle} does not

View File

@@ -25,6 +25,7 @@ import android.content.Context;
import android.os.Environment; import android.os.Environment;
import android.provider.DeviceConfig; import android.provider.DeviceConfig;
import android.provider.DeviceConfig.Properties; import android.provider.DeviceConfig.Properties;
import android.text.TextUtils;
import android.util.DataUnit; import android.util.DataUnit;
import android.util.Log; import android.util.Log;
import android.util.Slog; import android.util.Slog;
@@ -171,6 +172,13 @@ class BlobStoreConfig {
public static int MAX_BLOB_ACCESS_PERMITTED_PACKAGES = public static int MAX_BLOB_ACCESS_PERMITTED_PACKAGES =
DEFAULT_MAX_BLOB_ACCESS_PERMITTED_PACKAGES; DEFAULT_MAX_BLOB_ACCESS_PERMITTED_PACKAGES;
/**
* Denotes the maximum number of characters that a lease description can have.
*/
public static final String KEY_LEASE_DESC_CHAR_LIMIT = "lease_desc_char_limit";
public static int DEFAULT_LEASE_DESC_CHAR_LIMIT = 300;
public static int LEASE_DESC_CHAR_LIMIT = DEFAULT_LEASE_DESC_CHAR_LIMIT;
static void refresh(Properties properties) { static void refresh(Properties properties) {
if (!NAMESPACE_BLOBSTORE.equals(properties.getNamespace())) { if (!NAMESPACE_BLOBSTORE.equals(properties.getNamespace())) {
return; return;
@@ -221,6 +229,10 @@ class BlobStoreConfig {
MAX_BLOB_ACCESS_PERMITTED_PACKAGES = properties.getInt(key, MAX_BLOB_ACCESS_PERMITTED_PACKAGES = properties.getInt(key,
DEFAULT_MAX_BLOB_ACCESS_PERMITTED_PACKAGES); DEFAULT_MAX_BLOB_ACCESS_PERMITTED_PACKAGES);
break; break;
case KEY_LEASE_DESC_CHAR_LIMIT:
LEASE_DESC_CHAR_LIMIT = properties.getInt(key,
DEFAULT_LEASE_DESC_CHAR_LIMIT);
break;
default: default:
Slog.wtf(TAG, "Unknown key in device config properties: " + key); Slog.wtf(TAG, "Unknown key in device config properties: " + key);
} }
@@ -262,6 +274,8 @@ class BlobStoreConfig {
fout.println(String.format(dumpFormat, KEY_MAX_BLOB_ACCESS_PERMITTED_PACKAGES, fout.println(String.format(dumpFormat, KEY_MAX_BLOB_ACCESS_PERMITTED_PACKAGES,
MAX_BLOB_ACCESS_PERMITTED_PACKAGES, MAX_BLOB_ACCESS_PERMITTED_PACKAGES,
DEFAULT_MAX_BLOB_ACCESS_PERMITTED_PACKAGES)); DEFAULT_MAX_BLOB_ACCESS_PERMITTED_PACKAGES));
fout.println(String.format(dumpFormat, KEY_LEASE_DESC_CHAR_LIMIT,
LEASE_DESC_CHAR_LIMIT, DEFAULT_LEASE_DESC_CHAR_LIMIT));
} }
} }
@@ -368,6 +382,18 @@ class BlobStoreConfig {
return DeviceConfigProperties.MAX_BLOB_ACCESS_PERMITTED_PACKAGES; return DeviceConfigProperties.MAX_BLOB_ACCESS_PERMITTED_PACKAGES;
} }
/**
* Returns the lease description truncated to
* {@link DeviceConfigProperties#LEASE_DESC_CHAR_LIMIT} characters.
*/
public static CharSequence getTruncatedLeaseDescription(CharSequence description) {
if (TextUtils.isEmpty(description)) {
return description;
}
return TextUtils.trimToLengthWithEllipsis(description,
DeviceConfigProperties.LEASE_DESC_CHAR_LIMIT);
}
@Nullable @Nullable
public static File prepareBlobFile(long sessionId) { public static File prepareBlobFile(long sessionId) {
final File blobsDir = prepareBlobsDir(); final File blobsDir = prepareBlobsDir();

View File

@@ -1500,6 +1500,8 @@ public class BlobStoreManagerService extends SystemService {
"leaseExpiryTimeMillis must not be negative"); "leaseExpiryTimeMillis must not be negative");
Objects.requireNonNull(packageName, "packageName must not be null"); Objects.requireNonNull(packageName, "packageName must not be null");
description = BlobStoreConfig.getTruncatedLeaseDescription(description);
final int callingUid = Binder.getCallingUid(); final int callingUid = Binder.getCallingUid();
verifyCallingPackage(callingUid, packageName); verifyCallingPackage(callingUid, packageName);