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

Commit 762259aa authored by Rafael Prado's avatar Rafael Prado
Browse files

Protect setPermissionGrantState coexistence code.

Bug: 370472975
Bug: 336297680
Flag: android.app.admin.flags.set_permission_grant_state_coexistence
Test: btest -s sw android.devicepolicy.cts.PermissionGrantTest with flag
disabled.

Change-Id: Ia9c366ad976ee84d85d9d280385be437fafbef38
parent b762d264
Loading
Loading
Loading
Loading
+31 −44
Original line number Diff line number Diff line
@@ -16815,6 +16815,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
            }
        }
        EnforcingAdmin enforcingAdmin;
        // TODO(b/370472975): enable when we stop policy enforecer callback from blocking the main
        //  thread
        if (Flags.setPermissionGrantStateCoexistence()) {
            enforcingAdmin = enforcePermissionAndGetEnforcingAdmin(
                    admin,
@@ -16840,6 +16843,31 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                callback.sendResult(null);
                return;
            }
            // TODO(b/266924257): decide how to handle the internal state if the package doesn't
            //  exist, or the permission isn't requested by the app, because we could end up with
            //  inconsistent state between the policy engine and package manager. Also a package
            //  might get removed or has it's permission updated after we've set the policy.
            if (grantState == PERMISSION_GRANT_STATE_DEFAULT) {
                mDevicePolicyEngine.removeLocalPolicy(
                        PolicyDefinition.PERMISSION_GRANT(packageName, permission),
                        enforcingAdmin,
                        caller.getUserId());
            } else {
                mDevicePolicyEngine.setLocalPolicy(
                        PolicyDefinition.PERMISSION_GRANT(packageName, permission),
                        enforcingAdmin,
                        new IntegerPolicyValue(grantState),
                        caller.getUserId());
            }
            int newState = mInjector.binderWithCleanCallingIdentity(() ->
                    getPermissionGrantStateForUser(
                            packageName, permission, caller, caller.getUserId()));
            if (newState == grantState) {
                callback.sendResult(Bundle.EMPTY);
            } else {
                callback.sendResult(null);
            }
        } else {
            Preconditions.checkCallAuthorization((caller.hasAdminComponent()
                    && (isProfileOwner(caller) || isDefaultDeviceOwner(caller)
@@ -16862,9 +16890,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
            }
            synchronized (getLockObject()) {
                long ident = mInjector.binderClearCallingIdentity();
                try {
                boolean isPostQAdmin = getTargetSdk(caller.getPackageName(), caller.getUserId())
                        >= android.os.Build.VERSION_CODES.Q;
                try {
                    if (!isPostQAdmin) {
                        // Legacy admins assume that they cannot control pre-M apps
                        if (getTargetSdk(packageName, caller.getUserId())
@@ -16877,47 +16906,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                        callback.sendResult(null);
                        return;
                    }
                } catch (SecurityException e) {
                    Slogf.e(LOG_TAG, "Could not set permission grant state", e);
                    callback.sendResult(null);
                } finally {
                    mInjector.binderRestoreCallingIdentity(ident);
                }
            }
        }
        // TODO(b/278710449): enable when we stop policy enforecer callback from blocking the main
        //  thread
        if (false) {
            // TODO(b/266924257): decide how to handle the internal state if the package doesn't
            //  exist, or the permission isn't requested by the app, because we could end up with
            //  inconsistent state between the policy engine and package manager. Also a package
            //  might get removed or has it's permission updated after we've set the policy.
            if (grantState == PERMISSION_GRANT_STATE_DEFAULT) {
                mDevicePolicyEngine.removeLocalPolicy(
                        PolicyDefinition.PERMISSION_GRANT(packageName, permission),
                        enforcingAdmin,
                        caller.getUserId());
            } else {
                mDevicePolicyEngine.setLocalPolicy(
                        PolicyDefinition.PERMISSION_GRANT(packageName, permission),
                        enforcingAdmin,
                        new IntegerPolicyValue(grantState),
                        caller.getUserId());
            }
            int newState = mInjector.binderWithCleanCallingIdentity(() ->
                    getPermissionGrantStateForUser(
                            packageName, permission, caller, caller.getUserId()));
            if (newState == grantState) {
                callback.sendResult(Bundle.EMPTY);
            } else {
                callback.sendResult(null);
            }
        } else {
            synchronized (getLockObject()) {
                long ident = mInjector.binderClearCallingIdentity();
                try {
                    boolean isPostQAdmin = getTargetSdk(caller.getPackageName(), caller.getUserId())
                            >= android.os.Build.VERSION_CODES.Q;
                    if (grantState == PERMISSION_GRANT_STATE_GRANTED
                            || grantState == DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED
                            || grantState == DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT) {
@@ -16939,7 +16927,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                    }
                } catch (SecurityException e) {
                    Slogf.e(LOG_TAG, "Could not set permission grant state", e);
                    callback.sendResult(null);
                } finally {
                    mInjector.binderRestoreCallingIdentity(ident);