[Spice-devel] [PATCH] Don't truncate large 'now' values in _spice_timer_set

David Gibson dgibson at redhat.com
Mon Mar 10 16:16:05 PDT 2014


On Mon, 10 Mar 2014 11:58:19 +0100
Christophe Fergeau <cfergeau at redhat.com> wrote:

> From: David Gibson <dgibson at redhat.com>
> 
> static void _spice_timer_set(SpiceTimer *timer, uint32_t ms, uint32_t now)
> 
> The _spice_timer_set() function takes a 32-bit integer for the "now" value.
> The now value passed in however, can exceed 2^32 (it's in ms and derived
> from CLOCK_MONOTONIC, which will wrap around a 32-bit integer in around 46
> days).
> 
> If the now value passed in exceeds 2^32, this will mean timers are inserted
> into the active list with expiry values before the current time, they will
> immediately trigger, and (if they don't make themselves inactive) be
> reinserted still before the current time.
> 
> This leads to an infinite loop in spice_timer_queue_cb().
> 
> https://bugzilla.redhat.com/show_bug.cgi?id=1072700

Thanks for sending that Christophe, I hadn't gotten around to sending
upstream.  Just to be clear here:

Signed-off-by: David Gibson <dgibson at redhat.com>


> ---
>  server/spice_timer_queue.c | 13 +++++++------
>  1 file changed, 7 insertions(+), 6 deletions(-)
> 
> diff --git a/server/spice_timer_queue.c b/server/spice_timer_queue.c
> index 8f6e9c8..71de84a 100644
> --- a/server/spice_timer_queue.c
> +++ b/server/spice_timer_queue.c
> @@ -147,7 +147,7 @@ SpiceTimer *spice_timer_queue_add(SpiceTimerFunc func, void *opaque)
>      return timer;
>  }
>  
> -static void _spice_timer_set(SpiceTimer *timer, uint32_t ms, uint32_t now)
> +static void _spice_timer_set(SpiceTimer *timer, uint32_t ms, uint64_t now)
>  {
>      RingItem *next_item;
>      SpiceTimerQueue *queue;
> @@ -183,7 +183,8 @@ void spice_timer_set(SpiceTimer *timer, uint32_t ms)
>      spice_assert(pthread_equal(timer->queue->thread, pthread_self()) != 0);
>  
>      clock_gettime(CLOCK_MONOTONIC, &now);
> -    _spice_timer_set(timer, ms, now.tv_sec * 1000 + (now.tv_nsec / 1000 / 1000));
> +    _spice_timer_set(timer, ms,
> +                     (uint64_t)now.tv_sec * 1000 + (now.tv_nsec / 1000 / 1000));
>  }
>  
>  void spice_timer_cancel(SpiceTimer *timer)
> @@ -217,7 +218,7 @@ void spice_timer_remove(SpiceTimer *timer)
>  unsigned int spice_timer_queue_get_timeout_ms(void)
>  {
>      struct timespec now;
> -    int now_ms;
> +    int64_t now_ms;
>      RingItem *head;
>      SpiceTimer *head_timer;
>      SpiceTimerQueue *queue = spice_timer_queue_find_with_lock();
> @@ -232,9 +233,9 @@ unsigned int spice_timer_queue_get_timeout_ms(void)
>      head_timer = SPICE_CONTAINEROF(head, SpiceTimer, active_link);
>  
>      clock_gettime(CLOCK_MONOTONIC, &now);
> -    now_ms = (now.tv_sec * 1000) - (now.tv_nsec / 1000 / 1000);
> +    now_ms = ((int64_t)now.tv_sec * 1000) - (now.tv_nsec / 1000 / 1000);
>  
> -    return MAX(0, ((int)head_timer->expiry_time - now_ms));
> +    return MAX(0, ((int64_t)head_timer->expiry_time - now_ms));
>  }
>  
>  
> @@ -252,7 +253,7 @@ void spice_timer_queue_cb(void)
>      }
>  
>      clock_gettime(CLOCK_MONOTONIC, &now);
> -    now_ms = (now.tv_sec * 1000) + (now.tv_nsec / 1000 / 1000);
> +    now_ms = ((uint64_t)now.tv_sec * 1000) + (now.tv_nsec / 1000 / 1000);
>  
>      while ((head = ring_get_head(&queue->active_timers))) {
>          SpiceTimer *timer = SPICE_CONTAINEROF(head, SpiceTimer, active_link);
> -- 
> 1.8.5.3
> 


-- 
David Gibson <dgibson at redhat.com>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/spice-devel/attachments/20140311/742b2c1e/attachment.pgp>


More information about the Spice-devel mailing list