avr-libc-dev
[Top][All Lists]
Advanced

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

[avr-libc-dev] [bug #25723] Realloc corrupts free list when growing into


From: Lou Amadio
Subject: [avr-libc-dev] [bug #25723] Realloc corrupts free list when growing into the next free item
Date: Sat, 28 Feb 2009 17:12:30 +0000
User-agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_6; en-us) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16

Follow-up Comment #4, bug #25723 (project avr-libc):

Updated diff

(sorry about the 'blessed' comment - it was originally a blog post,
attempting to understand the avr-lib checkin and unit testing process in order
to 'bless' the fix)

Index: realloc.c
===================================================================
RCS file: /sources/avr-libc/avr-libc/libc/stdlib/realloc.c,v
retrieving revision 1.4
diff -u -r1.4 realloc.c
--- realloc.c   8 Feb 2005 20:34:17 -0000       1.4
+++ realloc.c   28 Feb 2009 17:10:38 -0000
@@ -46,21 +46,21 @@
        char *cp, *cp1;
        void *memp;
        size_t s, incr;
-
+       
        /* Trivial case, required by C standard. */
        if (ptr == 0)
                return malloc(len);
-
+       
        cp1 = (char *)ptr;
        cp1 -= sizeof(size_t);
        fp1 = (struct __freelist *)cp1;
-
+       
        cp = (char *)ptr + len; /* new next pointer */
        if (cp < cp1)
-               /* Pointer wrapped across top of RAM, fail. */
+       /* Pointer wrapped across top of RAM, fail. */
                return 0;
-       fp2 = (struct __freelist *)cp;
-
+       fp2 = (struct __freelist *)(cp - sizeof(size_t));
+       
        /*
         * See whether we are growing or shrinking.  When shrinking,
         * we split off a chunk for the released portion, and call
@@ -79,21 +79,19 @@
                free(&(fp2->nx));
                return ptr;
        }
-
+       
        /*
         * If we get here, we are growing.  First, see whether there
         * is space in the free list on top of our current chunk.
         */
-       incr = len - fp1->sz - sizeof(size_t);
+       incr = len - fp1->sz;
        cp = (char *)ptr + fp1->sz;
-       fp2 = (struct __freelist *)cp;
        for (s = 0, ofp3 = 0, fp3 = __flp;
-            fp3;
-            ofp3 = fp3, fp3 = fp3->nx) {
+               fp3;
+               ofp3 = fp3, fp3 = fp3->nx) {
                if (fp3 == fp2 && fp3->sz >= incr) {
                        /* found something that fits */
-                       if (incr <= fp3->sz &&
-                           incr > fp3->sz - sizeof(struct __freelist)) {
+                       if (incr <= fp3->sz + sizeof(size_t)) {
                                /* it just fits, so use it entirely */
                                fp1->sz += fp3->sz + sizeof(size_t);
                                if (ofp3)
@@ -104,7 +102,7 @@
                        }
                        /* split off a new freelist entry */
                        cp = (char *)ptr + len;
-                       fp2 = (struct __freelist *)cp;
+                       fp2 = (struct __freelist *)(cp - sizeof(size_t));
                        fp2->nx = fp3->nx;
                        fp2->sz = fp3->sz - incr - sizeof(size_t);
                        if (ofp3)
@@ -141,7 +139,7 @@
                /* If that failed, we are out of luck. */
                return 0;
        }
-
+       
        /*
         * Call malloc() for a new chunk, then copy over the data, and
         * release the old region.


    _______________________________________________________

Reply to this item at:

  <http://savannah.nongnu.org/bugs/?25723>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.nongnu.org/





reply via email to

[Prev in Thread] Current Thread [Next in Thread]