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