From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26223 invoked by alias); 21 Dec 2013 00:39:47 -0000 Mailing-List: contact glibc-bugs-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: glibc-bugs-owner@sourceware.org Received: (qmail 26169 invoked by uid 48); 21 Dec 2013 00:39:43 -0000 From: "neleai at seznam dot cz" To: glibc-bugs@sourceware.org Subject: [Bug malloc/15073] Race condition using ATOMIC_FASTBINS in _int_free causes crash or heap corruption Date: Sat, 21 Dec 2013 00:39:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: glibc X-Bugzilla-Component: malloc X-Bugzilla-Version: 2.15 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: neleai at seznam dot cz X-Bugzilla-Status: NEW X-Bugzilla-Priority: P2 X-Bugzilla-Assigned-To: unassigned at sourceware dot org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_status cc Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-Bugzilla-URL: http://sourceware.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-SW-Source: 2013-12/txt/msg00189.txt.bz2 https://sourceware.org/bugzilla/show_bug.cgi?id=15073 Ondrej Bilka changed: What |Removed |Added ---------------------------------------------------------------------------- Status|WAITING |NEW CC| |neleai at seznam dot cz --- Comment #6 from Ondrej Bilka --- Carlos, this is faster to debug on paper than trying debug optimized program. For minimal example what is wrong I could trigger assert for unoptimized version of malloc. In optimized version you need go to assembly to see where gcc scheduled loads. Idea is simple, while we free one chunk then a chunk on top of fastbin could be in other thread allocated, resized and then returned back into top of fastbin to trigger assertion or seqfault when trim unmaps corresponding page. A program is following, #include #include void * freea (void *p) { free (p); // 1 } int main () { pthread_t x; char *u, *v; u = malloc (16); pthread_create (&x, NULL, freea, u); v = malloc (16); free (v); // 2 malloc_trim (0); v = malloc (512); // 3 free (v); malloc_trim (0); v = malloc (16); free (v); // 4 } First step into free 1 until you get to this fragment. Here run free 2 so v gets into top of fastbin. unsigned int idx = fastbin_index(size); // 32 >> 4 = 2 fb = &fastbin (av, idx); mchunkptr fd; mchunkptr old = *fb; // v unsigned int old_idx = ~0u; do { /* Another simple check: make sure the top of the bin is not the record we are going to add (i.e., double free). */ if (__builtin_expect (old == p, 0)) { errstr = "double free or corruption (fasttop)"; goto errout; } Now here run step 3 where v is chunk of size 528 if (old != NULL) old_idx = fastbin_index(chunksize(old)); // 528 >> 4 = 33 p->fd = fd = old; And continue by step 4 which returns v into top of fastbin. which is same state as at 2. } while ((old = catomic_compare_and_exchange_val_rel (fb, p, fd)) != fd); And as 33 != 2 we cause an error. if (fd != NULL && __builtin_expect (old_idx != idx, 0)) { errstr = "invalid fastbin entry (free)"; goto errout; } -- You are receiving this mail because: You are on the CC list for the bug.