Loading services/core/java/com/android/server/appop/AppOpsService.java +44 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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}. * Loading Loading @@ -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) { Loading Loading @@ -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; Loading Loading @@ -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++) { Loading services/core/java/com/android/server/pm/ProtectedPackages.java +11 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; /** Loading Loading @@ -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); } } Loading
services/core/java/com/android/server/appop/AppOpsService.java +44 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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}. * Loading Loading @@ -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) { Loading Loading @@ -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; Loading Loading @@ -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++) { Loading
services/core/java/com/android/server/pm/ProtectedPackages.java +11 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; /** Loading Loading @@ -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); } }