Blame SOURCES/0042-Don-t-truncate-large-now-values-in-_spice_timer_set.patch

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