[PATCH] glamor: fix crash when drawing nothing

walter harms wharms at bfs.de
Fri Oct 16 09:55:57 PDT 2015



Am 16.10.2015 18:11, schrieb Rob Clark:
> For example, in the PolyFillRect() path w/ nrect==0, we end up in
> glamor_get_vbo_space(size=0):
> 
>    (gdb) bt
>    #0  0x0000007fb73df340 in raise () from /lib64/libc.so.6
>    #1  0x0000007fb73e0fb8 in abort () from /lib64/libc.so.6
>    #2  0x0000007fb73d84f4 in __assert_fail_base () from /lib64/libc.so.6
>    #3  0x0000007fb73d859c in __assert_fail () from /lib64/libc.so.6
>    #4  0x000000000045dc38 in glamor_get_vbo_space (screen=0x8dcb60, size=size at entry=0, vbo_offset=0x7ffffff250, vbo_offset at entry=0x7ffffff2d0) at glamor_vbo.c:112
>    #5  0x00000000004541ac in glamor_poly_fill_rect_gl (prect=0x11be650, nrect=0, gc=0x4cda70 <miPaintWindow+344>, drawable=0x7ffffff388) at glamor_rects.c:72
>    #6  glamor_poly_fill_rect (drawable=0x7ffffff388, gc=0x4cda70 <miPaintWindow+344>, nrect=0, prect=0x11be650) at glamor_rects.c:162
>    #7  0x0000000000557d0c in damagePolyFillRect (pDrawable=0x112c300, pGC=0xe81580, nRects=0, pRects=<optimized out>) at damage.c:1194
>    #8  0x00000000004cdb20 in miPaintWindow (pWin=<optimized out>, prgn=0x7ffffff388, what=<optimized out>) at miexpose.c:540
>    #9  0x00000000004db260 in miClearToBackground (pWin=0x112c300, x=<optimized out>, y=<optimized out>, w=<optimized out>, h=<optimized out>, generateExposures=0) at miwindow.c:116
>    #10 0x00000000004646e4 in ProcClearToBackground (client=0x111e810) at dispatch.c:1592
>    #11 0x000000000046907c in Dispatch () at dispatch.c:430
>    #12 0x000000000046cf90 in dix_main (argc=5, argv=0x7ffffff628, envp=<optimized out>) at main.c:300
>    #13 0x0000007fb73cb68c in __libc_start_main () from /lib64/libc.so.6
>    #14 0x000000000042b3e8 in _start ()
> 
> Also fixed a bunch of other call-sites which could in theory trigger the
> same issue.
> 
> v2: add back the early return if size==0 in glamor_get_vbo_space() just
> in case.  We'd hit a GL error in glamor_put_vbo_space() if we ever ended
> up with a call path that hit that (so keep the earlier early-returns),
> but a GL error is better than a crash so keep this extra safety-net.
> 
> Signed-off-by: Rob Clark <robdclark at gmail.com>
> ---
>  glamor/glamor_copy.c     | 3 +++
>  glamor/glamor_dash.c     | 3 +++
>  glamor/glamor_glyphblt.c | 3 +++
>  glamor/glamor_points.c   | 3 +++
>  glamor/glamor_rects.c    | 3 +++
>  glamor/glamor_render.c   | 3 +++
>  glamor/glamor_segs.c     | 3 +++
>  glamor/glamor_spans.c    | 3 +++
>  glamor/glamor_text.c     | 3 +++
>  glamor/glamor_vbo.c      | 3 +++
>  10 files changed, 30 insertions(+)
> 
> diff --git a/glamor/glamor_copy.c b/glamor/glamor_copy.c
> index 028acf2..97db20c 100644
> --- a/glamor/glamor_copy.c
> +++ b/glamor/glamor_copy.c
> @@ -317,6 +317,9 @@ glamor_copy_fbo_fbo_draw(DrawablePtr src,
>      const glamor_facet *copy_facet;
>      int n;
>  
> +    if (nbox == 0)
> +        return TRUE;
> +
>      glamor_make_current(glamor_priv);
>  
>      if (gc && !glamor_set_planemask(gc->depth, gc->planemask))
> diff --git a/glamor/glamor_dash.c b/glamor/glamor_dash.c
> index 101228e..b961951 100644
> --- a/glamor/glamor_dash.c
> +++ b/glamor/glamor_dash.c
> @@ -328,6 +328,9 @@ glamor_poly_segment_dash_gl(DrawablePtr drawable, GCPtr gc,
>      int add_last;
>      int i;
>  
> +    if (nseg == 0)
> +        return TRUE;
> +
>      if (!(prog = glamor_dash_setup(drawable, gc)))
>          return FALSE;
>  
> diff --git a/glamor/glamor_glyphblt.c b/glamor/glamor_glyphblt.c
> index 1791f6d..0cd3406 100644
> --- a/glamor/glamor_glyphblt.c
> +++ b/glamor/glamor_glyphblt.c
> @@ -175,6 +175,9 @@ glamor_push_pixels_gl(GCPtr gc, PixmapPtr bitmap,
>      INT16 *points = NULL;
>      char *vbo_offset;
>  
> +    if ((w * h) == 0)
> +        return TRUE;
> +

  ( ) seems a bit superfluous.

 re,
  wh

>      if (w * h > MAXINT / (2 * sizeof(float)))
>          goto bail;
>  
> diff --git a/glamor/glamor_points.c b/glamor/glamor_points.c
> index 3ba4a69..e0aa87e 100644
> --- a/glamor/glamor_points.c
> +++ b/glamor/glamor_points.c
> @@ -48,6 +48,9 @@ glamor_poly_point_gl(DrawablePtr drawable, GCPtr gc, int mode, int npt, DDXPoint
>      char *vbo_offset;
>      int box_x, box_y;
>  
> +    if (npt == 0)
> +        return TRUE;
> +
>      pixmap_priv = glamor_get_pixmap_private(pixmap);
>      if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
>          goto bail;
> diff --git a/glamor/glamor_rects.c b/glamor/glamor_rects.c
> index c378e4a..26d1401 100644
> --- a/glamor/glamor_rects.c
> +++ b/glamor/glamor_rects.c
> @@ -53,6 +53,9 @@ glamor_poly_fill_rect_gl(DrawablePtr drawable,
>      char *vbo_offset;
>      int box_x, box_y;
>  
> +    if (nrect == 0)
> +        return TRUE;
> +
>      pixmap_priv = glamor_get_pixmap_private(pixmap);
>      if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
>          goto bail;
> diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
> index c3a8f17..3ad4507 100644
> --- a/glamor/glamor_render.c
> +++ b/glamor/glamor_render.c
> @@ -621,6 +621,9 @@ glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
>  
>      vert_size = n_verts * glamor_priv->vb_stride;
>  
> +    if (vert_size == 0)
> +        return TRUE;
> +
>      glamor_make_current(glamor_priv);
>      vb = glamor_get_vbo_space(screen, vert_size, &vbo_offset);
>  
> diff --git a/glamor/glamor_segs.c b/glamor/glamor_segs.c
> index e167325..1c4ee75 100644
> --- a/glamor/glamor_segs.c
> +++ b/glamor/glamor_segs.c
> @@ -47,6 +47,9 @@ glamor_poly_segment_solid_gl(DrawablePtr drawable, GCPtr gc,
>      int box_x, box_y;
>      int add_last;
>  
> +    if (nseg == 0)
> +        return TRUE;
> +
>      pixmap_priv = glamor_get_pixmap_private(pixmap);
>      if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
>          goto bail;
> diff --git a/glamor/glamor_spans.c b/glamor/glamor_spans.c
> index 58da3ed..db5fe7c 100644
> --- a/glamor/glamor_spans.c
> +++ b/glamor/glamor_spans.c
> @@ -57,6 +57,9 @@ glamor_fill_spans_gl(DrawablePtr drawable,
>      int c;
>      int box_x, box_y;
>  
> +    if (n == 0)
> +        return TRUE;
> +
>      pixmap_priv = glamor_get_pixmap_private(pixmap);
>      if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
>          goto bail;
> diff --git a/glamor/glamor_text.c b/glamor/glamor_text.c
> index 81a22a5..afad751 100644
> --- a/glamor/glamor_text.c
> +++ b/glamor/glamor_text.c
> @@ -111,6 +111,9 @@ glamor_text(DrawablePtr drawable, GCPtr gc,
>      PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
>      glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
>  
> +    if (count == 0)
> +        return 0;
> +
>      /* Set the font as texture 1 */
>  
>      glActiveTexture(GL_TEXTURE1);
> diff --git a/glamor/glamor_vbo.c b/glamor/glamor_vbo.c
> index d74a005..425d2ae 100644
> --- a/glamor/glamor_vbo.c
> +++ b/glamor/glamor_vbo.c
> @@ -52,6 +52,9 @@ glamor_get_vbo_space(ScreenPtr screen, unsigned size, char **vbo_offset)
>  
>      glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
>  
> +    if (size == 0)
> +        return NULL;
> +
>      if (glamor_priv->has_buffer_storage) {
>          if (glamor_priv->vbo_size < glamor_priv->vbo_offset + size) {
>              if (glamor_priv->vbo_size)


More information about the xorg-devel mailing list