pixman: Branch '0.32'

Oded Gabbay gabbayo at kemper.freedesktop.org
Tue Sep 22 03:26:17 PDT 2015


 pixman/pixman-general.c |   16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

New commits:
commit 204fcd24d9b7e3988b7496e723014f327828751a
Author: Siarhei Siamashka <siarhei.siamashka at gmail.com>
Date:   Tue Sep 22 04:25:40 2015 +0300

    pixman-general: Fix stack related pointer arithmetic overflow
    
    As https://bugs.freedesktop.org/show_bug.cgi?id=92027#c6 explains,
    the stack is allocated at the very top of the process address space
    in some configurations (32-bit x86 systems with ASLR disabled).
    And the careless computations done with the 'dest_buffer' pointer
    may overflow, failing the buffer upper limit check.
    
    The problem can be reproduced using the 'stress-test' program,
    which segfaults when executed via setarch:
    
        export CFLAGS="-O2 -m32" && ./autogen.sh
        ./configure --disable-libpng --disable-gtk && make
        setarch i686 -R test/stress-test
    
    This patch introduces the required corrections. The extra check
    for negative 'width' may be redundant (the invalid 'width' value
    is not supposed to reach here), but it's better to play safe
    when dealing with the buffers allocated on stack.
    
    Reported-by: Ludovic Courtès <ludo at gnu.org>
    Signed-off-by: Siarhei Siamashka <siarhei.siamashka at gmail.com>
    Reviewed-by: soren.sandmann at gmail.com
    Signed-off-by: Oded Gabbay <oded.gabbay at gmail.com>

diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index a653fa7..f82ea7d 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -140,23 +140,21 @@ general_composite_rect  (pixman_implementation_t *imp,
 #define ALIGN(addr)							\
     ((uint8_t *)((((uintptr_t)(addr)) + 15) & (~15)))
 
-    src_buffer = ALIGN (scanline_buffer);
-    mask_buffer = ALIGN (src_buffer + width * Bpp);
-    dest_buffer = ALIGN (mask_buffer + width * Bpp);
+    if (width <= 0 || _pixman_multiply_overflows_int (width, Bpp * 3))
+	return;
 
-    if (ALIGN (dest_buffer + width * Bpp) >
-	    scanline_buffer + sizeof (stack_scanline_buffer))
+    if (width * Bpp * 3 > sizeof (stack_scanline_buffer) - 32 * 3)
     {
 	scanline_buffer = pixman_malloc_ab_plus_c (width, Bpp * 3, 32 * 3);
 
 	if (!scanline_buffer)
 	    return;
-
-	src_buffer = ALIGN (scanline_buffer);
-	mask_buffer = ALIGN (src_buffer + width * Bpp);
-	dest_buffer = ALIGN (mask_buffer + width * Bpp);
     }
 
+    src_buffer = ALIGN (scanline_buffer);
+    mask_buffer = ALIGN (src_buffer + width * Bpp);
+    dest_buffer = ALIGN (mask_buffer + width * Bpp);
+
     if (width_flag == ITER_WIDE)
     {
 	/* To make sure there aren't any NANs in the buffers */


More information about the xorg-commit mailing list