FAILED: patch "[PATCH] time: Prevent undefined behaviour in timespec64_to_ns()" failed to apply to 4.4-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.4-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From cb47755725da7b90fecbb2aa82ac3b24a7adb89b Mon Sep 17 00:00:00 2001
From: Zeng Tao <[email protected]>
Date: Tue, 1 Sep 2020 17:30:13 +0800
Subject: [PATCH] time: Prevent undefined behaviour in timespec64_to_ns()
UBSAN reports:
Undefined behaviour in ./include/linux/time64.h:127:27 signed integer overflow:
17179869187 * 1000000000 cannot be represented in type 'long long int'
Call Trace: timespec64_to_ns include/linux/time64.h:127 [inline] set_cpu_itimer+0x65c/0x880 kernel/time/itimer.c:180 do_setitimer+0x8e/0x740 kernel/time/itimer.c:245 __x64_sys_setitimer+0x14c/0x2c0 kernel/time/itimer.c:336 do_syscall_64+0xa1/0x540 arch/x86/entry/common.c:295
Commit bd40a175769d ("y2038: itimer: change implementation to timespec64") replaced the original conversion which handled time clamping correctly with timespec64_to_ns() which has no overflow protection.
Fix it in timespec64_to_ns() as this is not necessarily limited to the usage in itimers.
[ tglx: Added comment and adjusted the fixes tag ]
include/linux/time64.h +4 -0
@@ -124,6 +124,10 @@ static inline bool timespec64_valid_settod(const struct timespec64 *ts)*/ static inline s64 timespec64_to_ns (const struct timespec64 *ts) { +/* Prevent multiplication overflow */ +if ((unsigned long long )ts->tv_sec >=KTIME_SEC_MAX ) +return KTIME_MAX ; +return ((s64 ) ts->tv_sec *NSEC_PER_SEC ) + ts->tv_nsec; }
kernel/time/itimer.c +0 -4
@@ -172,10 +172,6 @@ static void set_cpu_itimer(struct task_struct *tsk, unsigned int clock_id,u64 oval, nval, ointerval, ninterval;struct cpu_itimer *it = &tsk->signal->it[clock_id]; -/* -* Use the to_ktime conversion because that clamps the maximum -* value to KTIME_MAX and avoid multiplication overflows. -*/ nval =timespec64_to_ns (&value->it_value); ninterval =timespec64_to_ns (&value->it_interval);