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

Commit 498c6cbd authored by Christopher Tate's avatar Christopher Tate
Browse files

Prevent some alarm pathologies

* Sanity-check the recurrence interval.  Some buggy apps pass seconds
  where the API expects milliseconds, with the result that the device
  pins the CPU at 100% trying to deliver alarm broadcasts every 60 ms
  or what have you.  The minimum recurrence is now 1 minute.

* Sanity-check alarms being scheduled for the immediate future.  As
  with the above this will catch people trying to schedule alarms
  in a spammy way that keeps the device from entering low-power state.
  The minimum futurity of a new alarm is now 5 seconds.

Bug 17495168

Change-Id: If8ff7d88da48960532ac21a0ba20094af9912603
parent c9f1b3a0
Loading
Loading
Loading
Loading
+20 −1
Original line number Original line Diff line number Diff line
@@ -75,6 +75,12 @@ class AlarmManagerService extends SystemService {
    // warning message.  The time duration is in milliseconds.
    // warning message.  The time duration is in milliseconds.
    private static final long LATE_ALARM_THRESHOLD = 10 * 1000;
    private static final long LATE_ALARM_THRESHOLD = 10 * 1000;


    // Minimum futurity of a new alarm
    private static final long MIN_FUTURITY = 5 * 1000;  // 5 seconds, in millis

    // Minimum alarm recurrence interval
    private static final long MIN_INTERVAL = 60 * 1000;  // one minute, in millis

    private static final int RTC_WAKEUP_MASK = 1 << RTC_WAKEUP;
    private static final int RTC_WAKEUP_MASK = 1 << RTC_WAKEUP;
    private static final int RTC_MASK = 1 << RTC;
    private static final int RTC_MASK = 1 << RTC;
    private static final int ELAPSED_REALTIME_WAKEUP_MASK = 1 << ELAPSED_REALTIME_WAKEUP;
    private static final int ELAPSED_REALTIME_WAKEUP_MASK = 1 << ELAPSED_REALTIME_WAKEUP;
@@ -696,6 +702,15 @@ class AlarmManagerService extends SystemService {
            windowLength = AlarmManager.INTERVAL_HOUR;
            windowLength = AlarmManager.INTERVAL_HOUR;
        }
        }


        // Sanity check the recurrence interval.  This will catch people who supply
        // seconds when the API expects milliseconds.
        if (interval > 0 && interval < MIN_INTERVAL) {
            Slog.w(TAG, "Suspiciously short interval " + interval
                    + " millis; expanding to " + (int)(MIN_INTERVAL/1000)
                    + " seconds");
            interval = MIN_INTERVAL;
        }

        if (type < RTC_WAKEUP || type > ELAPSED_REALTIME) {
        if (type < RTC_WAKEUP || type > ELAPSED_REALTIME) {
            throw new IllegalArgumentException("Invalid alarm type " + type);
            throw new IllegalArgumentException("Invalid alarm type " + type);
        }
        }
@@ -709,7 +724,11 @@ class AlarmManagerService extends SystemService {
        }
        }


        final long nowElapsed = SystemClock.elapsedRealtime();
        final long nowElapsed = SystemClock.elapsedRealtime();
        final long triggerElapsed = convertToElapsed(triggerAtTime, type);
        final long nominalTrigger = convertToElapsed(triggerAtTime, type);
        // Try to prevent spamming by making sure we aren't firing alarms in the immediate future
        final long minTrigger = nowElapsed + MIN_FUTURITY;
        final long triggerElapsed = (nominalTrigger > minTrigger) ? nominalTrigger : minTrigger;

        final long maxElapsed;
        final long maxElapsed;
        if (windowLength == AlarmManager.WINDOW_EXACT) {
        if (windowLength == AlarmManager.WINDOW_EXACT) {
            maxElapsed = triggerElapsed;
            maxElapsed = triggerElapsed;