|
|
2be4b2 |
From d6f73e30020e0e2cbe6ee48d5f1bf38e0587ba83 Mon Sep 17 00:00:00 2001
|
|
|
2be4b2 |
From: David Gibson <dgibson@redhat.com>
|
|
|
2be4b2 |
Date: Mon, 10 Mar 2014 11:55:47 +0100
|
|
|
2be4b2 |
Subject: [PATCH] Don't truncate large 'now' values in _spice_timer_set
|
|
|
2be4b2 |
|
|
|
2be4b2 |
static void _spice_timer_set(SpiceTimer *timer, uint32_t ms, uint32_t now)
|
|
|
2be4b2 |
|
|
|
2be4b2 |
The _spice_timer_set() function takes a 32-bit integer for the "now" value.
|
|
|
2be4b2 |
The now value passed in however, can exceed 2^32 (it's in ms and derived
|
|
|
2be4b2 |
from CLOCK_MONOTONIC, which will wrap around a 32-bit integer in around 46
|
|
|
2be4b2 |
days).
|
|
|
2be4b2 |
|
|
|
2be4b2 |
If the now value passed in exceeds 2^32, this will mean timers are inserted
|
|
|
2be4b2 |
into the active list with expiry values before the current time, they will
|
|
|
2be4b2 |
immediately trigger, and (if they don't make themselves inactive) be
|
|
|
2be4b2 |
reinserted still before the current time.
|
|
|
2be4b2 |
|
|
|
2be4b2 |
This leads to an infinite loop in spice_timer_queue_cb().
|
|
|
2be4b2 |
|
|
|
2be4b2 |
https://bugzilla.redhat.com/show_bug.cgi?id=1072700
|
|
|
2be4b2 |
---
|
|
|
2be4b2 |
server/spice_timer_queue.c | 13 +++++++------
|
|
|
2be4b2 |
1 file changed, 7 insertions(+), 6 deletions(-)
|
|
|
2be4b2 |
|
|
|
2be4b2 |
diff --git a/server/spice_timer_queue.c b/server/spice_timer_queue.c
|
|
|
2be4b2 |
index 8f6e9c8..71de84a 100644
|
|
|
2be4b2 |
--- a/server/spice_timer_queue.c
|
|
|
2be4b2 |
+++ b/server/spice_timer_queue.c
|
|
|
2be4b2 |
@@ -147,7 +147,7 @@ SpiceTimer *spice_timer_queue_add(SpiceTimerFunc func, void *opaque)
|
|
|
2be4b2 |
return timer;
|
|
|
2be4b2 |
}
|
|
|
2be4b2 |
|
|
|
2be4b2 |
-static void _spice_timer_set(SpiceTimer *timer, uint32_t ms, uint32_t now)
|
|
|
2be4b2 |
+static void _spice_timer_set(SpiceTimer *timer, uint32_t ms, uint64_t now)
|
|
|
2be4b2 |
{
|
|
|
2be4b2 |
RingItem *next_item;
|
|
|
2be4b2 |
SpiceTimerQueue *queue;
|
|
|
2be4b2 |
@@ -183,7 +183,8 @@ void spice_timer_set(SpiceTimer *timer, uint32_t ms)
|
|
|
2be4b2 |
spice_assert(pthread_equal(timer->queue->thread, pthread_self()) != 0);
|
|
|
2be4b2 |
|
|
|
2be4b2 |
clock_gettime(CLOCK_MONOTONIC, &now;;
|
|
|
2be4b2 |
- _spice_timer_set(timer, ms, now.tv_sec * 1000 + (now.tv_nsec / 1000 / 1000));
|
|
|
2be4b2 |
+ _spice_timer_set(timer, ms,
|
|
|
2be4b2 |
+ (uint64_t)now.tv_sec * 1000 + (now.tv_nsec / 1000 / 1000));
|
|
|
2be4b2 |
}
|
|
|
2be4b2 |
|
|
|
2be4b2 |
void spice_timer_cancel(SpiceTimer *timer)
|
|
|
2be4b2 |
@@ -217,7 +218,7 @@ void spice_timer_remove(SpiceTimer *timer)
|
|
|
2be4b2 |
unsigned int spice_timer_queue_get_timeout_ms(void)
|
|
|
2be4b2 |
{
|
|
|
2be4b2 |
struct timespec now;
|
|
|
2be4b2 |
- int now_ms;
|
|
|
2be4b2 |
+ int64_t now_ms;
|
|
|
2be4b2 |
RingItem *head;
|
|
|
2be4b2 |
SpiceTimer *head_timer;
|
|
|
2be4b2 |
SpiceTimerQueue *queue = spice_timer_queue_find_with_lock();
|
|
|
2be4b2 |
@@ -232,9 +233,9 @@ unsigned int spice_timer_queue_get_timeout_ms(void)
|
|
|
2be4b2 |
head_timer = SPICE_CONTAINEROF(head, SpiceTimer, active_link);
|
|
|
2be4b2 |
|
|
|
2be4b2 |
clock_gettime(CLOCK_MONOTONIC, &now;;
|
|
|
2be4b2 |
- now_ms = (now.tv_sec * 1000) - (now.tv_nsec / 1000 / 1000);
|
|
|
2be4b2 |
+ now_ms = ((int64_t)now.tv_sec * 1000) - (now.tv_nsec / 1000 / 1000);
|
|
|
2be4b2 |
|
|
|
2be4b2 |
- return MAX(0, ((int)head_timer->expiry_time - now_ms));
|
|
|
2be4b2 |
+ return MAX(0, ((int64_t)head_timer->expiry_time - now_ms));
|
|
|
2be4b2 |
}
|
|
|
2be4b2 |
|
|
|
2be4b2 |
|
|
|
2be4b2 |
@@ -252,7 +253,7 @@ void spice_timer_queue_cb(void)
|
|
|
2be4b2 |
}
|
|
|
2be4b2 |
|
|
|
2be4b2 |
clock_gettime(CLOCK_MONOTONIC, &now;;
|
|
|
2be4b2 |
- now_ms = (now.tv_sec * 1000) + (now.tv_nsec / 1000 / 1000);
|
|
|
2be4b2 |
+ now_ms = ((uint64_t)now.tv_sec * 1000) + (now.tv_nsec / 1000 / 1000);
|
|
|
2be4b2 |
|
|
|
2be4b2 |
while ((head = ring_get_head(&queue->active_timers))) {
|
|
|
2be4b2 |
SpiceTimer *timer = SPICE_CONTAINEROF(head, SpiceTimer, active_link);
|
|
|
2be4b2 |
--
|
|
|
2be4b2 |
2.4.4
|
|
|
2be4b2 |
|