qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] vnc: fix use-after-free in vnc_update_client_sy


From: Markus Armbruster
Subject: Re: [Qemu-devel] [PATCH] vnc: fix use-after-free in vnc_update_client_sync
Date: Thu, 06 Mar 2014 16:04:10 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.2 (gnu/linux)

Gerd Hoffmann <address@hidden> writes:

> Spotted by Coverity:
>
> 876     static int vnc_update_client_sync(VncState *vs, int has_dirty)
> 877     {
>
> (1) Event freed_arg:    "vnc_update_client(VncState *, int)" frees "vs".  
> [details]
> Also see events:        [deref_arg]
>
> 878         int ret = vnc_update_client(vs, has_dirty);
>
> (2) Event deref_arg:    Calling "vnc_jobs_join(VncState *)" dereferences 
> freed pointer "vs". [details]
> Also see events:        [freed_arg]
>
> 879         vnc_jobs_join(vs);
> 880         return ret;
> 881     }
>
> Remove vnc_update_client_sync wrapper, replace it with an additional
> argument to vnc_update_client, so we can so the sync properly in
> vnc_update_client (i.e. skip it in case of a client disconnect).
>
> Cc: Markus Armbruster <address@hidden>
> Signed-off-by: Gerd Hoffmann <address@hidden>
> ---
>  ui/vnc.c | 21 ++++++++-------------
>  1 file changed, 8 insertions(+), 13 deletions(-)
>
> diff --git a/ui/vnc.c b/ui/vnc.c
> index 5601cc3..b0efb1f 100644
> --- a/ui/vnc.c
> +++ b/ui/vnc.c
> @@ -416,8 +416,7 @@ out_error:
>     3) resolutions > 1024
>  */
>  
> -static int vnc_update_client(VncState *vs, int has_dirty);
> -static int vnc_update_client_sync(VncState *vs, int has_dirty);
> +static int vnc_update_client(VncState *vs, int has_dirty, bool sync);
>  static void vnc_disconnect_start(VncState *vs);
>  
>  static void vnc_colordepth(VncState *vs);
> @@ -750,7 +749,7 @@ static void vnc_dpy_copy(DisplayChangeListener *dcl,
>      QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
>          if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
>              vs->force_update = 1;
> -            vnc_update_client_sync(vs, 1);
> +            vnc_update_client(vs, 1, true);
>              /* vs might be free()ed here */
>          }
>      }
> @@ -873,14 +872,7 @@ static int find_and_clear_dirty_height(struct VncState 
> *vs,
>      return h;
>  }
>  
> -static int vnc_update_client_sync(VncState *vs, int has_dirty)
> -{
> -    int ret = vnc_update_client(vs, has_dirty);
> -    vnc_jobs_join(vs);

This is the problematic use, and you move it...

> -    return ret;
> -}
> -
> -static int vnc_update_client(VncState *vs, int has_dirty)
> +static int vnc_update_client(VncState *vs, int has_dirty, bool sync)
>  {
>      if (vs->need_update && vs->csock != -1) {
>          VncDisplay *vd = vs->vd;
> @@ -939,8 +931,11 @@ static int vnc_update_client(VncState *vs, int has_dirty)
>          return n;
>      }
>  
> -    if (vs->csock == -1)
> +    if (vs->csock == -1) {
>          vnc_disconnect_finish(vs);
> +    } else if (sync) {
> +        vnc_jobs_join(vs);
> +    }

... here, under a "not freed" guard.

>  
>      return 0;
>  }
> @@ -2749,7 +2744,7 @@ static void vnc_refresh(DisplayChangeListener *dcl)
>      vnc_unlock_display(vd);
>  
>      QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
> -        rects += vnc_update_client(vs, has_dirty);
> +        rects += vnc_update_client(vs, has_dirty, false);
>          /* vs might be free()ed here */
>      }

Reviewed-by: Markus Armbruster <address@hidden>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]