Skip to content

Commit 1692777

Browse files
johnstultz-workKAGA-KOKO
authored andcommitted
alarmtimer: Fix bug where relative alarm timers were treated as absolute
Sharvil noticed with the posix timer_settime interface, using the CLOCK_REALTIME_ALARM or CLOCK_BOOTTIME_ALARM clockid, if the users tried to specify a relative time timer, it would incorrectly be treated as absolute regardless of the state of the flags argument. This patch corrects this, properly checking the absolute/relative flag, as well as adds further error checking that no invalid flag bits are set. Reported-by: Sharvil Nanavati <[email protected]> Signed-off-by: John Stultz <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Prarit Bhargava <[email protected]> Cc: Sharvil Nanavati <[email protected]> Cc: stable <[email protected]> #3.0+ Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Thomas Gleixner <[email protected]>
1 parent e1a08b8 commit 1692777

File tree

1 file changed

+18
-2
lines changed

1 file changed

+18
-2
lines changed

kernel/time/alarmtimer.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -585,9 +585,14 @@ static int alarm_timer_set(struct k_itimer *timr, int flags,
585585
struct itimerspec *new_setting,
586586
struct itimerspec *old_setting)
587587
{
588+
ktime_t exp;
589+
588590
if (!rtcdev)
589591
return -ENOTSUPP;
590592

593+
if (flags & ~TIMER_ABSTIME)
594+
return -EINVAL;
595+
591596
if (old_setting)
592597
alarm_timer_get(timr, old_setting);
593598

@@ -597,8 +602,16 @@ static int alarm_timer_set(struct k_itimer *timr, int flags,
597602

598603
/* start the timer */
599604
timr->it.alarm.interval = timespec_to_ktime(new_setting->it_interval);
600-
alarm_start(&timr->it.alarm.alarmtimer,
601-
timespec_to_ktime(new_setting->it_value));
605+
exp = timespec_to_ktime(new_setting->it_value);
606+
/* Convert (if necessary) to absolute time */
607+
if (flags != TIMER_ABSTIME) {
608+
ktime_t now;
609+
610+
now = alarm_bases[timr->it.alarm.alarmtimer.type].gettime();
611+
exp = ktime_add(now, exp);
612+
}
613+
614+
alarm_start(&timr->it.alarm.alarmtimer, exp);
602615
return 0;
603616
}
604617

@@ -730,6 +743,9 @@ static int alarm_timer_nsleep(const clockid_t which_clock, int flags,
730743
if (!alarmtimer_get_rtcdev())
731744
return -ENOTSUPP;
732745

746+
if (flags & ~TIMER_ABSTIME)
747+
return -EINVAL;
748+
733749
if (!capable(CAP_WAKE_ALARM))
734750
return -EPERM;
735751

0 commit comments

Comments
 (0)