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

Commit 20b74584 authored by Yuting Fang's avatar Yuting Fang Committed by Android (Google) Code Review
Browse files

Merge "Prevent setting app op mode for device provisioning app through shell command" into main

parents 1a3eeb5c b3c3362b
Loading
Loading
Loading
Loading
+44 −0
Original line number Diff line number Diff line
@@ -182,6 +182,7 @@ import com.android.server.SystemServiceManager;
import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
import com.android.server.pm.PackageList;
import com.android.server.pm.PackageManagerLocal;
import com.android.server.pm.ProtectedPackages;
import com.android.server.pm.UserManagerInternal;
import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.pm.pkg.PackageState;
@@ -311,6 +312,8 @@ public class AppOpsService extends IAppOpsService.Stub {
    private final IPlatformCompat mPlatformCompat = IPlatformCompat.Stub.asInterface(
            ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));

    private ProtectedPackages mProtectedPackages;

    /**
     * Registered callbacks, called from {@link #collectAsyncNotedOp}.
     *
@@ -2128,6 +2131,12 @@ public class AppOpsService extends IAppOpsService.Stub {

        enforceManageAppOpsModes(Binder.getCallingPid(), Binder.getCallingUid(), uid);
        verifyIncomingOp(code);

        if (isDeviceProvisioningPackage(uid, null)) {
            Slog.w(TAG, "Cannot set uid mode for device provisioning app by Shell");
            return;
        }

        code = AppOpsManager.opToSwitch(code);

        if (permissionPolicyCallback == null) {
@@ -2438,6 +2447,11 @@ public class AppOpsService extends IAppOpsService.Stub {
            return;
        }

        if (isDeviceProvisioningPackage(uid, packageName)) {
            Slog.w(TAG, "Cannot set op mode for device provisioning app by Shell");
            return;
        }

        code = AppOpsManager.opToSwitch(code);

        PackageVerificationResult pvr;
@@ -2468,6 +2482,36 @@ public class AppOpsService extends IAppOpsService.Stub {
        notifyStorageManagerOpModeChangedSync(code, uid, packageName, mode, previousMode);
    }

    // Device provisioning package is restricted from setting app op mode through shell command
    private boolean isDeviceProvisioningPackage(int uid,
            @Nullable String packageName) {
        if (UserHandle.getAppId(Binder.getCallingUid()) == Process.SHELL_UID) {
            ProtectedPackages protectedPackages = getProtectedPackages();

            if (packageName != null && protectedPackages.isDeviceProvisioningPackage(packageName)) {
                return true;
            }

            String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid);
            if (packageNames != null) {
                for (String pkg : packageNames) {
                    if (protectedPackages.isDeviceProvisioningPackage(pkg)) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    // Race condition is allowed here for better performance
    private ProtectedPackages getProtectedPackages() {
        if (mProtectedPackages == null) {
            mProtectedPackages = new ProtectedPackages(mContext);
        }
        return mProtectedPackages;
    }

    private void notifyOpChanged(ArraySet<OnOpModeChangedListener> callbacks, int code,
            int uid, String packageName, String persistentDeviceId) {
        for (int i = 0; i < callbacks.size(); i++) {
+11 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.content.Context;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.SparseArray;

@@ -27,6 +28,7 @@ import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;

import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
@@ -164,4 +166,13 @@ public class ProtectedPackages {
        return hasDeviceOwnerOrProfileOwner(userId, packageName)
                || isProtectedPackage(userId, packageName);
    }

    /**
     * Returns {@code true} if a given package is the device provisioning package. Otherwise,
     * returns {@code false}.
     */
    public synchronized boolean isDeviceProvisioningPackage(String packageName) {
        return !TextUtils.isEmpty(mDeviceProvisioningPackage) && Objects.equals(
                mDeviceProvisioningPackage, packageName);
    }
}