[PATCH] glamor: fix crash when drawing nothing

Rob Clark robdclark at gmail.com
Fri Oct 16 09:11:06 PDT 2015


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;
+
     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)
-- 
2.5.0



More information about the xorg-devel mailing list