rendercheck: 2 commits - main.c Makefile.am rendercheck.1 rendercheck.h tests.c t_triangles.c

Eric Anholt anholt at kemper.freedesktop.org
Wed May 3 11:42:52 EEST 2006


 Makefile.am   |    3 
 main.c        |    4 
 rendercheck.1 |    4 
 rendercheck.h |   17 ++++
 t_triangles.c |  243 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 tests.c       |   35 ++++++++
 6 files changed, 302 insertions(+), 4 deletions(-)

New commits:
diff-tree af99a26276212838da35d9fd07702e74dcbab5a1 (from parents)
Merge: 0410434d5a10a52cb381d6713d347da759474edd c1d2c663c385a4c0e2ac6ba03664cf252dff62b0
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed May 3 01:32:57 2006 -0700

    Merge branch 'security-implications' containing a new test for the triangles
    calls, which I used for tracking down the Bug #6642 (CVE-2006-1526) issue.  It
    doesn't test much more of triangles than "we can render a couple of them".
    
    Conflicts:
    
    	Makefile.am
    	main.c
    	rendercheck.1
    	rendercheck.h
    	tests.c

diff --cc Makefile.am
index 9e2585f,71864b0..e2ad1c3
@@@ -10,10 -10,10 +10,11 @@@
  	t_composite.c \
  	t_dstcoords.c \
  	t_fill.c \
+ 	t_gradient.c \
 +	t_repeat.c \
  	t_srccoords.c \
  	t_tsrccoords.c \
- 	t_gradient.c
+ 	t_triangles.c
  
  INCLUDES = $(RC_CFLAGS)
  rendercheck_LDADD = $(RC_LIBS)
diff --cc main.c
index dd50b5e,80b7bd3..ead6efa
@@@ -107,7 -110,7 +107,7 @@@
      fprintf(stderr, "usage: %s [-d|--display display] [-v|--verbose]\n"
  	"\t[-t test1,test2,...] [--sync]\n"
              "\tAvailable tests: dcoors,scoords,mcoords,tscoords,\n"
-             "\t\ttmcoords,blend,composite,cacomposite,gradients,repeat\n",
 -            "\t\ttmcoords,blend,composite,cacomposite,gradients,triangles\n",
++            "\t\ttmcoords,blend,composite,cacomposite,gradients,repeat,triangles\n",
  	program);
      exit(1);
  }
@@@ -168,8 -171,8 +168,10 @@@
  					enabled_tests |= TEST_CACOMPOSITE;
  				} else if (strcmp(test, "gradients") == 0) {
  					enabled_tests |= TEST_GRADIENTS;
 +				} else if (strcmp(test, "repeat") == 0) {
 +					enabled_tests |= TEST_REPEAT;
+ 				} else if (strcmp(test, "triangles") == 0) {
+ 					enabled_tests |= TEST_TRIANGLES;
  				} else {
  					usage(argv[0]);
  				}
diff --cc rendercheck.1
index de502a4,d019344..e24de37
@@@ -28,8 -28,8 +28,8 @@@
  .BI \-t|\-\-tests\ test1,test2,test3...
  Enables only a specific subset of the possible tests.  Test names include 
  fill, dcoords, scoords, mcoords, tscoords, tmcoords, blend, composite,
- cacomposite, gradients, and repeat.  Names must be separated by commas and have
- no spaces.
 -cacomposite, gradients, and triangles.  Names must be separated by commas and
 -have no spaces.
++cacomposite, gradients, repeat, and triangles.  Names must be separated by
++commas and have no spaces.
  .TP
  .BI \-v|\-\-verbose
  Enables verbose printing of information on tests run, and successes and
diff --cc rendercheck.h
index 5d9521b,54b5feb..1667f5a
@@@ -58,7 -60,7 +58,8 @@@
  #define TEST_COMPOSITE		0x0080
  #define TEST_CACOMPOSITE	0x0100
  #define TEST_GRADIENTS  	0x0200
 -#define TEST_TRIANGLES  	0x0400
 +#define TEST_REPEAT	  	0x0400
