bugAVR C Runtime Library - Bugs: bug #40535, realloc(xxx, 0) doesn't free

 
 

You are not allowed to post comments on this tracker with your current authentication level.

bug #40535: realloc(xxx, 0) doesn't free

Submitter:  Thomas R. <glglgl>
Submitted:  Sun 10 Nov 2013 11:11:09 AM UTC
   
 
Category:  Library Severity:  3 - Normal
Priority:  5 - Normal Item Group:  libc code
Status:  Need Info Assigned to:  joerg_wunsch
Percent Complete:  0% Open/Closed:  Open
Release:  1.8.0 Fixed Release:  None

Sun 10 Nov 2013 09:34:41 PM UTC, comment #4: 

I stand corrected. I saw in the Linux man page for realloc(3) that calling it with length == 0 would require to free() and thought this was actually required by the standard. But I don't find that in the standard, so probably I was wrong there.




About my claim concerning destroyed free list, I stand corrected as well. The free list is not destroyed immediately, but:

    * cp1 and fp1 point to ptr-sizeof(size_t)
    * cp and fp2 point to ptr + len, which is ptr if len == 0
    This makes fp1->nx and fp2->sz sharing the same address (ptr) []
    * the fp2 part is added as a new entry to the free list, leaving the old memory block having a length field of 0 and nothing else, even no space for a ->nx pointer.

This does not hurt until I call free(ptr), ptr being the value just returned from realloc(). There the fact [*] above makes it impossible to add the now being freed part, which is uncapable to hold a nx pointer, to the free list, as the said fp2->sz is now tampered as well.No matter if that part of memory is still free or allocated in the meanwhile, this leads to trouble sooner or later.

This fact makes this bug a duplicate of bug #32702, which AFAICS already contains a test case and which I would consider as rather severe and important in turn.

Additionally, I'd like to write a test case proving that the bug is destructive if realloc() is called with a new length of < sizeof((struct __freelist).nx) if that is necessary. But that may take some days, as I first would have to wrap my head around making the test cases work in my build environment. Maybe I get the opportunity in the next days to do so.

Again, sorry for the noise made by contradicting myself, and for sounding quite vague, but nevertheless I hope that I could contribute and/or help concerning that bug #32702.

Thomas R. <glglgl>
Sun 10 Nov 2013 01:03:25 PM UTC, comment #3: 


> If this doesn't get fixed, the code in realloc()
> ignores the fact that fp1 == fp2 and there happen
> potentially nasty things with the freelist.


Could you provide a testcase for this?  Ideall, something
that would fit into tests/simulate/stdlib/realloc-*.c.

Joerg Wunsch <joerg_wunsch>
Group administrator
Sun 10 Nov 2013 12:55:45 PM UTC, comment #2: 


> realloc(xxx, 0) is supposed to free the given memory block if xxx is not NULL


Can you point me to a wording in the standard that would
require this?  I can't seem to find something to that effect.

The rationale allows this to be one possible implementation,
but it's not mandated.  Our implementation simply deallocates
as much as possible, and the returned object pointer is
consistent with a pointer to an object resulting out of
malloc(0).

I tend to dismiss the request since it bears the risk of
introducing new bugs, of course unless someone can prove the
existing implementation violates the C standard.

Joerg Wunsch <joerg_wunsch>
Group administrator
Sun 10 Nov 2013 11:15:47 AM UTC, comment #1: 

I hope the project still lives on that given SVN and I don't suggest something that has already been fixed.

If this doesn't get fixed, the code in realloc() ignores  the fact that fp1 == fp2 and there happen potentially nasty things with the freelist.

Thomas R. <glglgl>
Sun 10 Nov 2013 11:11:09 AM UTC, original submission:  

realloc(xxx, 0) is supposed to free the given memory block if xxx is not NULL, If xxx is NULL, realloc() is supposed to work like malloc().

So I suggest to modify

http://svn.sv.gnu.org/viewvc/trunk/avr-libc/libc/stdlib/realloc.c?revision=2127&root=avr-libc&view=markup

in that way to add after

/* Trivial case, required by C standard. */
if (ptr == 0)
return malloc(len);

the lines

/* Another trivial case, required by C standard. */
if (len == 0) {
free(ptr);
                return NULL;
        }

because in this case

  • realloc(NULL, 0) returns the same as malloc(0)
  • realloc(anythingelse, 0) does free(anythingelse).


This behaviour is required by the standard.

Thomas R. <glglgl>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by joerg_wunsch (Posted a comment)
  • -email is unavailable- added by glglgl (Submitted the item)
  •  

    Follow 2 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2013-11-10 joerg_wunsch StatusNone Need Info
        Assigned toNone joerg_wunsch

    Back to the top

    Powered by Savane 3.13-758e.
    Corresponding source code