[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#260767: marked as done (double-free on small allocations causes infinite loop or SIGSEGV in malloc)



Your message dated Tue, 10 Aug 2004 15:08:22 -0500
with message-id <1092168502.2750.18.camel@laptop1>
and subject line source of double-free found
has caused the attached Bug report to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what I am
talking about this indicates a serious mail system misconfiguration
somewhere.  Please contact me immediately.)

Debian bug tracking system administrator
(administrator, Debian Bugs database)

--------------------------------------
Received: (at submit) by bugs.debian.org; 22 Jul 2004 04:16:07 +0000
>From licquia@progeny.com Wed Jul 21 21:16:07 2004
Return-path: <licquia@progeny.com>
Received: from jeffindy.licquia.org [216.37.46.185] 
	by spohr.debian.org with esmtp (Exim 3.35 1 (Debian))
	id 1BnV03-0004s4-00; Wed, 21 Jul 2004 21:16:07 -0700
Received: from sentinel.licquia.org (unknown [192.168.53.1])
	by jeffindy.licquia.org (Postfix) with ESMTP id 540AD1BC1A
	for <submit@bugs.debian.org>; Wed, 21 Jul 2004 23:16:06 -0500 (EST)
Received: from server1.internal.licquia.org (server1.internal.licquia.org [192.168.50.3])
	by sentinel.licquia.org (Postfix) with ESMTP id 3AA7ED524
	for <submit@bugs.debian.org>; Wed, 21 Jul 2004 23:16:05 -0500 (EST)
Received: by server1.internal.licquia.org (Postfix, from userid 1000)
	id 0466020EF84; Wed, 21 Jul 2004 23:16:05 -0500 (EST)
Subject: double-free on small allocations causes infinite loop or SIGSEGV
	in malloc
From: Jeff Licquia <licquia@progeny.com>
To: submit@bugs.debian.org
Content-Type: text/plain
Content-Transfer-Encoding: 7bit
Message-Id: <1090469764.30973.53.camel@server1.internal.licquia.org>
Mime-Version: 1.0
X-Mailer: Ximian Evolution 1.4.6 
Date: Wed, 21 Jul 2004 23:16:04 -0500
Delivered-To: submit@bugs.debian.org
X-Spam-Checker-Version: SpamAssassin 2.60-bugs.debian.org_2004_03_25 
	(1.212-2003-09-23-exp) on spohr.debian.org
X-Spam-Status: No, hits=-6.5 required=4.0 tests=BAYES_10,HAS_PACKAGE 
	autolearn=no version=2.60-bugs.debian.org_2004_03_25
X-Spam-Level: 

Package: libc6
Version: 2.3.2.ds1-13
Severity: serious
Tags: sarge sid

Small allocations via malloc() and friends uses the "fastbin" facility
to optimize situations where lots of small allocations and deallocations
of memory are needed.  Basically, small allocations are not freed right
away; instead, they are kept in an array of null-terminated
singly-linked lists (where the array indexes act as hashes of the
allocation sizes), and are handed back out on the next allocation.

Unfortunately, the fastbin facility does not do adequate error checking
in the case of a double free.  When free() is called and a fastbin is
considered appropriate, the memory in question is tacked on to the front
of the list, with its "fd" pointer ("forward") pointing to the old first
node of the list:

   Before free(A): B -> C -> NULL
   After free(A):  A -> B -> C -> NULL

Allocations simply pull off the first node, making each fastbin a LIFO
queue.

If A is freed twice in a row, A gets tacked to the front of the list on
the first free.  On the second free, the first node (A) is saved, the
new node (also A) is set to the first node, and the new first node's
pointer to the next node (A's "fd" pointer) is set to the old first node
(A).  This creates an infinite loop when the fastbin must be traversed
for bookkeeping (malloc_consolidate), which happens (among other
occasions) with larger allocations.

Here is some code that reproduces this:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    char *one, *two, *three;

    printf("doing small allocations\n");

    one = (char *) malloc(2);
    two = (char *) malloc(2);
    three = (char *) malloc(2);

    printf("freeing the last allocation twice\n");

    free(three);
    free(three);

    printf("allocating a lot of memory\n");

    three = (char *) malloc(1048576);

    printf("done\n");
    return 0;
}

On my i386 system, this segfaults fairly quickly in the middle of the
last malloc():

----------
(gdb) break main
Breakpoint 1 at 0x80483d4: file test.c, line 8.
(gdb) run
Starting program: /home/jeff/tmp/libc-malloc-test/test

