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

Commit 004aa708 authored by Raphael Kim's avatar Raphael Kim
Browse files

Clear calling identity to grant CDM permission when checking device config.

Bug: 286942347
Test: m services.companion
Change-Id: I88b399636123a4a394f2a280a19692c55a9d2441
Merged-In: I88b399636123a4a394f2a280a19692c55a9d2441
parent 79125d43
Loading
Loading
Loading
Loading
+0 −14
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@ import android.app.NotificationManager;
import android.app.PendingIntent;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.companion.utils.FeatureUtils;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -1227,11 +1226,6 @@ public final class CompanionDeviceManager {
    @Nullable
    public IntentSender buildPermissionTransferUserConsentIntent(int associationId)
            throws DeviceNotAssociatedException {
        if (!FeatureUtils.isPermSyncEnabled()) {
            throw new UnsupportedOperationException("Calling"
                    + " buildPermissionTransferUserConsentIntent, but this API is disabled by the"
                    + " system.");
        }
        try {
            PendingIntent pendingIntent = mService.buildPermissionTransferUserConsentIntent(
                    mContext.getOpPackageName(),
@@ -1264,10 +1258,6 @@ public final class CompanionDeviceManager {
    @Deprecated
    @UserHandleAware
    public void startSystemDataTransfer(int associationId) throws DeviceNotAssociatedException {
        if (!FeatureUtils.isPermSyncEnabled()) {
            throw new UnsupportedOperationException("Calling startSystemDataTransfer, but this API"
                    + " is disabled by the system.");
        }
        try {
            mService.startSystemDataTransfer(mContext.getOpPackageName(), mContext.getUserId(),
                    associationId, null);
@@ -1300,10 +1290,6 @@ public final class CompanionDeviceManager {
            @NonNull Executor executor,
            @NonNull OutcomeReceiver<Void, CompanionException> result)
            throws DeviceNotAssociatedException {
        if (!FeatureUtils.isPermSyncEnabled()) {
            throw new UnsupportedOperationException("Calling startSystemDataTransfer, but this API"
                    + " is disabled by the system.");
        }
        try {
            mService.startSystemDataTransfer(mContext.getOpPackageName(), mContext.getUserId(),
                    associationId, new SystemDataTransferCallbackProxy(executor, result));
+14 −2
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.companion.utils;

import android.os.Binder;
import android.os.Build;
import android.provider.DeviceConfig;

@@ -31,8 +32,19 @@ public final class FeatureUtils {
    private static final String PROPERTY_PERM_SYNC_ENABLED = "perm_sync_enabled";

    public static boolean isPermSyncEnabled() {
        return Build.isDebuggable() || DeviceConfig.getBoolean(NAMESPACE_COMPANION,
        // Permissions sync is always enabled in debuggable mode.
        if (Build.isDebuggable()) {
            return true;
        }

        // Clear app identity to read the device config for feature flag.
        final long identity = Binder.clearCallingIdentity();
        try {
            return DeviceConfig.getBoolean(NAMESPACE_COMPANION,
                    PROPERTY_PERM_SYNC_ENABLED, false);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }

    private FeatureUtils() {
+10 −0
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ import android.companion.IOnAssociationsChangedListener;
import android.companion.IOnMessageReceivedListener;
import android.companion.IOnTransportsChangedListener;
import android.companion.ISystemDataTransferCallback;
import android.companion.utils.FeatureUtils;
import android.content.ComponentName;
import android.content.Context;
import android.content.SharedPreferences;
@@ -746,6 +747,11 @@ public class CompanionDeviceManagerService extends SystemService {
        @Override
        public PendingIntent buildPermissionTransferUserConsentIntent(String packageName,
                int userId, int associationId) {
            if (!FeatureUtils.isPermSyncEnabled()) {
                throw new UnsupportedOperationException("Calling"
                        + " buildPermissionTransferUserConsentIntent, but this API is disabled by"
                        + " the system.");
            }
            return mSystemDataTransferProcessor.buildPermissionTransferUserConsentIntent(
                    packageName, userId, associationId);
        }
@@ -753,6 +759,10 @@ public class CompanionDeviceManagerService extends SystemService {
        @Override
        public void startSystemDataTransfer(String packageName, int userId, int associationId,
                ISystemDataTransferCallback callback) {
            if (!FeatureUtils.isPermSyncEnabled()) {
                throw new UnsupportedOperationException("Calling startSystemDataTransfer, but this"
                        + " API is disabled by the system.");
            }
            mSystemDataTransferProcessor.startSystemDataTransfer(packageName, userId,
                    associationId, callback);
        }
+2 −30
Original line number Diff line number Diff line
@@ -22,14 +22,10 @@ import static com.android.server.companion.transport.Transport.MESSAGE_REQUEST_P

import android.annotation.NonNull;
import android.annotation.SuppressLint;
import android.app.ActivityManagerInternal;
import android.companion.AssociationInfo;
import android.companion.IOnMessageReceivedListener;
import android.companion.IOnTransportsChangedListener;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Binder;
import android.os.Build;
import android.os.ParcelFileDescriptor;
import android.os.RemoteCallbackList;
@@ -38,7 +34,6 @@ import android.util.Slog;
import android.util.SparseArray;

import com.android.internal.annotations.GuardedBy;
import com.android.server.LocalServices;
import com.android.server.companion.AssociationStore;

import java.io.FileDescriptor;
@@ -143,32 +138,9 @@ public class CompanionTransportManager {
        }
    }

    /**
     * For the moment, we only offer transporting of system data to built-in
     * companion apps; future work will improve the security model to support
     * third-party companion apps.
     */
    private void enforceCallerCanTransportSystemData(String packageName, int userId) {
        mContext.enforceCallingOrSelfPermission(DELIVER_COMPANION_MESSAGES, TAG);

        try {
            final ApplicationInfo info = mContext.getPackageManager().getApplicationInfoAsUser(
                    packageName, 0, userId);
            final int instrumentationUid = LocalServices.getService(ActivityManagerInternal.class)
                    .getInstrumentationSourceUid(Binder.getCallingUid());
            if (!Build.isDebuggable() && !info.isSystemApp()
                    && instrumentationUid == android.os.Process.INVALID_UID) {
                throw new SecurityException("Transporting of system data currently only available "
                        + "to built-in companion apps or tests");
            }
        } catch (NameNotFoundException e) {
            throw new IllegalArgumentException(e);
        }
    }

    public void attachSystemDataTransport(String packageName, int userId, int associationId,
            ParcelFileDescriptor fd) {
        enforceCallerCanTransportSystemData(packageName, userId);
        mContext.enforceCallingOrSelfPermission(DELIVER_COMPANION_MESSAGES, TAG);
        synchronized (mTransports) {
            if (mTransports.contains(associationId)) {
                detachSystemDataTransport(packageName, userId, associationId);
@@ -182,7 +154,7 @@ public class CompanionTransportManager {
    }

    public void detachSystemDataTransport(String packageName, int userId, int associationId) {
        enforceCallerCanTransportSystemData(packageName, userId);
        mContext.enforceCallingOrSelfPermission(DELIVER_COMPANION_MESSAGES, TAG);
        synchronized (mTransports) {
            final Transport transport = mTransports.get(associationId);
            if (transport != null) {
+0 −7
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@ package com.android.server.companion.transport;
import android.annotation.NonNull;
import android.companion.IOnMessageReceivedListener;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
@@ -188,12 +187,6 @@ public abstract class Transport {
                break;
            }
            case MESSAGE_REQUEST_PERMISSION_RESTORE: {
                if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)
                        && !Build.isDebuggable()) {
                    Slog.w(TAG, "Restoring permissions only supported on watches");
                    sendMessage(MESSAGE_RESPONSE_FAILURE, sequence, EmptyArray.BYTE);
                    break;
                }
                try {
                    callback(message, data);
                    sendMessage(MESSAGE_RESPONSE_SUCCESS, sequence, EmptyArray.BYTE);