ASAN heap use after free

14,126

Unfortunately your problem isn't really solvable.

When you have multiple copies of the same pointer, e.g.

int *p1 = malloc(sizeof (int));
int *p2 = p1;
int *p3 = p2;

then freeing any of them invalidates all of them:

free(p2);
// Now p1, p2, p3 have invalid values.
// The C standard calls these "indeterminate values"; accessing them has undefined behavior

You can manually set p2 to NULL after freeing, but that still leaves p1 and p3 dangling. You cannot automatically find all copies of a pointer value that may exist anywhere in your program's memory.

You need to restructure the logic of your program. There is no quick and easy fix.

Share:
14,126
Sanjay
Author by

Sanjay

Updated on June 04, 2022

Comments

  • Sanjay
    Sanjay almost 2 years

    I am running ASAN for finding memory leaks in a very big project. I have found out the cause, but do not know how to resolve it. I have made a sample program to make the problem understandable. In the below program I can only work-around on specified code. For rest of the code it is not possible to do work around. So please suggest what work around I may have to resolve below ASAN error. (How to make pointer two as NULL using t1?)

    #include<stdio.h>
    #include<stdlib.h>
    
    typedef struct l
    {
        int a, b;
    }pack;
    
    void delete_me(pack *ap)
    {
        free(ap);
    }
    
    int main(void)
    {
        pack **d_ptr = (pack **)malloc(3 * sizeof(pack *));
        pack *one, *two, *three;
        one = (pack *)malloc(sizeof(pack));
        one->a = 1, one->b = 2;
        two = (pack *)malloc(sizeof(pack));
        two->a = 3, two->b = 4;
        three = (pack *)malloc(sizeof(pack));
        three->a = 5, three->b = 6;
        d_ptr[0] = one;
        d_ptr[1] = two;
        d_ptr[2] = three;
    
        // I can Only work-around below code (4 lines)
        pack *t1 = d_ptr[1]; // For which index t1 would be assigned, is not known before hand
        t1->a = 1; t1->b = 2;
        printf("a: %d, b: %d\n", two->a, two->b);
        delete_me(t1); // How to delete t1 so that corresponding pointer also becomes NULL?
        // Work around only till here was possible.
    
        // Below this, No workaround possible.
        if (two && (two->a == one->a)) // ASAN ERROR
                printf("ERROR\n");
        else
                printf("It works!\n");
        return 0;
    }
    

    ASAN Error: ERROR: AddressSanitizer: heap-use-after-free