Bug 34363 - Xorg crashes due to garbage pointer at do_get_buffers() at dri2
Summary: Xorg crashes due to garbage pointer at do_get_buffers() at dri2
Status: RESOLVED FIXED
Alias: None
Product: xorg
Classification: Unclassified
Component: Server/Ext/DRI (show other bugs)
Version: 7.6 (2010.12)
Hardware: ARM Linux (All)
: medium major
Assignee: Xorg Project Team
QA Contact: Xorg Project Team
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-02-16 16:42 UTC by Kyong-jin (Vince) Kim
Modified: 2011-03-17 09:59 UTC (History)
0 users

See Also:
i915 platform:
i915 features:


Attachments
dri2 patch for preveting Xorg from crash (1.03 KB, patch)
2011-02-16 16:42 UTC, Kyong-jin (Vince) Kim
no flags Details | Splinter Review

Description Kyong-jin (Vince) Kim 2011-02-16 16:42:08 UTC
Created attachment 43461 [details] [review]
dri2 patch for preveting Xorg from crash 

do_get_buffers() create array of pointer called "buffers" using malloc.

This array will be filled with pointer for buffer by allocate_or_reuse_buffer()- eventually, it uses EXA if enabled. 

Unlikely, allocate_or_reuse_buffer() fails to allocate memory at buffers[i] where i is less than "count". 

Because of failure, the rest of buffers (from buffers[i] to buffers[count-1]) remains with some garbage pointer when it was allocated at malloc.

Then it jumps to  "err_out" to free those allocated buffers[i], but it tries to clean up buffers until buffers[count-1] - we know that this is not properly allocated.

At the end, Xserver crashes due to dereferencing garbage pointer.....

This crash cab be prevented by using calloc instead of malloc.

Here is my patch to fix this problem.



--- xserver-panda-org/hw/xfree86/dri2/dri2.c    2011-02-09 14:25:26.000000000 -0800
+++ xserver-panda/hw/xfree86/dri2/dri2.c 2011-02-15 16:36:37.794484553 -0800
@@ -402,8 +402,16 @@
     dimensions_match = (pDraw->width == pPriv->width)
       && (pDraw->height == pPriv->height)
       && (pPriv->serialNumber == DRI2DrawableSerial(pDraw));
-
-    buffers = malloc((count + 1) * sizeof(buffers[0]));
+       
+      /* can't use malloc here because
+       * 1. if allocate_or_reuse_buffer() failes to allocate buffer, buffers[i] is set to null 
+       * 2. actually allocated number of buffer is *less* than "count"
+       * 3. (*ds->DestroyBuffer)(pDraw, buffers[i]) at "err_out" frees up those memory  
+       * 4. DestroyBuffer() dereferences some *garbage* pointer(if malloc was used) at buffers[i], 
+       * where i is greater than allocated number of buffer at step 2.   
+       * 5. Xserver crashes due to dereferencing garbage poiner.....
+       */
+    buffers = calloc((count + 1), sizeof(buffers[0]));
 
     for (i = 0; i < count; i++) {
       const unsigned attachment = *(attachments++);
Comment 1 Stefan Dirsch 2011-03-17 09:59:48 UTC
That's already in git (master).

commit a73c28f0bdafb1c5cb8129179188a99c0ca052e2
Author: Justin Dou <Justin.Dou@intel.com>
Date:   Thu Feb 10 16:27:29 2011 -0500

    Replace malloc with calloc to initialize the buffers[] as NULL in 
    do_get_buffers function
    
    The calling for allocate_or_reuse_buffer may fail due to some reason, e.g. 
    out of memory.
    If the buffers[] were not initialized to be NULL, the following err_out may
    try to access an illegal memory, which will cause X crash afterward.
    
    Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
    Signed-off-by: Justin Dou <Justin.Dou@intel.com>
    Signed-off-by: Keith Packard <keithp@keithp.com>


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.