++#define TEST_TRIANGLES  	0x0800
  
  extern int pixmap_move_iter;
  extern int win_width, win_height;
@@@ -120,10 -121,18 +121,26 @@@
  trans_coords_test(Display *dpy, picture_info *win, picture_info *white,
      Bool test_mask);
  
 +Bool linear_gradient_test(Display *dpy, picture_info *win,
 +                          picture_info *dst, int op, picture_info *dst_color);
 +
 +Bool
 +repeat_test(Display *dpy, picture_info *win, picture_info *dst, int op,
 +    picture_info *dst_color, picture_info *c1, picture_info *c2,
 +    Bool test_mask);
++
+ Bool
+ linear_gradient_test(Display *dpy, picture_info *win,
+     picture_info *dst, int op, picture_info *dst_color);
+ 
+ Bool
+ triangles_test(Display *dpy, picture_info *win, picture_info *dst, int op,
+     picture_info *src_color, picture_info *dst_color);
+ 
+ Bool
+ tristrip_test(Display *dpy, picture_info *win, picture_info *dst, int op,
+     picture_info *src_color, picture_info *dst_color);
+ 
+ Bool
+ trifan_test(Display *dpy, picture_info *win, picture_info *dst, int op,
+     picture_info *src_color, picture_info *dst_color);
diff --cc tests.c
index ee4a208,04e7541..83c8436
@@@ -555,45 -479,33 +555,80 @@@
                      }
                  }
              }
 +	    if (group_ok)
 +		 success_mask |= TEST_GRADIENTS;
 +        }
 +
 +        if (enabled_tests & TEST_REPEAT) {
 +	    Bool ok, group_ok = TRUE;
 +
 +            for (i = 0; i < num_ops; i++) {
 +                for (j = 0; j <= num_dests; j++) {
 +                    picture_info *pi;
 +                    
 +                    if (j != num_dests)
 +                        pi = &dests[j];
 +                    else
 +                        pi = win;
 +                    printf("Beginning %s src repeat test on %s\n",
 +                           ops[i].name, pi->name);
 +		    /* Test with white dest, and generated repeating src
 +		     * consisting of colors 1 and 2 (r, g).
 +		     */
 +		    ok = repeat_test(dpy, win, pi, i, argb32white, argb32red,
 +		        argb32green, FALSE);
 +		    RECORD_RESULTS();
 +
 +                    printf("Beginning %s mask repeat test on %s\n",
 +                           ops[i].name, pi->name);
 +		    /* Test with white dest, translucent red src, and generated
 +		     * repeating mask consisting of colors 1 and 2 (r, g).
 +		     */
 +		    ok = repeat_test(dpy, win, pi, i, argb32white, argb32red,
 +		        argb32green, TRUE);
 +		    RECORD_RESULTS();
 +                }
 +            }
 +	    if (group_ok)
 +		success_mask |= TEST_REPEAT;
          }
  
