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