diff options
| author | 2025-03-12 14:40:08 -0700 | |
|---|---|---|
| committer | 2025-03-12 14:40:08 -0700 | |
| commit | 20b74584ce2f36a242cf14c1b2ac821fd7b93efe (patch) | |
| tree | 7b26c1d7592603ba7f293828967ec8fde7565ba8 | |
| parent | 1a3eeb5c63fdfd87406acb896ef3fa1af0d62d9d (diff) | |
| parent | b3c3362bc4fbc654a3bc15e79c4b4159b0e5e79a (diff) | |
Merge "Prevent setting app op mode for device provisioning app through shell command" into main
| -rw-r--r-- | services/core/java/com/android/server/appop/AppOpsService.java | 44 | ||||
| -rw-r--r-- | services/core/java/com/android/server/pm/ProtectedPackages.java | 11 |
2 files changed, 55 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index 286c4cd709b1..5ecac2253b49 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -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++) { diff --git a/services/core/java/com/android/server/pm/ProtectedPackages.java b/services/core/java/com/android/server/pm/ProtectedPackages.java index 524252c1469f..e71588168972 100644 --- a/services/core/java/com/android/server/pm/ProtectedPackages.java +++ b/services/core/java/com/android/server/pm/ProtectedPackages.java @@ -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); + } } |