+ 	if (enabled_tests & TEST_TRIANGLES) {
++	    Bool ok, group_ok = TRUE;
++
+ 	    for (i = 0; i < num_ops; i++) {
+ 		for (j = 0; j <= num_dests; j++) {
+ 			picture_info *pi;
+ 
+ 			if (j != num_dests)
+ 			    pi = &dests[j];
+ 			else
+ 			    pi = win;
+ 
+ 			printf("Beginning %s Triangles test on %s\n",
+ 			    ops[i].name, pi->name);
 -			triangles_test(dpy, win, pi, i, &pictures_1x1[num_formats],
 -			    &pictures_1x1[0]);
++			ok = triangles_test(dpy, win, pi, i,
++			    &pictures_1x1[num_formats], &pictures_1x1[0]);
++			RECORD_RESULTS();
+ 
+ 			printf("Beginning %s TriStrip test on %s\n",
+ 			    ops[i].name, pi->name);
 -			tristrip_test(dpy, win, pi, i, &pictures_1x1[num_formats],
 -			    &pictures_1x1[0]);
++			ok = tristrip_test(dpy, win, pi, i,
++			    &pictures_1x1[num_formats], &pictures_1x1[0]);
++			RECORD_RESULTS();
+ 
+ 			printf("Beginning %s TriFan test on %s\n",
+ 			    ops[i].name, pi->name);
 -			trifan_test(dpy, win, pi, i, &pictures_1x1[num_formats],
 -			    &pictures_1x1[0]);
++			ok = trifan_test(dpy, win, pi, i,
++			    &pictures_1x1[num_formats], &pictures_1x1[0]);
++			RECORD_RESULTS();
+ 		}
+ 	    }
++	    if (group_ok)
++		success_mask |= TEST_TRIANGLES;
+ 	}
++
 +	printf("%d tests passed of %d total\n", tests_passed, tests_total);
 +
 +	return tests_passed == tests_total;
  }
diff-tree c1d2c663c385a4c0e2ac6ba03664cf252dff62b0 (from d5949bcc33e115f12762127093f1d5b3158c1c01)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Apr 19 09:13:55 2006 -0700

    Add a trivial test for Triangles, TriStrip, and TriFan, which exposed a security
    flaw in the server

diff --git a/Makefile.am b/Makefile.am
index 41e0957..71864b0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -10,9 +10,10 @@ rendercheck_SOURCES = \
 	t_composite.c \
 	t_dstcoords.c \
 	t_fill.c \
+	t_gradient.c \
 	t_srccoords.c \
 	t_tsrccoords.c \
-	t_gradient.c
+	t_triangles.c
 
 INCLUDES = $(RC_CFLAGS)
 rendercheck_LDADD = $(RC_LIBS)
diff --git a/main.c b/main.c
index ce23e87..80b7bd3 100644
--- a/main.c
+++ b/main.c
@@ -110,7 +110,7 @@ usage (char *program)
     fprintf(stderr, "usage: %s [-d|--display display] [-v|--verbose]\n"
 	"\t[-t test1,test2,...] [--sync]\n"
             "\tAvailable tests: dcoors,scoords,mcoords,tscoords,\n"
-            "\t\ttmcoords,blend,composite,cacomposite,gradients\n",
+            "\t\ttmcoords,blend,composite,cacomposite,gradients,triangles\n",
 	program);
     exit(1);
 }
@@ -171,6 +171,8 @@ int main(int argc, char **argv)
 					enabled_tests |= TEST_CACOMPOSITE;
 				} else if (strcmp(test, "gradients") == 0) {
 					enabled_tests |= TEST_GRADIENTS;
+				} else if (strcmp(test, "triangles") == 0) {
+					enabled_tests |= TEST_TRIANGLES;
 				} else {
 					usage(argv[0]);
 				}
diff --git a/rendercheck.1 b/rendercheck.1
index 6723700..d019344 100644
--- a/rendercheck.1
+++ b/rendercheck.1
@@ -27,8 +27,9 @@ Enables synchronous xlib operation, for 
 .TP
 .BI \-t|\-\-tests\ test1,test2,test3...
 Enables only a specific subset of the possible tests.  Test names include 
-fill, dcoords, scoords, mcoords, tscoords, tmcoords, blend, composite, and
-cacomposite.  Names must be separated by commas and have no spaces.
+fill, dcoords, scoords, mcoords, tscoords, tmcoords, blend, composite,
+cacomposite, gradients, and triangles.  Names must be separated by commas and
+have no spaces.
 .TP
 .BI \-v|\-\-verbose
 Enables verbose printing of information on tests run, and successes and
