Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

I am trying to track use-after-free errors in C. And my question is that, if I have the 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 the use of aliasA is a UAF error? If it is, what is going wrong here?

To clear the question, I think it is 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 output is:

5
66

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

From the output above, it seems like the use of ptr2 gives the same output as new_ptr.

When I wrote my solution to detect UAF error, I record the information of pointers. The pointers' values are stored as uint64_t and a boolean type flag is to declare whether the pointer is alive.

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

Thanks in advance!

like image 731
Xy Luo Avatar asked Dec 20 '17 04:12

Xy Luo


People also ask

What happens when a pointer is freed?

The function free takes a pointer as parameter and deallocates the memory region pointed to by that pointer. The memory region passed to free must be previously allocated with calloc , malloc or realloc . If the pointer is NULL , no action is taken.

Does malloc need to be freed?

But the memory allocation using malloc() is not de-allocated on its own. So, “free()” method is used to de-allocate the memory. But the free() method is not compulsory to use.

Can you reassign pointer after freeing it?

When you declare a pointer it will be allocated for it a memory location. That location can be reassigned. If you reassign it after having assigned it a value with a malloc() call and before to free() it, this is a memory leak. After free() you can reassign it and no leak will happen, do not forget to free() it again.

What does pointer being freed was not allocated?

It means you're only supposed to call free on a pointer you obtained from malloc , realloc or calloc .


1 Answers

If you don't dereference the pointer aliasA, it depends on the definition of "use after free" whether this constitutes "use after free". For example CWE-416 doesn't talk about just using the pointer value, but about dereferencing it, i.e. using the object that was freed.

However, the C standard says that even using the pointer value has undefined behaviour (Appendix J.2):

  1. The behavior is undefined in the following circumstances:

    [...]

    • The value of a pointer that refers to space deallocated by a call to the free or realloc function is used (7.22.3).

This is because the value of the pointer becomes indeterminate:

The value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime.

Therefore the following code has undefined behaviour:

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");
}

The comparison there is meaningless and the compiler is given the freedom to do whatever it pleases with its optimization, as aliasA doesn't need to contain a valid value any more. It is totally OK for a compiler to even to set a trap into aliasA which would cause your program to abort at the if statement with a diagnostics message. Or it can be that these could seem to point to the same address even though they were given distinct addresses of memory, or vice versa.

like image 118