1
* glibc detected ./load: double free or corruption (!prev): ADDRESS **

When using glibc, how does it know that I am double-freeing? Does it keep track of everything I malloced and freed? Is it contained in metadata like how free knows how much space to free (How does free know how much to free?)

Community
  • 1
  • 1
Secret
  • 3,291
  • 3
  • 32
  • 50

4 Answers4

6

For each allocation, memory manager keeps some 'header' (most likely tree node or linked list). When you passed to free something that doesn't contain valid header - well, it couldn't correctly be freed. As for where this information is being kept - it's up to implementation, but usually it placed right before address you got from malloc - however, size and structure is very likely to be unknown, but at least it gives an idea how easily this header could be broken/corrupted/overwritten/etc.

keltar
  • 17,711
  • 2
  • 37
  • 42
  • Is this based on speculation about how the memory manager could work or actual knowledge of its specification or implementation? – Eric Postpischil Sep 03 '13 at 11:29
  • There is no specification. Everything is up to implementation. It's how most malloc's works - at least glibc and many others. Surely there are many other ways - e.g. OpenBSD's malloc actually uses mmap for every allocation. – keltar Sep 03 '13 at 11:32
  • @kelter: The fact that the C standard leaves many things up to an implementation does not prevent an implementation from having its own specification. Regardless, is this answer based on speculation or actual knowledge of the implementation? – Eric Postpischil Sep 03 '13 at 11:37
  • There are a number of criteria used, but a [double free doesn't get noted if the header is corrupt](http://sourceware.org/git/?p=glibc.git;a=blob;f=malloc/malloc.c;h=dd295f522c1f7e9953f67808ef8c54880abdc44f;hb=HEAD). In the case of the OP's error, it is simply because the header was already marked as free'd. – user7116 Sep 03 '13 at 11:45
  • I've already answered that in previous comment. And, after two comments, i still don't get your point. The behaviour i've described is correct for glibc, uclibc, and who knows how many others - however, in original answer i've explicitly stated that implementations may vary. – keltar Sep 03 '13 at 11:48
  • @user7116: Thank you, that is the first answer or comment based on actual information about the implementation. Please consider entering a fuller answer. – Eric Postpischil Sep 03 '13 at 12:07
  • @keltar: I do not see where you have said whether this answer is based on speculation or actual knowledge of the implementation. You have asserted that certain things happen, but you have not stated the source of the information. From what source do these statements come? – Eric Postpischil Sep 03 '13 at 14:15
  • And i see only trolling here. I've already given you answer twice. But okay, if it's so hard to look at source code of glibc - https://sourceware.org/git/?p=glibc.git;a=blob;f=malloc/malloc.c;h=dd295f522c1f7e9953f67808ef8c54880abdc44f;hb=HEAD#l1228 and everything that uses these two macros. – keltar Sep 04 '13 at 03:28
1

When you malloc something, you get a pointer on a memory bloc. You already know that ^^. The memory management also reserve an (hidden) header before* your bloc (which tracks the bloc size for instance) When you free your pointer, the header is red to check if it is a valid pointer. The free operation also erase the header. If you free twice, the header will no longer be valid on the second free. Hence the detection.

johan d
  • 2,798
  • 18
  • 26
  • Is this based on speculation about how the memory manager could work or actual knowledge of its specification or implementation? – Eric Postpischil Sep 03 '13 at 11:28
  • It's from what I learnt (school). Neither speculation, nor spec. Is it false? – johan d Sep 03 '13 at 13:05
  • Neither you nor I know whether it is true or false. The problem is that without a specification or source code or a note from the author’s mother, you cannot rely on software. You do not know what it is supposed to do or how it may change in different versions or with different settings or circumstances. Different implementations of memory management work in different ways. – Eric Postpischil Sep 03 '13 at 14:14
0

The C language standard says that freeing a pointer a second time is undefined behavior. What you see in glibc is one particular case of this undefined behavior--a helpful one--where a message is issued. Most allocators keep track of what is allocated and up to a certain amount it can keep track of what has been freed. But you cannot count on this behavior.

A C program is also allowed to silently crash or ignore the situation (or any other action it deems necessary).

Jens
  • 69,818
  • 15
  • 125
  • 179
  • 1
    The question asks how the behavior is accomplished, not why it is permitted by the standard or what it is. – Eric Postpischil Sep 03 '13 at 11:26
  • 2
    @EricPostpischil The question starts with "In C, how does it know..." and it is tagged *only C*. Since C doesn't make any statement other than that it's undefined, the OP should know that. And I even answered how it is accomplished, by tracking what has been freed. Just what is your problem, dude? – Jens Sep 03 '13 at 11:39
  • The OP is clearly using glibc. A genuine answer could both educate them about software engineering and give them information to help determine whether glibc could reliably detect certain kinds of bugs. Depending on the method used, glibc might (in theory) guarantee that any double free within, say, 16 free calls of the original is detected, or that there is no guarantee, or that additional information can be obtained by interrogating some special interface. The point is, there IS some detection method in use, and answers like this are inappropriate because they dissuade people… – Eric Postpischil Sep 03 '13 at 11:57
  • … from pursuing knowledge. There is much more to computing than “here is the C standard, stay within it and never look beyond it.” – Eric Postpischil Sep 03 '13 at 11:58
0

The memory allocated by malloc(), calloc() or realloc() does have a metadata for the allocation, which is used by free() to de-allocate the allocated memory.

However, one should not make any assumptions about how or whether the double free is detected as the behavior is undefined in the standard as stated below.

free() frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(), calloc() or realloc(). Otherwise, or if free(ptr) has already been called before, undefined behavior occurs. If ptr is NULL, no operation is performed.

HAL
  • 3,888
  • 3
  • 19
  • 28
  • This does not answer the question. – Eric Postpischil Sep 03 '13 at 11:29
  • 1
    @EricPostpischil Since the behavior is undefined in the C standard, how it could or might be detected is irrelevant. – HAL Sep 03 '13 at 11:43
  • Nonetheless, this “answer” does not answer the question. The method is relevant both to library implementors and to people who want to use features of a particular library (e.g., people who believe that detection of certain errors could help them find bugs). – Eric Postpischil Sep 03 '13 at 11:49
  • 1
    I believe it does from the C perspective(the original question). – HAL Sep 03 '13 at 11:56