From 597285ca58770f3c9495aa91fbf24129b01cf426 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 20 Jan 2019 22:18:17 +0100 Subject: Cygwin: timerfd: fix read(2) running wild - On systems with inexact realtime clock, the current timestamp may be fractionally smaller than the desired timestamp. This breaks the computation for incrementing overrun_count so overrun_count may end up as 0. Expiring the timer with an overrun_count of 0 is a no-go. Make sure we always increment overrun_count by at least one after timer expiry. - Do not expire the timer when another process deletes its timer_tracker. This, too, may result in a 0 overrun_count. Signed-off-by: Corinna Vinschen --- winsup/cygwin/timerfd.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/timerfd.cc b/winsup/cygwin/timerfd.cc index ae26004a4..dbb63e676 100644 --- a/winsup/cygwin/timerfd.cc +++ b/winsup/cygwin/timerfd.cc @@ -69,6 +69,9 @@ timerfd_tracker::thread_func () LONG64 now = get_clock_now (); LONG64 ts = get_exp_ts (); + /* Make concessions for unexact realtime clock */ + if (ts > now) + ts = now - 1; increment_overrun_count ((now - ts + get_interval () - 1) / get_interval ()); /* Set exp_ts to current timestamp. Make sure exp_ts ends up @@ -251,7 +254,6 @@ timerfd_shared::dtor () { return false; } - timer_expired (); disarm_timer (); NtClose (_timer); NtClose (_arm_evt); -- cgit v1.2.3