[libvirt] [PATCHv2] util: make it more robust to calculate timeout value

Peter Krempa pkrempa at redhat.com
Fri May 22 15:59:33 UTC 2015


On Fri, May 22, 2015 at 15:52:25 +0800, Wang Yufei wrote:
> From: Zhang Bo <oscar.zhangbo at huawei.com>
> 
> When we change system clock to years ago, a certain CPU may use up 100% cputime.
> The reason is that in function virEventPollCalculateTimeout(), we assign the
> unsigned long long result to an INT variable,
>         *timeout = then - now; // timeout is INT, and then/now are long long
>         if (*timeout < 0)
>             *timeout = 0;
> there's a chance that variable @then minus variable @now may be a very large number
> that overflows INT value expression, then *timeout will be negative and be assigned to 0.
> Next the 'poll' in function virEventPollRunOnce() will get into an 'endless' while loop there.
> thus, the cpu that virEventPollRunOnce() thread runs on will go up to 100%.
> 
> Although as we discussed before in https://www.redhat.com/archives/libvir-list/2015-May/msg00400.html
> it should be prohibited to set-time while other applications are running, but it does
> seems to have no harm to make the codes more robust.
> 
> Signed-off-by: Wang Yufei <james.wangyufei at huawei.com>
> Signed-off-by: Zhang Bo <oscar.zhangbo at huawei.com>
> ---
>  src/util/vireventpoll.c | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/src/util/vireventpoll.c b/src/util/vireventpoll.c
> index ffda206..9c9e7af 100644
> --- a/src/util/vireventpoll.c
> +++ b/src/util/vireventpoll.c
> @@ -357,9 +357,12 @@ static int virEventPollCalculateTimeout(int *timeout)
>              return -1;
>  
>          EVENT_DEBUG("Schedule timeout then=%llu now=%llu", then, now);
> -        *timeout = then - now;
> -        if (*timeout < 0)
> +        if (then <= now) {
>              *timeout = 0;
> +        } else {
> +            *timeout = (int) (then - now);

This still won't fix the overflow issue since the same implicit typecast
would be done without the explicit one. You probably should clamp the
value to INT_MAX if you want to be safe.

> +            *timeout = (*timeout > 0) ? (*timeout) : (*timeout)*(-1);

This would denote that timeout overflowed, hence you did not fix it at
first.

> +        }
>      } else {
>          *timeout = -1;
>      }

I'm not discussing the previous comments done by DanPB though.

Peter
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20150522/54544555/attachment-0001.sig>


More information about the libvir-list mailing list