Breakpoint 1, main (argc=1, argv=0xbffffbd4) at test.c:8
8           printf("doing small allocations\n");
(gdb) n
doing small allocations
10          one = (char *) malloc(2);
(gdb) n
11          two = (char *) malloc(2);
(gdb) n
12          three = (char *) malloc(2);
(gdb) n
14          printf("freeing the last allocation twice\n");
(gdb) n
freeing the last allocation twice
16          free(three);
(gdb) n
17          free(three);
(gdb) n
19          printf("allocating a lot of memory\n");
(gdb) n
allocating a lot of memory
21          three = (char *) malloc(1048576);
(gdb) n

Program received signal SIGSEGV, Segmentation fault.
malloc_consolidate (av=0x40147fc0) at malloc.c:4368
4368    malloc.c: No such file or directory.
        in malloc.c
(gdb) bt
#0  malloc_consolidate (av=0x40147fc0) at malloc.c:4368
#1  0x40089ce8 in _int_malloc (av=0x40147fc0, bytes=135065) at
malloc.c:3797
#2  0x40088ed3 in __libc_malloc (bytes=1048576) at malloc.c:3296
#3  0x08048447 in main (argc=1, argv=0xbffffbd4) at test.c:21
(gdb)
----------

In researching this bug, I learned that malloc was reimplemented in
glibc 2.3, so I cannot say if this bug affects glibc 2.2 or earlier.

The severity deserves an explanation.  I found this bug as part of my
work on getting Debian in shape for LSB 2.0.  It appears that test
/tset/LSB.os/genuts/glob/T.glob 29 does a double-free which tweaks this
bug.  That test ends up succeeding, but the next test (test 30) hangs at
the very first attempt to allocate memory through no fault of its own. 
This causes bogus test failures, which will have an impact on Debian's
ability to certify under at least LSB 2.0.  I suspect that the LSB 1.3
version of this test will experience similar problems.

One might argue that the LSB's double-free is the real problem, and I
will indeed be working with the LSB people to get this problem solved. 
Unfortunately, it's very possible that the LSB will not be in a position
to fix this bug in a timely manner, and thus it would be better to fix
the underlying incorrect behavior in glibc.

I won't argue with a severity adjustment, though.

I will have to write a workaround patch to fix this problem, and will
attach it to this bug report when it is ready.


---------------------------------------
Received: (at 260767-done) by bugs.debian.org; 10 Aug 2004 20:08:31 +0000
>From licquia@progeny.com Tue Aug 10 13:08:31 2004
Return-path: <licquia@progeny.com>
Received: from jeffindy.licquia.org [216.37.46.185] 
	by spohr.debian.org with esmtp (Exim 3.35 1 (Debian))
	id 1Bucv9-0007bj-00; Tue, 10 Aug 2004 13:08:31 -0700
Received: from sentinel.licquia.org (unknown [192.168.53.1])
	by jeffindy.licquia.org (Postfix) with ESMTP id 98BAB1BB87
	for <260767-done@bugs.debian.org>; Tue, 10 Aug 2004 15:08:30 -0500 (EST)
Received: from server2.internal.licquia.org (server2.internal.licquia.org [192.168.50.4])
	by sentinel.licquia.org (Postfix) with ESMTP id 5509ED520
	for <260767-done@bugs.debian.org>; Tue, 10 Aug 2004 15:08:29 -0500 (EST)
Received: by server2.internal.licquia.org (Postfix, from userid 1000)
	id 2467810A6FE; Tue, 10 Aug 2004 15:08:29 -0500 (EST)
Received: from [192.168.52.2] (laptop1.internal.licquia.org [192.168.52.2]) by
	server2.internal.licquia.org (tmda-ofmipd) with ESMTP;
	Tue, 10 Aug 2004 15:08:23 -0500 (EST)
Subject: source of double-free found
To: 260767-done@bugs.debian.org
Content-Type: text/plain
Message-Id: <1092168502.2750.18.camel@laptop1>
Mime-Version: 1.0
X-Mailer: Ximian Evolution 1.4.6 
Date: Tue, 10 Aug 2004 15:08:22 -0500
Content-Transfer-Encoding: 7bit
From: Jeff Licquia <licquia@progeny.com>
X-Delivery-Agent: TMDA/1.0.3 (Seattle Slew)
Delivered-To: 260767-done@bugs.debian.org
X-Spam-Checker-Version: SpamAssassin 2.60-bugs.debian.org_2004_03_25 
	(1.212-2003-09-23-exp) on spohr.debian.org
X-Spam-Status: No, hits=-3.0 required=4.0 tests=BAYES_00 autolearn=no 
	version=2.60-bugs.debian.org_2004_03_25
X-Spam-Level: 

See bug 264884 for the source of the double-free, which is also in
glibc.



Reply to: