From patchwork Fri Nov 6 16:57:51 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 9582 Received: (qmail 38596 invoked by alias); 6 Nov 2015 16:57:56 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 38581 invoked by uid 89); 6 Nov 2015 16:57:55 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.5 required=5.0 tests=AWL, BAYES_00, SPF_HELO_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Subject: [PATCH v1a] malloc: Do not free or realloc chunks in corrupt arenas To: GNU C Library References: <563CDB4C.1010806@redhat.com> From: Florian Weimer Message-ID: <563CDC0F.3090105@redhat.com> Date: Fri, 6 Nov 2015 17:57:51 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <563CDB4C.1010806@redhat.com> On 11/06/2015 05:54 PM, Florian Weimer wrote: > I am not sure if this is an actual bug in the malloc backtrace patch, or > if this is can only happen once there are additional sources of corrupt > arenas besides the malloc backtrace path > > This was found through code inspection. I do not have a test case at > the moment. Sorry, wrong version of patch attached. This is the correct one, I hope. Florian 2015-11-06 Florian Weimer * malloc/malloc.c (__libc_free): Do not free chunks in corrupt arenas. (realloc_from_corrupt): New function. (__libc_realloc): Call it for corrupt arenas. diff --git a/malloc/malloc.c b/malloc/malloc.c index 839263e..2446c4a 100644 --- a/malloc/malloc.c +++ b/malloc/malloc.c @@ -2966,10 +2966,38 @@ __libc_free (void *mem) } ar_ptr = arena_for_chunk (p); + + if (__glibc_unlikely (arena_is_corrupt (ar_ptr))) + /* Do nothing if the arena is known to be corrupt. */ + return; + _int_free (ar_ptr, p, 0); } libc_hidden_def (__libc_free) +/* Always make a copy to enlarge a chunk in a corrupt arena. The + chunk must not have been allocated with mmap. */ +static void * +realloc_from_corrupt (void *oldmem, size_t bytes, + INTERNAL_SIZE_T oldsize) +{ + /* Size adjustment for the non-mmap case. */ + oldsize -= SIZE_SZ; + + /* Reuse the old chunk if possible. */ + if (oldsize >= bytes) + return oldmem; + + void *newmem = __libc_malloc (bytes); + if (__glibc_unlikely (newmem == NULL)) + return NULL; + memcpy (newmem, oldmem, oldsize); + + /* Do not free the old object because the arena is known to be + corrupt. */ + return newmem; +} + void * __libc_realloc (void *oldmem, size_t bytes) { @@ -3041,6 +3069,9 @@ __libc_realloc (void *oldmem, size_t bytes) return newmem; } + if (__glibc_unlikely (arena_is_corrupt (ar_ptr))) + return realloc_from_corrupt (oldmem, bytes, oldsize); + (void) mutex_lock (&ar_ptr->mutex); newp = _int_realloc (ar_ptr, oldp, oldsize, nb);