summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author yutingfang <yutingfang@google.com> 2025-02-05 17:13:25 -0800
committer yutingfang <yutingfang@google.com> 2025-02-26 16:20:45 -0800
commitb3c3362bc4fbc654a3bc15e79c4b4159b0e5e79a (patch)
treeaf295035eaca20095f2bcc0130bd27cce3945d2c
parentb86c4a61e78cf0244a100a4efaf31ae51a76fb58 (diff)
Prevent setting app op mode for device provisioning app through shell
command For security reasons, device provisioning package should be restricted from setting app op mode through shell command. Bug: 330507809 Test: Manual through adb shell command Flag: EXEMPT bug fix Change-Id: Ifa2ea860054c90a69834e95c24307d2cc2d28a45
-rw-r--r--services/core/java/com/android/server/appop/AppOpsService.java44
-rw-r--r--services/core/java/com/android/server/pm/ProtectedPackages.java11
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 c8b8909f203f..644708073da8 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}.
*
@@ -2121,6 +2124,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) {
@@ -2431,6 +2440,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;
@@ -2461,6 +2475,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);
+ }
}