ce426f
Short description: Don't corrupt heap if top chunk is MINSIZE.
ce426f
Author(s): Mel Gorman <mgorman@suse.de>
ce426f
Origin: git://sourceware.org/git/glibc.git
ce426f
Bug-RHEL: N/A
ce426f
Bug-Fedora: N/A
ce426f
Bug-Upstream: #18502
ce426f
Upstream status: committed
ce426f
ce426f
commit f8ef472c0ff4644445ec716036d31430b4fa4bab
ce426f
Author: Mel Gorman <mgorman@suse.de>
ce426f
Date:   Mon Jun 8 13:36:13 2015 +0100
ce426f
ce426f
    malloc: Do not corrupt the top of a threaded heap if top chunk is MINSIZE [BZ #18502]
ce426f
    
ce426f
    mksquashfs was reported in openSUSE to be causing segmentation faults when
ce426f
    creating installation images. Testing showed that mksquashfs sometimes
ce426f
    failed and could be reproduced within 10 attempts. The core dump looked
ce426f
    like the heap top was corrupted and was pointing to an unmapped area. In
ce426f
    other cases, this has been due to an application corrupting glibc structures
ce426f
    but mksquashfs appears to be fine in this regard.
ce426f
    
ce426f
    The problem is that heap_trim is "growing" the top into unmapped space.
ce426f
    If the top chunk == MINSIZE then top_area is -1 and this check does not
ce426f
    behave as expected due to a signed/unsigned comparison
ce426f
    
ce426f
      if (top_area <= pad)
ce426f
        return 0;
ce426f
    
ce426f
    The next calculation extra = ALIGN_DOWN(top_area - pad, pagesz) calculates
ce426f
    extra as a negative number which also is unnoticed due to a signed/unsigned
ce426f
    comparison. We then call shrink_heap(heap, negative_number) which crashes
ce426f
    later. This patch adds a simple check against MINSIZE to make sure extra
ce426f
    does not become negative. It adds a cast to hint to the reader that this
ce426f
    is a signed vs unsigned issue.
ce426f
    
ce426f
    Without the patch, mksquash fails within 10 attempts. With it applied, it
ce426f
    completed 1000 times without error. The standard test suite "make check"
ce426f
    showed no changes in the summary of test results.
ce426f
ce426f
Index: glibc-2.17-c758a686/malloc/arena.c
ce426f
===================================================================
ce426f
--- glibc-2.17-c758a686.orig/malloc/arena.c
ce426f
+++ glibc-2.17-c758a686/malloc/arena.c
ce426f
@@ -705,7 +705,7 @@ heap_trim(heap_info *heap, size_t pad)
ce426f
     return 0;
ce426f
 
ce426f
   top_area = top_size - MINSIZE - 1;
ce426f
-  if (top_area <= pad)
ce426f
+  if (top_area < 0 || (size_t) top_area <= pad)
ce426f
     return 0;
ce426f
 
ce426f
   /* Release in pagesize units and round down to the nearest page.  */