[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20190306131326.10275-3-yaohongbo@huawei.com>
Date: Wed, 6 Mar 2019 21:13:26 +0800
From: Hongbo Yao <yaohongbo@...wei.com>
To: <tglx@...utronix.de>, <edumazet@...gle.com>,
<linux-kernel@...r.kernel.org>, <yaohongbo@...wei.com>
Subject: [RFC PATCH 2/2] hrtimer: Prevent overflow for relative refrences
I ran Syzkaller testsuite, and got the following call trace.
===============================================================
UBSAN: Undefined behaviour in ../kernel/time/hrtimer.c:514:11
signed integer overflow:
9223372036854775807 - -240652746 cannot be represented in type 'long
long int'
CPU: 1 PID: 9308 Comm: trinity-c5 Not tainted 4.19.25-dirty #4
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
rel-1.12.0-0-ga698c8995f-prebuilt.qemu.org 04/01/2014
Call Trace:
<IRQ>
dump_stack+0xdd/0x12a
ubsan_epilogue+0x10/0x65
handle_overflow+0x1a8/0x212
? val_to_string.constprop.2+0x137/0x137
? print_lock_contention_bug+0x190/0x190
? __next_base+0x2b/0xc0
? __hrtimer_run_queues+0xca/0x830
__ubsan_handle_sub_overflow+0x11/0x19
__hrtimer_next_event_base+0x1a9/0x1b0
__hrtimer_get_next_event+0x96/0x140
hrtimer_interrupt+0x391/0x610
smp_apic_timer_interrupt+0x137/0x3d0
apic_timer_interrupt+0xf/0x20
===============================================================
Use ktime_sub_safe() which has the necessary sanity checks in place and
limits the result to the valid range.
Signed-off-by: Hongbo Yao <yaohongbo@...wei.com>
---
kernel/time/hrtimer.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index cadc5bcbfc9e..2195b35af085 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -527,7 +527,8 @@ static ktime_t __hrtimer_next_event_base(struct hrtimer_cpu_base *cpu_base,
timer = container_of(next, struct hrtimer, node);
}
- expires = ktime_sub(hrtimer_get_expires(timer), base->offset);
+ expires = ktime_sub_safe(hrtimer_get_expires(timer),
+ base->offset);
if (expires < expires_next) {
expires_next = expires;
@@ -781,7 +782,8 @@ static void hrtimer_reprogram(struct hrtimer *timer, bool reprogram)
{
struct hrtimer_cpu_base *cpu_base = this_cpu_ptr(&hrtimer_bases);
struct hrtimer_clock_base *base = timer->base;
- ktime_t expires = ktime_sub(hrtimer_get_expires(timer), base->offset);
+ ktime_t expires = ktime_sub_safe(hrtimer_get_expires(timer),
+ base->offset);
WARN_ON_ONCE(hrtimer_get_expires_tv64(timer) < 0);
--
2.20.1
Powered by blists - more mailing lists