Skip to content

Commit

Permalink
iv_timer: Protect against some cases of timer memory corruption.
Browse files Browse the repository at this point in the history
In one recent report, ivykis was getting into an infinite loop in
iv_run_timers() because of a registered iv_timer struct having
become corrupted.

Specifically, this timer was actually on the timer heap, but with a
heap index (->index) of zero, which normally indicates that the timer
is on the expired list, and ->list_expired.{next,prev} pointing to
writeable memory.  When this timer would then get to the root of the
heap, we would get into an infinite loop calling iv_timer_unregister()
on this timer, which ought to remove the timer from the heap, but in
this case wouldn't, as its heap index was already zero.

We can catch this case by making sure that whenever a timer expires
and we try to remove it from the heap, its heap index is equal to 1,
which signifies the root position, and abort if otherwise.

Signed-off-by: Lennert Buytenhek <[email protected]>
  • Loading branch information
buytenh committed Jun 16, 2018
1 parent cdcde54 commit 8f8eb78
Showing 1 changed file with 5 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/iv_timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ void iv_run_timers(struct iv_state *st)
while (st->num_timers) {
struct iv_timer_ *t = st->ratnode.first_leaf.child[1];

if (t->index != 1) {
iv_fatal("iv_run_timers: root timer has heap "
"index %d", t->index);
}

if (timespec_gt(&t->expires, &st->time))
break;
iv_timer_unregister((struct iv_timer *)t);
Expand Down

0 comments on commit 8f8eb78

Please sign in to comment.