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

Commit fe830f97 authored by Sudheer Shanka's avatar Sudheer Shanka Committed by Android (Google) Code Review
Browse files

Merge "Validate input arguments to BlobStoreManager APIs."

parents dba93038 4824e3dc
Loading
Loading
Loading
Loading
+18 −8
Original line number Diff line number Diff line
@@ -45,6 +45,10 @@ import java.util.Objects;
public final class BlobHandle implements Parcelable {
    private static final String ALGO_SHA_256 = "SHA-256";

    private static final String[] SUPPORTED_ALGOS = {
            ALGO_SHA_256
    };

    private static final int LIMIT_BLOB_TAG_LENGTH = 128; // characters

    /**
@@ -104,14 +108,9 @@ public final class BlobHandle implements Parcelable {
    public static @NonNull BlobHandle create(@NonNull String algorithm, @NonNull byte[] digest,
            @NonNull CharSequence label, @CurrentTimeMillisLong long expiryTimeMillis,
            @NonNull String tag) {
        Preconditions.checkNotNull(algorithm, "algorithm must not be null");
        Preconditions.checkNotNull(digest, "digest must not be null");
        Preconditions.checkNotNull(label, "label must not be null");
        Preconditions.checkArgumentNonnegative(expiryTimeMillis,
                "expiryTimeMillis must not be negative");
        Preconditions.checkNotNull(tag, "tag must not be null");
        Preconditions.checkArgument(tag.length() <= LIMIT_BLOB_TAG_LENGTH, "tag too long");
        return new BlobHandle(algorithm, digest, label, expiryTimeMillis, tag);
        final BlobHandle handle = new BlobHandle(algorithm, digest, label, expiryTimeMillis, tag);
        handle.assertIsValid();
        return handle;
    }

    /**
@@ -223,6 +222,17 @@ public final class BlobHandle implements Parcelable {
        fout.println("tag: " + tag);
    }

    /** @hide */
    public void assertIsValid() {
        Preconditions.checkArgumentIsSupported(SUPPORTED_ALGOS, algorithm);
        Preconditions.checkByteArrayNotEmpty(digest, "digest");
        Preconditions.checkStringNotEmpty(label, "label must not be null");
        Preconditions.checkArgumentNonnegative(expiryTimeMillis,
                "expiryTimeMillis must not be negative");
        Preconditions.checkStringNotEmpty(tag, "tag must not be null");
        Preconditions.checkArgument(tag.length() <= LIMIT_BLOB_TAG_LENGTH, "tag too long");
    }

