Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What should mprobe return when it is passed a pointer to a freed block of memory?

Tags:

c

malloc

free

The GNU libc manual page for mcheck says that the MCHECK_FREE status means "The block was already freed." That would imply to me that the block was freed (at least) once. This answer seems to imply the same in the code example. However, the Linux manpage says quite explicitly that MCHECK_FREE means "A block of memory was freed twice." I modified the code example from the above answer to make it slightly more descriptive:

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

void print_status(enum mcheck_status status)
{
    switch(status)
    {
        case MCHECK_DISABLED:
        printf("MCHECK_DISABLED\n");
        break;

        case MCHECK_OK:
        printf("MCHECK_OK\n");
        break;

        case MCHECK_HEAD:
        printf("MCHECK_HEAD\n");
        break;

        case MCHECK_TAIL:
        printf("MCHECK_TAIL\n");
        break;

        case MCHECK_FREE:
        printf("MCHECK_FREE\n");
        break;
    }
}

void no_op(enum mcheck_status status) {}

int main()
{
    mcheck(&no_op);

    void* f = malloc(4);

    print_status(mprobe(f));

    free(f);

    print_status(mprobe(f));

    return 0;
}

When I run this code I get this output:

MCHECK_OK
MCHECK_HEAD

This means I'm clearly getting MCHECK_HEAD as a response when checking a freed block. Is this behaviour reliable? Is it reasonable to expect that the header of a block will always be clobbered when it is freed? Are there different implementations of mcheck/mprobe that will return MCHECK_FREE instead?

like image 644
Charlim Avatar asked Dec 07 '25 08:12

Charlim


1 Answers

I emailed a libc developer mailing list. I split my problem into 2 questions, each of which were responded to:

  1. Which manual (GNU or Linux) is correct about MCHECK_FREE?

They are both correct, but written from slightly different perspectives.

If the block was previously free'd then you should return MCHECK_FREE.

However, if you can't detect that it was previously free'd because of corruption then you might only be able to return MCHECK_HEAD as the default results if the corruption has changed all co-located metadata about the state information.

  1. Is it reasonable to generally expect that MCHECK_HEAD will be returned [when calling mprobe on a freed pointer]?

Yes.

like image 169
Charlim Avatar answered Dec 08 '25 22:12

Charlim



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!