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

Commit e9a38062 authored by Sudheer Shanka's avatar Sudheer Shanka
Browse files

Revert "Add API to allow apps with location permission to access data blobs."

This reverts commit e0237fa5. Reverting
based on the feedback from Permissions and privacy team.

Bug: 158705914
Test: atest --test-mapping apex/blobstore
Change-Id: Id057e8c61dcf9d3d111ab20530a2074083052392
parent 46614cfa
Loading
Loading
Loading
Loading
+5 −66
Original line number Diff line number Diff line
@@ -258,8 +258,7 @@ public class BlobStoreManager {
    public @NonNull ParcelFileDescriptor openBlob(@NonNull BlobHandle blobHandle)
            throws IOException {
        try {
            return mService.openBlob(blobHandle, mContext.getOpPackageName(),
                    mContext.getAttributionTag());
            return mService.openBlob(blobHandle, mContext.getOpPackageName());
        } catch (ParcelableException e) {
            e.maybeRethrow(IOException.class);
            throw new RuntimeException(e);
@@ -316,7 +315,7 @@ public class BlobStoreManager {
            @CurrentTimeMillisLong long leaseExpiryTimeMillis) throws IOException {
        try {
            mService.acquireLease(blobHandle, descriptionResId, null, leaseExpiryTimeMillis,
                    mContext.getOpPackageName(), mContext.getAttributionTag());
                    mContext.getOpPackageName());
        } catch (ParcelableException e) {
            e.maybeRethrow(IOException.class);
            e.maybeRethrow(LimitExceededException.class);
@@ -379,7 +378,7 @@ public class BlobStoreManager {
            @CurrentTimeMillisLong long leaseExpiryTimeMillis) throws IOException {
        try {
            mService.acquireLease(blobHandle, INVALID_RES_ID, description, leaseExpiryTimeMillis,
                    mContext.getOpPackageName(), mContext.getAttributionTag());
                    mContext.getOpPackageName());
        } catch (ParcelableException e) {
            e.maybeRethrow(IOException.class);
            e.maybeRethrow(LimitExceededException.class);
@@ -498,8 +497,7 @@ public class BlobStoreManager {
     */
    public void releaseLease(@NonNull BlobHandle blobHandle) throws IOException {
        try {
            mService.releaseLease(blobHandle, mContext.getOpPackageName(),
                    mContext.getAttributionTag());
            mService.releaseLease(blobHandle, mContext.getOpPackageName());
        } catch (ParcelableException e) {
            e.maybeRethrow(IOException.class);
            throw new RuntimeException(e);
@@ -604,8 +602,7 @@ public class BlobStoreManager {
    @Nullable
    public LeaseInfo getLeaseInfo(@NonNull BlobHandle blobHandle) throws IOException {
        try {
            return mService.getLeaseInfo(blobHandle, mContext.getOpPackageName(),
                    mContext.getAttributionTag());
            return mService.getLeaseInfo(blobHandle, mContext.getOpPackageName());
        } catch (ParcelableException e) {
            e.maybeRethrow(IOException.class);
            throw new RuntimeException(e);
@@ -899,64 +896,6 @@ public class BlobStoreManager {
            }
        }

        /**
         * Allow apps with location permission to access this blob data once it is committed using
         * a {@link BlobHandle} representing the blob.
         *
         * <p> This needs to be called before committing the blob using
         * {@link #commit(Executor, Consumer)}.
         *
         * Note that if a caller allows access to the blob using this API in addition to other APIs
         * like {@link #allowPackageAccess(String, byte[])}, then apps satisfying any one of these
         * access conditions will be allowed to access the blob.
         *
         * @param permissionName the name of the location permission that needs to be granted
         *                       for the app. This can be either one of
         *                       {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or
         *                       {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}.
         *
         * @throws IOException when there is an I/O error while changing the access.
         * @throws SecurityException when the caller is not the owner of the session.
         * @throws IllegalStateException when the caller tries to change access for a blob which is
         *                               already committed.
         */
        public void allowPackagesWithLocationPermission(@NonNull String permissionName)
                throws IOException {
            try {
                mSession.allowPackagesWithLocationPermission(permissionName);
            } catch (ParcelableException e) {
                e.maybeRethrow(IOException.class);
                throw new RuntimeException(e);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }

        /**
         * Returns {@code true} if access has been allowed for apps with location permission by
         * using {@link #allowPackagesWithLocationPermission(String)}.
         *
         * @param permissionName the name of the location permission that needs to be granted
         *                       for the app. This can be either one of
         *                       {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or
         *                       {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}.
         *
         * @throws IOException when there is an I/O error while getting the access type.
         * @throws IllegalStateException when the caller tries to get access type from a session
         *                               which is closed or abandoned.
         */
        public boolean arePackagesWithLocationPermissionAllowed(@NonNull String permissionName)
                throws IOException {
            try {
                return mSession.arePackagesWithLocationPermissionAllowed(permissionName);
            } catch (ParcelableException e) {
                e.maybeRethrow(IOException.class);
                throw new RuntimeException(e);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }

        /**
         * Commit the file that was written so far to this session to the blob store maintained by
         * the system.
+4 −6
Original line number Diff line number Diff line
@@ -25,13 +25,12 @@ import android.os.RemoteCallback;
interface IBlobStoreManager {
    long createSession(in BlobHandle handle, in String packageName);
    IBlobStoreSession openSession(long sessionId, in String packageName);
    ParcelFileDescriptor openBlob(in BlobHandle handle, in String packageName,
           in String attributionTag);
    ParcelFileDescriptor openBlob(in BlobHandle handle, in String packageName);
    void abandonSession(long sessionId, in String packageName);

    void acquireLease(in BlobHandle handle, int descriptionResId, in CharSequence description,
            long leaseTimeoutMillis, in String packageName, in String attributionTag);
    void releaseLease(in BlobHandle handle, in String packageName, in String attributionTag);
            long leaseTimeoutMillis, in String packageName);
    void releaseLease(in BlobHandle handle, in String packageName);
    long getRemainingLeaseQuotaBytes(String packageName);

    void waitForIdle(in RemoteCallback callback);
@@ -40,6 +39,5 @@ interface IBlobStoreManager {
    void deleteBlob(long blobId);

    List<BlobHandle> getLeasedBlobs(in String packageName);
    LeaseInfo getLeaseInfo(in BlobHandle blobHandle, in String packageName,
            in String attributionTag);
    LeaseInfo getLeaseInfo(in BlobHandle blobHandle, in String packageName);
}
 No newline at end of file
+0 −2
Original line number Diff line number Diff line
@@ -26,12 +26,10 @@ interface IBlobStoreSession {
    void allowPackageAccess(in String packageName, in byte[] certificate);
    void allowSameSignatureAccess();
    void allowPublicAccess();
    void allowPackagesWithLocationPermission(in String permissionName);

    boolean isPackageAccessAllowed(in String packageName, in byte[] certificate);
    boolean isSameSignatureAccessAllowed();
    boolean isPublicAccessAllowed();
    boolean arePackagesWithLocationPermissionAllowed(in String permissionName);

    long getSize();
    void close();
+0 −4
Original line number Diff line number Diff line
@@ -38,7 +38,6 @@ public final class XmlTags {
    public static final String ATTR_TYPE = "t";
    public static final String TAG_ALLOWED_PACKAGE = "wl";
    public static final String ATTR_CERTIFICATE = "ct";
    public static final String TAG_ALLOWED_PERMISSION = "ap";

    // For BlobHandle
    public static final String TAG_BLOB_HANDLE = "bh";
@@ -56,7 +55,4 @@ public final class XmlTags {
    public static final String TAG_LEASEE = "l";
    public static final String ATTR_DESCRIPTION_RES_NAME = "rn";
    public static final String ATTR_DESCRIPTION = "d";

    // Generic
    public static final String ATTR_VALUE = "val";
}
+2 −79
Original line number Diff line number Diff line
@@ -15,30 +15,19 @@
 */
package com.android.server.blob;

import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
import static android.Manifest.permission.ACCESS_FINE_LOCATION;
import static android.app.blob.XmlTags.ATTR_CERTIFICATE;
import static android.app.blob.XmlTags.ATTR_PACKAGE;
import static android.app.blob.XmlTags.ATTR_TYPE;
import static android.app.blob.XmlTags.ATTR_VALUE;
import static android.app.blob.XmlTags.TAG_ALLOWED_PACKAGE;
import static android.app.blob.XmlTags.TAG_ALLOWED_PERMISSION;

import static com.android.server.blob.BlobStoreConfig.TAG;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.UserHandle;
import android.permission.PermissionManager;
import android.util.ArraySet;
import android.util.Base64;
import android.util.DebugUtils;
import android.util.IndentingPrintWriter;
import android.util.Slog;

import com.android.internal.util.XmlUtils;

@@ -64,27 +53,21 @@ class BlobAccessMode {
            ACCESS_TYPE_PUBLIC,
            ACCESS_TYPE_SAME_SIGNATURE,
            ACCESS_TYPE_ALLOWLIST,
            ACCESS_TYPE_LOCATION_PERMISSION,
    })
    @interface AccessType {}
    public static final int ACCESS_TYPE_PRIVATE = 1 << 0;
    public static final int ACCESS_TYPE_PUBLIC = 1 << 1;
    public static final int ACCESS_TYPE_SAME_SIGNATURE = 1 << 2;
    public static final int ACCESS_TYPE_ALLOWLIST = 1 << 3;
    public static final int ACCESS_TYPE_LOCATION_PERMISSION = 1 << 4;

    private int mAccessType = ACCESS_TYPE_PRIVATE;

    private final ArraySet<PackageIdentifier> mAllowedPackages = new ArraySet<>();
    private final ArraySet<String> mAllowedPermissions = new ArraySet<>();

    void allow(BlobAccessMode other) {
        if ((other.mAccessType & ACCESS_TYPE_ALLOWLIST) != 0) {
            mAllowedPackages.addAll(other.mAllowedPackages);
        }
        if ((other.mAccessType & ACCESS_TYPE_LOCATION_PERMISSION) != 0) {
            mAllowedPermissions.addAll(other.mAllowedPermissions);
        }
        mAccessType |= other.mAccessType;
    }

@@ -101,11 +84,6 @@ class BlobAccessMode {
        mAllowedPackages.add(PackageIdentifier.create(packageName, certificate));
    }

    void allowPackagesWithLocationPermission(@NonNull String permissionName) {
        mAccessType |= ACCESS_TYPE_LOCATION_PERMISSION;
        mAllowedPermissions.add(permissionName);
    }

    boolean isPublicAccessAllowed() {
        return (mAccessType & ACCESS_TYPE_PUBLIC) != 0;
    }
@@ -121,15 +99,8 @@ class BlobAccessMode {
        return mAllowedPackages.contains(PackageIdentifier.create(packageName, certificate));
    }

    boolean arePackagesWithLocationPermissionAllowed(@NonNull String permissionName) {
        if ((mAccessType & ACCESS_TYPE_LOCATION_PERMISSION) == 0) {
            return false;
        }
        return mAllowedPermissions.contains(permissionName);
    }

    boolean isAccessAllowedForCaller(Context context, @NonNull String callingPackage,
            @NonNull String committerPackage, int callingUid, @Nullable String attributionTag) {
    boolean isAccessAllowedForCaller(Context context,
            @NonNull String callingPackage, @NonNull String committerPackage) {
        if ((mAccessType & ACCESS_TYPE_PUBLIC) != 0) {
            return true;
        }
@@ -153,37 +124,9 @@ class BlobAccessMode {
            }
        }

        if ((mAccessType & ACCESS_TYPE_LOCATION_PERMISSION) != 0) {
            final AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
            for (int i = 0; i < mAllowedPermissions.size(); ++i) {
                final String permission = mAllowedPermissions.valueAt(i);
                if (PermissionManager.checkPackageNamePermission(permission, callingPackage,
                        UserHandle.getUserId(callingUid)) != PackageManager.PERMISSION_GRANTED) {
                    continue;
                }
                // TODO: Add appropriate message
                if (appOpsManager.noteOpNoThrow(getAppOp(permission), callingUid, callingPackage,
                        attributionTag, null /* message */) == AppOpsManager.MODE_ALLOWED) {
                    return true;
                }
            }
        }

        return false;
    }

    private static String getAppOp(String permission) {
        switch (permission) {
            case ACCESS_FINE_LOCATION:
                return AppOpsManager.OPSTR_FINE_LOCATION;
            case ACCESS_COARSE_LOCATION:
                return AppOpsManager.OPSTR_COARSE_LOCATION;
            default:
                Slog.w(TAG, "Unknown permission found: " + permission);
                return null;
        }
    }

    int getAccessType() {
        return mAccessType;
    }
@@ -205,16 +148,6 @@ class BlobAccessMode {
            }
            fout.decreaseIndent();
        }
        fout.print("Allowed permissions:");
        if (mAllowedPermissions.isEmpty()) {
            fout.println(" (Empty)");
        } else {
            fout.increaseIndent();
            for (int i = 0, count = mAllowedPermissions.size(); i < count; ++i) {
                fout.println(mAllowedPermissions.valueAt(i).toString());
            }
            fout.decreaseIndent();
        }
    }

    void writeToXml(@NonNull XmlSerializer out) throws IOException {
@@ -226,12 +159,6 @@ class BlobAccessMode {
            XmlUtils.writeByteArrayAttribute(out, ATTR_CERTIFICATE, packageIdentifier.certificate);
            out.endTag(null, TAG_ALLOWED_PACKAGE);
        }
        for (int i = 0, count = mAllowedPermissions.size(); i < count; ++i) {
            out.startTag(null, TAG_ALLOWED_PERMISSION);
            final String permission = mAllowedPermissions.valueAt(i);
            XmlUtils.writeStringAttribute(out, ATTR_VALUE, permission);
            out.endTag(null, TAG_ALLOWED_PERMISSION);
        }
    }

    @NonNull
@@ -249,10 +176,6 @@ class BlobAccessMode {
                final byte[] certificate = XmlUtils.readByteArrayAttribute(in, ATTR_CERTIFICATE);
                blobAccessMode.allowPackageAccess(packageName, certificate);
            }
            if (TAG_ALLOWED_PERMISSION.equals(in.getName())) {
                final String permission = XmlUtils.readStringAttribute(in, ATTR_VALUE);
                blobAccessMode.allowPackagesWithLocationPermission(permission);
            }
        }
        return blobAccessMode;
    }
Loading