    public static final @NonNull Creator<BlobHandle> CREATOR = new Creator<BlobHandle>() {
        @Override
        public @NonNull BlobHandle createFromParcel(@NonNull Parcel source) {
+23 −18
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManagerInternal;
import android.content.res.ResourceId;
import android.os.Binder;
import android.os.Handler;
import android.os.HandlerThread;
@@ -91,6 +92,7 @@ import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * Service responsible for maintaining and facilitating access to data blobs published by apps.
@@ -658,10 +660,9 @@ public class BlobStoreManagerService extends SystemService {
        @IntRange(from = 1)
        public long createSession(@NonNull BlobHandle blobHandle,
                @NonNull String packageName) {
            Preconditions.checkNotNull(blobHandle, "blobHandle must not be null");
            Preconditions.checkNotNull(packageName, "packageName must not be null");
            // TODO: verify blobHandle.algorithm is sha-256
            // TODO: assert blobHandle is valid.
            Objects.requireNonNull(blobHandle, "blobHandle must not be null");
            blobHandle.assertIsValid();
            Objects.requireNonNull(packageName, "packageName must not be null");

            final int callingUid = Binder.getCallingUid();
            verifyCallingPackage(callingUid, packageName);
@@ -682,7 +683,7 @@ public class BlobStoreManagerService extends SystemService {
                @NonNull String packageName) {
            Preconditions.checkArgumentPositive(sessionId,
                    "sessionId must be positive: " + sessionId);
            Preconditions.checkNotNull(packageName, "packageName must not be null");
            Objects.requireNonNull(packageName, "packageName must not be null");

            final int callingUid = Binder.getCallingUid();
            verifyCallingPackage(callingUid, packageName);
@@ -695,7 +696,7 @@ public class BlobStoreManagerService extends SystemService {
                @NonNull String packageName) {
            Preconditions.checkArgumentPositive(sessionId,
                    "sessionId must be positive: " + sessionId);
            Preconditions.checkNotNull(packageName, "packageName must not be null");
            Objects.requireNonNull(packageName, "packageName must not be null");

            final int callingUid = Binder.getCallingUid();
            verifyCallingPackage(callingUid, packageName);
@@ -706,8 +707,9 @@ public class BlobStoreManagerService extends SystemService {
        @Override
        public ParcelFileDescriptor openBlob(@NonNull BlobHandle blobHandle,
                @NonNull String packageName) {
            Preconditions.checkNotNull(blobHandle, "blobHandle must not be null");
            Preconditions.checkNotNull(packageName, "packageName must not be null");
            Objects.requireNonNull(blobHandle, "blobHandle must not be null");
            blobHandle.assertIsValid();
            Objects.requireNonNull(packageName, "packageName must not be null");

            final int callingUid = Binder.getCallingUid();
            verifyCallingPackage(callingUid, packageName);
@@ -727,24 +729,27 @@ public class BlobStoreManagerService extends SystemService {

        @Override
        public void acquireLease(@NonNull BlobHandle blobHandle, @IdRes int descriptionResId,
                @CurrentTimeSecondsLong long leaseTimeoutSecs, @NonNull String packageName) {
            Preconditions.checkNotNull(blobHandle, "blobHandle must not be null");
            Preconditions.checkNotNull(packageName, "packageName must not be null");
            Preconditions.checkArgumentPositive(descriptionResId,
                    "descriptionResId must be positive; value=" + descriptionResId);
                @CurrentTimeSecondsLong long leaseExpiryTimeMillis, @NonNull String packageName) {
            Objects.requireNonNull(blobHandle, "blobHandle must not be null");
            blobHandle.assertIsValid();
            Preconditions.checkArgument(ResourceId.isValid(descriptionResId),
                    "descriptionResId is not valid");
            Preconditions.checkArgumentNonnegative(leaseExpiryTimeMillis,
                    "leaseExpiryTimeMillis must not be negative");
            Objects.requireNonNull(packageName, "packageName must not be null");

            final int callingUid = Binder.getCallingUid();
            verifyCallingPackage(callingUid, packageName);

            acquireLeaseInternal(blobHandle, descriptionResId, leaseTimeoutSecs,
            acquireLeaseInternal(blobHandle, descriptionResId, leaseExpiryTimeMillis,
                    callingUid, packageName);
        }

        @Override
        public void releaseLease(@NonNull BlobHandle blobHandle, @NonNull String packageName) {
            Preconditions.checkNotNull(blobHandle, "blobHandle must not be null");
            Preconditions.checkNotNull(packageName, "packageName must not be null");

            Objects.requireNonNull(blobHandle, "blobHandle must not be null");
            blobHandle.assertIsValid();
            Objects.requireNonNull(packageName, "packageName must not be null");

            final int callingUid = Binder.getCallingUid();
            verifyCallingPackage(callingUid, packageName);
@@ -754,7 +759,7 @@ public class BlobStoreManagerService extends SystemService {

        @Override
        public void waitForIdle(@NonNull RemoteCallback remoteCallback) {
            Preconditions.checkNotNull(remoteCallback, "remoteCallback must not be null");
            Objects.requireNonNull(remoteCallback, "remoteCallback must not be null");

            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP,
                    "Caller is not allowed to call this; caller=" + Binder.getCallingUid());
+7 −2
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Objects;

/** TODO: add doc */
public class BlobStoreSession extends IBlobStoreSession.Stub {
@@ -155,6 +156,8 @@ public class BlobStoreSession extends IBlobStoreSession.Stub {
    @NonNull
    public ParcelFileDescriptor openWrite(@BytesLong long offsetBytes,
            @BytesLong long lengthBytes) {
        Preconditions.checkArgumentNonnegative(offsetBytes, "offsetBytes must not be negative");

        assertCallerIsOwner();
        synchronized (mSessionLock) {
            if (mState != STATE_OPENED) {
@@ -242,7 +245,7 @@ public class BlobStoreSession extends IBlobStoreSession.Stub {
    public void allowPackageAccess(@NonNull String packageName,
            @NonNull byte[] certificate) {
        assertCallerIsOwner();
        Preconditions.checkNotNull(packageName, "packageName must not be null");
        Objects.requireNonNull(packageName, "packageName must not be null");
        synchronized (mSessionLock) {
            if (mState != STATE_OPENED) {
                throw new IllegalStateException("Not allowed to change access type in state: "
@@ -280,7 +283,9 @@ public class BlobStoreSession extends IBlobStoreSession.Stub {
    public boolean isPackageAccessAllowed(@NonNull String packageName,
            @NonNull byte[] certificate) {
        assertCallerIsOwner();
        Preconditions.checkNotNull(packageName, "packageName must not be null");
        Objects.requireNonNull(packageName, "packageName must not be null");
        Preconditions.checkByteArrayNotEmpty(certificate, "certificate");

        synchronized (mSessionLock) {
            if (mState != STATE_OPENED) {
                throw new IllegalStateException("Not allowed to get access type in state: "
+60 −0
Original line number Diff line number Diff line
@@ -21,7 +21,9 @@ import android.annotation.NonNull;
import android.compat.annotation.UnsupportedAppUsage;
import android.text.TextUtils;

import java.util.Arrays;
import java.util.Collection;
import java.util.Objects;

/**
 * Simple static methods to be called at the start of your own methods to verify
@@ -496,6 +498,64 @@ public class Preconditions {
        return value;
    }

    /**
     * Ensures that the given byte array is not {@code null}, and contains at least one element.
     *
     * @param value an array of elements.
     * @param valueName the name of the argument to use if the check fails.

     * @return the validated array
     *
     * @throws NullPointerException if the {@code value} was {@code null}
     * @throws IllegalArgumentException if the {@code value} was empty
     */
    @NonNull
    public static byte[] checkByteArrayNotEmpty(final byte[] value, final String valueName) {
        if (value == null) {
            throw new NullPointerException(valueName + " must not be null");
        }
        if (value.length == 0) {
            throw new IllegalArgumentException(valueName + " is empty");
        }
        return value;
    }

    /**
     * Ensures that argument {@code value} is one of {@code supportedValues}.
     *
     * @param supportedValues an array of string values
     * @param value a string value
     *
     * @return the validated value
     *
     * @throws NullPointerException if either {@code value} or {@code supportedValues} is null
     * @throws IllegalArgumentException if the {@code value} is not in {@code supportedValues}
     */
    @NonNull
    public static String checkArgumentIsSupported(final String[] supportedValues,
            final String value) {
        checkNotNull(value);
        checkNotNull(supportedValues);

        if (!contains(supportedValues, value)) {
            throw new IllegalArgumentException(value + "is not supported "
                    + Arrays.toString(supportedValues));
        }
        return value;
    }

    private static boolean contains(String[] values, String value) {
        if (values == null) {
            return false;
        }
        for (int i = 0; i < values.length; ++i) {
            if (Objects.equals(value, values[i])) {
                return true;
            }
        }
        return false;
    }

    /**
     * Ensures that all elements in the argument floating point array are within the inclusive range
     *