The new pointer (by malloc) is the same as one of the freed / old pointers

I am trying to track errors after using in C. And my question is if I have code like this:

A * ptrA = malloc(sizeof(A)); A * aliasA = ptrA; // do something ' free(ptrA) // some other code B * ptrB = malloc(sizeof(B)); // assume this return same pointer as ptrA //trying to use aliasA here 

Just wondering if using aliasA is UAF error? If so, what is going wrong here?

To fix this question, I think it’s better to add a small example:

 int main(){ int *ptr = (int *)malloc(4); *ptr = 5; int *ptr2 = ptr; printf("%d\n", *ptr); free(ptr); int *new_ptr = malloc(4); *new_ptr = 66; printf("%d\n", *ptr2); return 0; } 

And the result:

 5 66 

(I checked ptr and new_ptr in S2E: http://s2e.systems/ , and these two pointers actually point to the same address. After releasing ptr, the same address is assigned to new_ptr.)

From the above output, it seems that using ptr2 gives the same result as new_ptr .

When I wrote my solution for detecting a UAF error, I write down the pointer information. Pointer values ​​are stored as uint64_t , and the boolean type flag is used to declare whether the pointer is alive.

Therefore, I assume that the problem occurs when the new_ptr and ptr tags point to the same address, because once malloc() is called flag new_ptr will turn true . After that, when I use ptr , I can not detect this UAF error, because this address is marked as live.

Thanks in advance!

+5
source share
3 answers

If you are not looking for the aliasA pointer, it depends on the definition of "use after free", whether it means "use after free." For example, CWE-416 does not mean simple use of the pointer value, but dereferencing it, i.e. Using a freed object.

However, the C standard states that even using a pointer value has undefined behavior (Appendix J.2) :

  • Undefined behavior in the following cases:

    [...]

    • A pointer value is used that refers to the space freed up by calling the free or realloc function (7.22.3).

This is because the pointer value becomes undefined :

The pointer value becomes undefined when the object it points to (or has just passed) reaches the end of its life.

Therefore, the following code has undefined behavior:

 A *ptrA = malloc(sizeof(A)); A *aliasA = ptrA; free(ptrA); A *ptrB = malloc(sizeof(A)); if (aliasA == ptrB) { // undefined behaviour, as it might be a trap printf("We were given the same pointer"); } 

Comparison is pointless there, and the compiler is given the freedom to do what he likes with its optimization, since aliasA no longer needs to contain a valid value. This is quite normal for the compiler even to set a trap in aliasA , which will cause your program to interrupt in the if with a diagnostic message. Or it may happen that they can point to the same address, even if they were given different memory addresses or vice versa.

+3
source

This is a UAF error.

In practice, it is unlikely that the second call to malloc() returns the same address as aliasA , since the behavior is not guaranteed. You should not rely on this.

You may ask: can I compare them to make sure they have the same address? Oh no. The comparison may have some meaning for you, but this behavior is undefined, because comparing pointer equality is only valid if two pointers point to different elements in the same array. In this case, the two allocated blocks are probably not the same array, so the comparison between these pointers is not defined.

Finally, you should not rely on the address returned by malloc() . All you can do is use it in the amount of memory requested by the call.

In practice, Thiru Shetty's Answer is a good way to pursue.

+1
source

aliasA is a UAF error, it may contain the same value as ptrA , but it is not guaranteed, and it is recommended that you reassign a freed pointer (both aliasA and ptrA) to NULL to avoid a dangling pointer .

In your case, it is better to assign NULL after free :

 free(ptrA); free(aliasA); ptrA = NULL; aliasA = NULL; 
0
source

Source: https://habr.com/ru/post/1274210/


All Articles