Add limits on BlobHandle label and lease expiry strings.

Fixes: 157221032
Test: atest --test-mapping apex/blobstore
Change-Id: Ic8eac1d956b60fbcd171c2705d5a151c7d5baf87
This commit is contained in:
Sudheer Shanka
2020-06-26 15:02:04 -07:00
parent aeb6e12780
commit 94b852f9a6
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_LABEL_LENGTH = 100; // characters
/**
* 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 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
* allowed to be accessed by any other app,
* in {@link System#currentTimeMillis()} timebase or {@code 0} to
@@ -205,9 +209,9 @@ public final class BlobHandle implements Parcelable {
final BlobHandle other = (BlobHandle) obj;
return this.algorithm.equals(other.algorithm)
&& Arrays.equals(this.digest, other.digest)
&& this.label.equals(other.label)
&& this.label.toString().equals(other.label.toString())
&& this.expiryTimeMillis == other.expiryTimeMillis
&& this.tag.equals(tag);
&& this.tag.equals(other.tag);
}
@Override
@@ -233,6 +237,7 @@ public final class BlobHandle implements Parcelable {
Preconditions.checkArgumentIsSupported(SUPPORTED_ALGOS, algorithm);
Preconditions.checkByteArrayNotEmpty(digest, "digest");
Preconditions.checkStringNotEmpty(label, "label must not be null");
Preconditions.checkArgument(label.length() <= LIMIT_BLOB_LABEL_LENGTH, "label too long");
Preconditions.checkArgumentNonnegative(expiryTimeMillis,
"expiryTimeMillis must not be negative");
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
* acquire a lease for.
* @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
* automatically released, in {@link System#currentTimeMillis()}
* 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
* acquire a lease for.
* @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 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.provider.DeviceConfig;
import android.provider.DeviceConfig.Properties;
import android.text.TextUtils;
import android.util.DataUnit;
import android.util.Log;
import android.util.Slog;
@@ -171,6 +172,13 @@ class BlobStoreConfig {
public static int 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) {
if (!NAMESPACE_BLOBSTORE.equals(properties.getNamespace())) {
return;
@@ -221,6 +229,10 @@ class BlobStoreConfig {
MAX_BLOB_ACCESS_PERMITTED_PACKAGES = properties.getInt(key,
DEFAULT_MAX_BLOB_ACCESS_PERMITTED_PACKAGES);
break;
case KEY_LEASE_DESC_CHAR_LIMIT:
LEASE_DESC_CHAR_LIMIT = properties.getInt(key,
DEFAULT_LEASE_DESC_CHAR_LIMIT);
break;
default:
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,
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;
}
/**
* 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
public static File prepareBlobFile(long sessionId) {
final File blobsDir = prepareBlobsDir();

View File

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