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

Commit d0452521 authored by Suprabh Shukla's avatar Suprabh Shukla
Browse files

Not clearing data for a package that is a DO or PO

Added a check inside PackageManagerService to make sure data for a
package with a DO or PO for the running user is not cleared. Currently,
the 'pm clear' command goes through without any such checks.

Bug: b/27243904
Change-Id: I87d4ad2db031f47946f34627a5ee465ef144f85e
parent cd84059f
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -69,4 +69,13 @@ public abstract class DevicePolicyManagerInternal {
     * @return true if the uid is an active admin with the given policy.
     */
    public abstract boolean isActiveAdminWithPolicy(int uid, int reqPolicy);

    /**
     * Checks if a given package has a device or a profile owner for the given user
     *
     * @param packageName The package to check
     * @param userId the userId to check for.
     * @return true if package has a device or profile owner, false otherwise.
     */
    public abstract boolean hasDeviceOwnerOrProfileOwner(String packageName, int userId);
}
+8 −2
Original line number Diff line number Diff line
@@ -101,6 +101,8 @@ import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.ProfilerInfo;
import android.app.admin.DevicePolicyManager;
import android.app.admin.DevicePolicyManagerInternal;
import android.app.admin.IDevicePolicyManager;
import android.app.assist.AssistContent;
import android.app.assist.AssistStructure;
import android.app.backup.IBackupManager;
@@ -5261,9 +5263,13 @@ public final class ActivityManagerService extends ActivityManagerNative
    public boolean clearApplicationUserData(final String packageName,
            final IPackageDataObserver observer, int userId) {
        enforceNotIsolatedCaller("clearApplicationUserData");
        if (packageName != null && packageName.equals(mDeviceOwnerName)) {
            throw new SecurityException("Clearing DeviceOwner data is forbidden.");
        final DevicePolicyManagerInternal dpmi = LocalServices
                .getService(DevicePolicyManagerInternal.class);
        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
        }
        int uid = Binder.getCallingUid();
        int pid = Binder.getCallingPid();
        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
+10 −2
Original line number Diff line number Diff line
@@ -103,6 +103,7 @@ import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.IActivityManager;
import android.app.admin.DevicePolicyManagerInternal;
import android.app.admin.IDevicePolicyManager;
import android.app.backup.IBackupManager;
import android.content.BroadcastReceiver;
@@ -15110,8 +15111,15 @@ public class PackageManagerService extends IPackageManager.Stub {
            final IPackageDataObserver observer, final int userId) {
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.CLEAR_APP_USER_DATA, null);
        enforceCrossUserPermission(Binder.getCallingUid(), userId,
                true /* requireFullPermission */, false /* checkShell */, "clear application data");
        final DevicePolicyManagerInternal dpmi = LocalServices
                .getService(DevicePolicyManagerInternal.class);
        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
        }
        // Queue up an async operation since the package deletion may take a little while.
        mHandler.post(new Runnable() {
            public void run() {
@@ -15123,8 +15131,8 @@ public class PackageManagerService extends IPackageManager.Stub {
                clearExternalStorageDataSync(packageName, userId, true);
                if (succeeded) {
                    // invoke DeviceStorageMonitor's update method to clear any notifications
                    DeviceStorageMonitorInternal
                            dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
                    DeviceStorageMonitorInternal dsm = LocalServices
                            .getService(DeviceStorageMonitorInternal.class);
                    if (dsm != null) {
                        dsm.checkMemory();
                    }
+21 −2
Original line number Diff line number Diff line
@@ -32,7 +32,6 @@ import android.Manifest.permission;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.accounts.AccountManager;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
@@ -308,7 +307,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
     * Whether or not device admin feature is supported. If it isn't return defaults for all
     * public methods.
     */
    private boolean mHasFeature;
    boolean mHasFeature;

    private final SecurityLogMonitor mSecurityLogMonitor;

@@ -7810,6 +7809,26 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                listener.onCrossProfileWidgetProvidersChanged(userId, packages);
            }
        }

        @Override
        public boolean hasDeviceOwnerOrProfileOwner(String packageName, int userId) {
            if (!mHasFeature || packageName == null) {
                return false;
            }
            if (userId < 0) {
                throw new UnsupportedOperationException("userId should be >= 0");
            }
            synchronized (DevicePolicyManagerService.this) {
                if (packageName.equals(mOwners.getProfileOwnerPackage(userId))) {
                    return true;
                }
                if (userId == mOwners.getDeviceOwnerUserId()
                        && packageName.equals(mOwners.getDeviceOwnerPackageName())) {
                    return true;
                }
            }
            return false;
        }
    }

    /**