[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