87 lines
3.3 KiB
Diff
87 lines
3.3 KiB
Diff
|
From patchwork Tue Jun 26 13:21:31 2018
|
||
|
Content-Type: text/plain; charset="utf-8"
|
||
|
MIME-Version: 1.0
|
||
|
Content-Transfer-Encoding: 7bit
|
||
|
Subject: [1/2] posix-timers: Make forward callback return s64
|
||
|
From: Thomas Gleixner <tglx@linutronix.de>
|
||
|
X-Patchwork-Id: 10489059
|
||
|
Message-Id: <20180626132704.922098090@linutronix.de>
|
||
|
To: LKML <linux-kernel@vger.kernel.org>
|
||
|
Cc: John Stultz <john.stultz@linaro.org>,
|
||
|
Peter Zijlstra <peterz@infradead.org>,
|
||
|
Michael Kerrisk <mtk.manpages@gmail.com>, air icy <icytxw@gmail.com>
|
||
|
Date: Tue, 26 Jun 2018 15:21:31 +0200
|
||
|
|
||
|
The posix timer ti_overrun handling is broken because the forwarding
|
||
|
functions can return a huge number of overruns which does not fit in an
|
||
|
int. As a consequence timer_getoverrun(2) and siginfo::si_overrun can turn
|
||
|
into random number generators.
|
||
|
|
||
|
As a first step to address that let the timer_forward() callbacks return
|
||
|
the full 64 bit value.
|
||
|
|
||
|
Cast it to (int) temporarily until k_itimer::ti_overrun is converted to
|
||
|
64bit and the conversion to user space visible values is sanitized.
|
||
|
|
||
|
Reported-by: air icy <icytxw@gmail.com>
|
||
|
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
|
||
|
Acked-by: John Stultz <john.stultz@linaro.org>
|
||
|
---
|
||
|
kernel/time/alarmtimer.c | 4 ++--
|
||
|
kernel/time/posix-timers.c | 6 +++---
|
||
|
kernel/time/posix-timers.h | 2 +-
|
||
|
3 files changed, 6 insertions(+), 6 deletions(-)
|
||
|
|
||
|
--- a/kernel/time/alarmtimer.c
|
||
|
+++ b/kernel/time/alarmtimer.c
|
||
|
@@ -581,11 +581,11 @@ static void alarm_timer_rearm(struct k_i
|
||
|
* @timr: Pointer to the posixtimer data struct
|
||
|
* @now: Current time to forward the timer against
|
||
|
*/
|
||
|
-static int alarm_timer_forward(struct k_itimer *timr, ktime_t now)
|
||
|
+static s64 alarm_timer_forward(struct k_itimer *timr, ktime_t now)
|
||
|
{
|
||
|
struct alarm *alarm = &timr->it.alarm.alarmtimer;
|
||
|
|
||
|
- return (int) alarm_forward(alarm, timr->it_interval, now);
|
||
|
+ return alarm_forward(alarm, timr->it_interval, now);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
--- a/kernel/time/posix-timers.c
|
||
|
+++ b/kernel/time/posix-timers.c
|
||
|
@@ -645,11 +645,11 @@ static ktime_t common_hrtimer_remaining(
|
||
|
return __hrtimer_expires_remaining_adjusted(timer, now);
|
||
|
}
|
||
|
|
||
|
-static int common_hrtimer_forward(struct k_itimer *timr, ktime_t now)
|
||
|
+static s64 common_hrtimer_forward(struct k_itimer *timr, ktime_t now)
|
||
|
{
|
||
|
struct hrtimer *timer = &timr->it.real.timer;
|
||
|
|
||
|
- return (int)hrtimer_forward(timer, now, timr->it_interval);
|
||
|
+ return hrtimer_forward(timer, now, timr->it_interval);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
@@ -702,7 +702,7 @@ void common_timer_get(struct k_itimer *t
|
||
|
* expiry time forward by intervals, so expiry is > now.
|
||
|
*/
|
||
|
if (iv && (timr->it_requeue_pending & REQUEUE_PENDING || sig_none))
|
||
|
- timr->it_overrun += kc->timer_forward(timr, now);
|
||
|
+ timr->it_overrun += (int)kc->timer_forward(timr, now);
|
||
|
|
||
|
remaining = kc->timer_remaining(timr, now);
|
||
|
/* Return 0 only, when the timer is expired and not pending */
|
||
|
--- a/kernel/time/posix-timers.h
|
||
|
+++ b/kernel/time/posix-timers.h
|
||
|
@@ -19,7 +19,7 @@ struct k_clock {
|
||
|
void (*timer_get)(struct k_itimer *timr,
|
||
|
struct itimerspec64 *cur_setting);
|
||
|
void (*timer_rearm)(struct k_itimer *timr);
|
||
|
- int (*timer_forward)(struct k_itimer *timr, ktime_t now);
|
||
|
+ s64 (*timer_forward)(struct k_itimer *timr, ktime_t now);
|
||
|
ktime_t (*timer_remaining)(struct k_itimer *timr, ktime_t now);
|
||
|
int (*timer_try_to_cancel)(struct k_itimer *timr);
|
||
|
void (*timer_arm)(struct k_itimer *timr, ktime_t expires,
|