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

Commit a39afd3f authored by Matías Hernández's avatar Matías Hernández Committed by Android (Google) Code Review
Browse files

Merge "Fix rule ownership check when notifying from a ConditionProviderService" into main

parents ca4dc167 65f78534
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -325,7 +325,7 @@ public class ConditionProviders extends ManagedServices {
        for (int i = 0; i < N; i++) {
            final Condition c = conditions[i];
            if (mCallback != null) {
                mCallback.onConditionChanged(c.id, c);
                mCallback.onConditionChanged(c.id, c, info.uid);
            }
        }
    }
@@ -515,7 +515,7 @@ public class ConditionProviders extends ManagedServices {

    public interface Callback {
        void onServiceAdded(ComponentName component);
        void onConditionChanged(Uri id, Condition condition);
        void onConditionChanged(Uri id, Condition condition, int callerUid);
    }

}
+12 −8
Original line number Diff line number Diff line
@@ -5903,8 +5903,9 @@ public class NotificationManagerService extends SystemService {
        // TODO: b/310620812 - Remove getZenRules() when MODES_API is inlined.
        @Override
        public List<ZenModeConfig.ZenRule> getZenRules() throws RemoteException {
            enforcePolicyAccess(Binder.getCallingUid(), "getZenRules");
            return mZenModeHelper.getZenRules(getCallingZenUser());
            int callingUid = Binder.getCallingUid();
            enforcePolicyAccess(callingUid, "getZenRules");
            return mZenModeHelper.getZenRules(getCallingZenUser(), callingUid);
        }
        @Override
@@ -5912,15 +5913,17 @@ public class NotificationManagerService extends SystemService {
            if (!android.app.Flags.modesApi()) {
                throw new IllegalStateException("getAutomaticZenRules called with flag off!");
            }
            enforcePolicyAccess(Binder.getCallingUid(), "getAutomaticZenRules");
            return mZenModeHelper.getAutomaticZenRules(getCallingZenUser());
            int callingUid = Binder.getCallingUid();
            enforcePolicyAccess(callingUid, "getAutomaticZenRules");
            return mZenModeHelper.getAutomaticZenRules(getCallingZenUser(), callingUid);
        }
        @Override
        public AutomaticZenRule getAutomaticZenRule(String id) throws RemoteException {
            Objects.requireNonNull(id, "Id is null");
            enforcePolicyAccess(Binder.getCallingUid(), "getAutomaticZenRule");
            return mZenModeHelper.getAutomaticZenRule(getCallingZenUser(), id);
            int callingUid = Binder.getCallingUid();
            enforcePolicyAccess(callingUid, "getAutomaticZenRule");
            return mZenModeHelper.getAutomaticZenRule(getCallingZenUser(), id, callingUid);
        }
        @Override
@@ -6065,8 +6068,9 @@ public class NotificationManagerService extends SystemService {
        @Condition.State
        public int getAutomaticZenRuleState(@NonNull String id) {
            Objects.requireNonNull(id, "id is null");
            enforcePolicyAccess(Binder.getCallingUid(), "getAutomaticZenRuleState");
            return mZenModeHelper.getAutomaticZenRuleState(getCallingZenUser(), id);
            int callingUid = Binder.getCallingUid();
            enforcePolicyAccess(callingUid, "getAutomaticZenRuleState");
            return mZenModeHelper.getAutomaticZenRuleState(getCallingZenUser(), id, callingUid);
        }
        @Override
+6 −3
Original line number Diff line number Diff line
@@ -113,15 +113,18 @@ public class ZenModeConditions implements ConditionProviders.Callback {
    }

    @Override
    public void onConditionChanged(Uri id, Condition condition) {
    public void onConditionChanged(Uri id, Condition condition, int callingUid) {
        if (DEBUG) Log.d(TAG, "onConditionChanged " + id + " " + condition);
        ZenModeConfig config = mHelper.getConfig();
        if (config == null) return;
        final int callingUid = Binder.getCallingUid();
        if (!Flags.fixCallingUidFromCps()) {
            // Old behavior: overwrite with known-bad callingUid (always system_server).
            callingUid = Binder.getCallingUid();
        }

        // This change is known to be for UserHandle.CURRENT because ConditionProviders for
        // background users are not bound.
        mHelper.setAutomaticZenRuleState(UserHandle.CURRENT, id, condition,
        mHelper.setAutomaticZenRuleStateFromConditionProvider(UserHandle.CURRENT, id, condition,
                callingUid == Process.SYSTEM_UID ? ZenModeConfig.ORIGIN_SYSTEM
                        : ZenModeConfig.ORIGIN_APP,
                callingUid);
+27 −20
Original line number Diff line number Diff line
@@ -413,13 +413,13 @@ public class ZenModeHelper {
    }

    // TODO: b/310620812 - Make private (or inline) when MODES_API is inlined.
    public List<ZenRule> getZenRules(UserHandle user) {
    public List<ZenRule> getZenRules(UserHandle user, int callingUid) {
        List<ZenRule> rules = new ArrayList<>();
        synchronized (mConfigLock) {
            ZenModeConfig config = getConfigLocked(user);
            if (config == null) return rules;
            for (ZenRule rule : config.automaticRules.values()) {
                if (canManageAutomaticZenRule(rule)) {
                if (canManageAutomaticZenRule(rule, callingUid)) {
                    rules.add(rule);
                }
            }
@@ -432,8 +432,8 @@ public class ZenModeHelper {
     * (which means the owned rules for a regular app, and every rule for system callers) together
     * with their ids.
     */
    Map<String, AutomaticZenRule> getAutomaticZenRules(UserHandle user) {
        List<ZenRule> ruleList = getZenRules(user);
    Map<String, AutomaticZenRule> getAutomaticZenRules(UserHandle user, int callingUid) {
        List<ZenRule> ruleList = getZenRules(user, callingUid);
        HashMap<String, AutomaticZenRule> rules = new HashMap<>(ruleList.size());
        for (ZenRule rule : ruleList) {
            rules.put(rule.id, zenRuleToAutomaticZenRule(rule));
@@ -441,7 +441,7 @@ public class ZenModeHelper {
        return rules;
    }

    public AutomaticZenRule getAutomaticZenRule(UserHandle user, String id) {
    public AutomaticZenRule getAutomaticZenRule(UserHandle user, String id, int callingUid) {
        ZenRule rule;
        synchronized (mConfigLock) {
            ZenModeConfig config = getConfigLocked(user);
@@ -449,7 +449,7 @@ public class ZenModeHelper {
            rule = config.automaticRules.get(id);
        }
        if (rule == null) return null;
        if (canManageAutomaticZenRule(rule)) {
        if (canManageAutomaticZenRule(rule, callingUid)) {
            return zenRuleToAutomaticZenRule(rule);
        }
        return null;
@@ -591,7 +591,7 @@ public class ZenModeHelper {
                        + " reason=" + reason);
            }
            ZenModeConfig.ZenRule oldRule = config.automaticRules.get(ruleId);
            if (oldRule == null || !canManageAutomaticZenRule(oldRule)) {
            if (oldRule == null || !canManageAutomaticZenRule(oldRule, callingUid)) {
                throw new SecurityException(
                        "Cannot update rules not owned by your condition provider");
            }
@@ -859,7 +859,7 @@ public class ZenModeHelper {
            newConfig = config.copy();
            ZenRule ruleToRemove = newConfig.automaticRules.get(id);
            if (ruleToRemove == null) return false;
            if (canManageAutomaticZenRule(ruleToRemove)) {
            if (canManageAutomaticZenRule(ruleToRemove, callingUid)) {
                newConfig.automaticRules.remove(id);
                maybePreserveRemovedRule(newConfig, ruleToRemove, origin);
                if (ruleToRemove.getPkg() != null
@@ -893,7 +893,8 @@ public class ZenModeHelper {
            newConfig = config.copy();
            for (int i = newConfig.automaticRules.size() - 1; i >= 0; i--) {
                ZenRule rule = newConfig.automaticRules.get(newConfig.automaticRules.keyAt(i));
                if (Objects.equals(rule.getPkg(), packageName) && canManageAutomaticZenRule(rule)) {
                if (Objects.equals(rule.getPkg(), packageName)
                        && canManageAutomaticZenRule(rule, callingUid)) {
                    newConfig.automaticRules.removeAt(i);
                    maybePreserveRemovedRule(newConfig, rule, origin);
                }
@@ -938,14 +939,14 @@ public class ZenModeHelper {
    }

    @Condition.State
    int getAutomaticZenRuleState(UserHandle user, String id) {
    int getAutomaticZenRuleState(UserHandle user, String id, int callingUid) {
        synchronized (mConfigLock) {
            ZenModeConfig config = getConfigLocked(user);
            if (config == null) {
                return Condition.STATE_UNKNOWN;
            }
            ZenRule rule = config.automaticRules.get(id);
            if (rule == null || !canManageAutomaticZenRule(rule)) {
            if (rule == null || !canManageAutomaticZenRule(rule, callingUid)) {
                return Condition.STATE_UNKNOWN;
            }
            if (Flags.modesApi() && Flags.modesUi()) {
@@ -968,7 +969,7 @@ public class ZenModeHelper {
            newConfig = config.copy();
            ZenRule rule = newConfig.automaticRules.get(id);
            if (Flags.modesApi()) {
                if (rule != null && canManageAutomaticZenRule(rule)) {
                if (rule != null && canManageAutomaticZenRule(rule, callingUid)) {
                    setAutomaticZenRuleStateLocked(newConfig, Collections.singletonList(rule),
                            condition, origin, callingUid);
                }
@@ -980,8 +981,8 @@ public class ZenModeHelper {
        }
    }

    void setAutomaticZenRuleState(UserHandle user, Uri ruleDefinition, Condition condition,
            @ConfigOrigin int origin, int callingUid) {
    void setAutomaticZenRuleStateFromConditionProvider(UserHandle user, Uri ruleDefinition,
            Condition condition, @ConfigOrigin int origin, int callingUid) {
        checkSetRuleStateOrigin("setAutomaticZenRuleState(Uri ruleDefinition)", origin);
        ZenModeConfig newConfig;
        synchronized (mConfigLock) {
@@ -992,7 +993,7 @@ public class ZenModeHelper {
            List<ZenRule> matchingRules = findMatchingRules(newConfig, ruleDefinition, condition);
            if (Flags.modesApi()) {
                for (int i = matchingRules.size() - 1; i >= 0; i--) {
                    if (!canManageAutomaticZenRule(matchingRules.get(i))) {
                    if (!canManageAutomaticZenRule(matchingRules.get(i), callingUid)) {
                        matchingRules.remove(i);
                    }
                }
@@ -1125,15 +1126,21 @@ public class ZenModeHelper {
        return count;
    }

    public boolean canManageAutomaticZenRule(ZenRule rule) {
        final int callingUid = Binder.getCallingUid();
    public boolean canManageAutomaticZenRule(ZenRule rule, int callingUid) {
        if (!com.android.server.notification.Flags.fixCallingUidFromCps()) {
            // Old behavior: ignore supplied callingUid and instead obtain it here. Will be
            // incorrect if not currently handling a Binder call.
            callingUid = Binder.getCallingUid();
        }

        if (callingUid == 0 || callingUid == Process.SYSTEM_UID) {
            // Checked specifically, because checkCallingPermission() will fail.
            return true;
        } else if (mContext.checkCallingPermission(android.Manifest.permission.MANAGE_NOTIFICATIONS)
                == PackageManager.PERMISSION_GRANTED) {
            return true;
        } else {
            String[] packages = mPm.getPackagesForUid(Binder.getCallingUid());
            String[] packages = mPm.getPackagesForUid(callingUid);
            if (packages != null) {
                final int packageCount = packages.length;
                for (int i = 0; i < packageCount; i++) {
@@ -2902,8 +2909,8 @@ public class ZenModeHelper {
    }

    /**
     * Checks that the {@code origin} supplied to {@link #setAutomaticZenRuleState} overloads makes
     * sense.
     * Checks that the {@code origin} supplied to {@link #setAutomaticZenRuleState} or
     * {@link #setAutomaticZenRuleStateFromConditionProvider} makes sense.
     */
    private static void checkSetRuleStateOrigin(String method, @ConfigOrigin int origin) {
        if (!Flags.modesApi()) {
+11 −1
Original line number Diff line number Diff line
@@ -197,3 +197,13 @@ flag {
    purpose: PURPOSE_BUGFIX
  }
}

flag {
  name: "fix_calling_uid_from_cps"
  namespace: "systemui"
  description: "Correctly checks zen rule ownership when a CPS notifies with a Condition"
  bug: "379722187"
  metadata {
    purpose: PURPOSE_BUGFIX
  }
}
Loading