diff --git a/rendercheck.h b/rendercheck.h
index 98de62a..54b5feb 100644
--- a/rendercheck.h
+++ b/rendercheck.h
@@ -60,6 +60,7 @@ struct op_info {
 #define TEST_COMPOSITE		0x0080
 #define TEST_CACOMPOSITE	0x0100
 #define TEST_GRADIENTS  	0x0200
+#define TEST_TRIANGLES  	0x0400
 
 extern int pixmap_move_iter;
 extern int win_width, win_height;
@@ -120,5 +121,18 @@ Bool
 trans_coords_test(Display *dpy, picture_info *win, picture_info *white,
     Bool test_mask);
 
-Bool linear_gradient_test(Display *dpy, picture_info *win,
-                          picture_info *dst, int op, picture_info *dst_color);
+Bool
+linear_gradient_test(Display *dpy, picture_info *win,
+    picture_info *dst, int op, picture_info *dst_color);
+
+Bool
+triangles_test(Display *dpy, picture_info *win, picture_info *dst, int op,
+    picture_info *src_color, picture_info *dst_color);
+
+Bool
+tristrip_test(Display *dpy, picture_info *win, picture_info *dst, int op,
+    picture_info *src_color, picture_info *dst_color);
+
+Bool
+trifan_test(Display *dpy, picture_info *win, picture_info *dst, int op,
+    picture_info *src_color, picture_info *dst_color);
diff --git a/t_triangles.c b/t_triangles.c
new file mode 100644
index 0000000..c911399
--- /dev/null
+++ b/t_triangles.c
@@ -0,0 +1,243 @@
+/*
+ * Copyright © 2006 Eric Anholt
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *    Eric Anholt <anholt at FreeBSD.org>
+ *
+ */
+
+#include <stdio.h>
+
+#include "rendercheck.h"
+
+/* Test basic functionality of the triangle operations.  We don't care that much
+ * probably (nobody has used them yet), but we can trivially test by filling
+ * doing two triangles that will exactly cover the rectangle from 2,2 to 4,4.
+ */
+Bool
+triangles_test(Display *dpy, picture_info *win, picture_info *dst, int op,
+    picture_info *src_color, picture_info *dst_color)
+{
+	XTriangle triangles[2];
+	color4d tdst, tsrc;
+	int x, y;
+	Bool success = TRUE;
+
+	triangles[0].p1.x = XDoubleToFixed(2);
+	triangles[0].p1.y = XDoubleToFixed(2);
+	triangles[0].p2.x = XDoubleToFixed(4);
+	triangles[0].p2.y = XDoubleToFixed(2);
+	triangles[0].p3.x = XDoubleToFixed(4);
+	triangles[0].p3.y = XDoubleToFixed(4);
+
+	triangles[1].p1.x = XDoubleToFixed(2);
+	triangles[1].p1.y = XDoubleToFixed(2);
+	triangles[1].p2.x = XDoubleToFixed(2);
+	triangles[1].p2.y = XDoubleToFixed(4);
+	triangles[1].p3.x = XDoubleToFixed(4);
+	triangles[1].p3.y = XDoubleToFixed(4);
+
+	/* Fill the dst to dst_color */
+	XRenderComposite(dpy, PictOpSrc, dst_color->pict, None, dst->pict, 0, 0,
+	    0, 0, 0, 0, win_width, win_height);
+	/* Paint the triangles with src_color */
+	XRenderCompositeTriangles(dpy, ops[op].op, src_color->pict, dst->pict,
+	    XRenderFindStandardFormat(dpy, PictStandardA8), 0, 0, triangles, 2);
+
+	/* Copy the output to the window, so the user sees something visual. */
+	XRenderComposite(dpy, PictOpSrc, dst->pict, 0, win->pict, 0, 0, 0, 0,
+	    0, 0, win_width, win_height);	
+
+	/* Color expected outside of the triangles */
+	tdst = dst_color->color;
+	color_correct(dst, &tdst);
+
+	/* Color expected inside of the triangles */
+	do_composite(ops[op].op, &src_color->color, NULL, &tdst, &tsrc, FALSE);
+	color_correct(dst, &tsrc);
+
+	for (x = 0; x < 5; x++) {
+	    for (y = 0; y < 5; y++) {
+		color4d expected, tested;
+
+		if (x >= 2 && x < 4 && y >= 2 && y < 4) {
+			expected = tsrc;
+		} else {
+			expected = tdst;
+		}
+
+		get_pixel(dpy, dst, x, y, &tested);
+
+		if (!eval_diff("triangles", &expected, &tested, x, y,
+		    is_verbose))
+		{
+			success = FALSE;
+		}
+	    }
+	}
+	if (!success) {
+		printf("src color: %.2f %.2f %.2f %.2f\n"
+		    "dst color: %.2f %.2f %.2f %.2f\n",
+		    src_color->color.r, src_color->color.g,
+		    src_color->color.b, src_color->color.a,
+		    dst_color->color.r, dst_color->color.g,
+		    dst_color->color.b, dst_color->color.a);
+	}
+
+	return success;
+}
+
+Bool
+trifan_test(Display *dpy, picture_info *win, picture_info *dst, int op,
+    picture_info *src_color, picture_info *dst_color)
+{
+	XPointFixed points[4];
+	color4d tdst, tsrc;
+	int x, y;
+	Bool success = TRUE;
+
+	points[0].x = XDoubleToFixed(2);
+	points[0].y = XDoubleToFixed(2);
+	points[1].x = XDoubleToFixed(4);
+	points[1].y = XDoubleToFixed(2);
+	points[2].x = XDoubleToFixed(4);
+	points[2].y = XDoubleToFixed(4);
+	points[3].x = XDoubleToFixed(2);
+	points[3].y = XDoubleToFixed(4);
+
+	/* Fill the dst to dst_color */
+	XRenderComposite(dpy, PictOpSrc, dst_color->pict, None, dst->pict, 0, 0,
+	    0, 0, 0, 0, win_width, win_height);
+	/* Paint the triangles with src_color */
+	XRenderCompositeTriFan(dpy, ops[op].op, src_color->pict, dst->pict,
+	    XRenderFindStandardFormat(dpy, PictStandardA8), 0, 0, points, 4);
+
+	/* Copy the output to the window, so the user sees something visual. */
+	XRenderComposite(dpy, PictOpSrc, dst->pict, 0, win->pict, 0, 0, 0, 0,
+	    0, 0, win_width, win_height);	
+
+	/* Color expected outside of the triangles */
+	tdst = dst_color->color;
+	color_correct(dst, &tdst);
+
+	/* Color expected inside of the triangles */
+	do_composite(ops[op].op, &src_color->color, NULL, &tdst, &tsrc, FALSE);
+	color_correct(dst, &tsrc);
+
+	for (x = 0; x < 5; x++) {
+	    for (y = 0; y < 5; y++) {
+		color4d expected, tested;
+
+		if (x >= 2 && x < 4 && y >= 2 && y < 4) {
+			expected = tsrc;
+		} else {
+			expected = tdst;
+		}
+
+		get_pixel(dpy, dst, x, y, &tested);
+
+		if (!eval_diff("triangles", &expected, &tested, x, y,
+		    is_verbose))
+		{
+			success = FALSE;
+		}
+	    }
+	}
+	if (!success) {
+		printf("src color: %.2f %.2f %.2f %.2f\n"
+		    "dst color: %.2f %.2f %.2f %.2f\n",
+		    src_color->color.r, src_color->color.g,
+		    src_color->color.b, src_color->color.a,
+		    dst_color->color.r, dst_color->color.g,
+		    dst_color->color.b, dst_color->color.a);
+	}
+
+	return success;
+}
+
+Bool
+tristrip_test(Display *dpy, picture_info *win, picture_info *dst, int op,
+    picture_info *src_color, picture_info *dst_color)
+{
+	XPointFixed points[4];
+	color4d tdst, tsrc;
+	int x, y;
+	Bool success = TRUE;
+
+	points[0].x = XDoubleToFixed(2);
+	points[0].y = XDoubleToFixed(2);
+	points[1].x = XDoubleToFixed(4);
+	points[1].y = XDoubleToFixed(2);
+	points[2].x = XDoubleToFixed(2);
+	points[2].y = XDoubleToFixed(4);
+	points[3].x = XDoubleToFixed(4);
+	points[3].y = XDoubleToFixed(4);
+
+	/* Fill the dst to dst_color */
+	XRenderComposite(dpy, PictOpSrc, dst_color->pict, None, dst->pict, 0, 0,
+	    0, 0, 0, 0, win_width, win_height);
+	/* Paint the triangles with src_color */
+	XRenderCompositeTriStrip(dpy, ops[op].op, src_color->pict, dst->pict,
+	    XRenderFindStandardFormat(dpy, PictStandardA8), 0, 0, points, 4);
+
+	/* Copy the output to the window, so the user sees something visual. */
+	XRenderComposite(dpy, PictOpSrc, dst->pict, 0, win->pict, 0, 0, 0, 0,
+	    0, 0, win_width, win_height);	
+
+	/* Color expected outside of the triangles */
+	tdst = dst_color->color;
+	color_correct(dst, &tdst);
+
+	/* Color expected inside of the triangles */
+	do_composite(ops[op].op, &src_color->color, NULL, &tdst, &tsrc, FALSE);
+	color_correct(dst, &tsrc);
+
+	for (x = 0; x < 5; x++) {
+	    for (y = 0; y < 5; y++) {
+		color4d expected, tested;
+
+		if (x >= 2 && x < 4 && y >= 2 && y < 4) {
+			expected = tsrc;
+		} else {
+			expected = tdst;
+		}
+
+		get_pixel(dpy, dst, x, y, &tested);
+
+		if (!eval_diff("triangles", &expected, &tested, x, y,
+		    is_verbose))
+		{
+			success = FALSE;
+		}
+	    }
+	}
+	if (!success) {
+		printf("src color: %.2f %.2f %.2f %.2f\n"
+		    "dst color: %.2f %.2f %.2f %.2f\n",
+		    src_color->color.r, src_color->color.g,
+		    src_color->color.b, src_color->color.a,
+		    dst_color->color.r, dst_color->color.g,
+		    dst_color->color.b, dst_color->color.a);
+	}
+
+	return success;
+}
diff --git a/tests.c b/tests.c
index 58598a3..04e7541 100644
--- a/tests.c
+++ b/tests.c
@@ -480,4 +480,32 @@ begin_test(Display *dpy, picture_info *w
                 }
             }
         }
+
+	if (enabled_tests & TEST_TRIANGLES) {
+	    for (i = 0; i < num_ops; i++) {
+		for (j = 0; j <= num_dests; j++) {
+			picture_info *pi;
+
+			if (j != num_dests)
+			    pi = &dests[j];
+			else
+			    pi = win;
+
+			printf("Beginning %s Triangles test on %s\n",
+			    ops[i].name, pi->name);
+			triangles_test(dpy, win, pi, i, &pictures_1x1[num_formats],
+			    &pictures_1x1[0]);
+
+			printf("Beginning %s TriStrip test on %s\n",
+			    ops[i].name, pi->name);
+			tristrip_test(dpy, win, pi, i, &pictures_1x1[num_formats],
+			    &pictures_1x1[0]);
+
+			printf("Beginning %s TriFan test on %s\n",
+			    ops[i].name, pi->name);
+			trifan_test(dpy, win, pi, i, &pictures_1x1[num_formats],
+			    &pictures_1x1[0]);
+		}
+	    }
+	}
 }



More information about the xorg-commit mailing list