新指针(通过malloc)与已释放/旧指针之一相同 [英] New pointer (by malloc) is same as one of the freed/old pointers

查看:104
本文介绍了新指针(通过malloc)与已释放/旧指针之一相同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试跟踪C中的释放后使用"错误. 我的问题是,如果我有这样的代码:

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

只是想知道aliasA的使用是否是UAF错误? 如果是,这是怎么了?

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

输出为:

5
66

(我在S2E中检查了ptrnew_ptr: http://s2e.systems/和这两个指针实际上指向相同的地址.释放ptr之后,会将相同的地址分配给new_ptr.)

(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.)

从上面的输出中,似乎使用ptr2会提供与new_ptr相同的输出.

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

当我编写解决方案来检测UAF错误时,我记录了指针的信息.指针的值存储为uint64_t,布尔类型flag用于声明指针是否有效.

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.

因此,我猜想new_ptrptr指向相同的地址时会出现问题,因为一旦malloc()被调用,而flagflag将变为true.之后,当我使用ptr时,由于该地址被标记为活动状态,因此无法检测到该UAF错误.

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.

提前谢谢!

推荐答案

如果您不取消引用指针aliasA,则是否构成自由使用后使用"的定义免费使用后使用".例如, CWE-416 并不是只说使用指针值,但要取消引用,即使用已释放的 object .

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.

但是,C标准指出,即使使用指针值也具有未定义的行为

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

  1. 在以下情况下该行为未定义:

  1. The behavior is undefined in the following circumstances:

[...]

  • 使用了指向通过调用free或realloc函数释放的空间的指针的值(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");
}

进行比较是没有意义的,编译器可以自由地进行优化,因为aliasA不再需要包含 valid 值.编译器甚至可以在aliasA中设置陷阱,这将完全使您正常运行,这将导致您的程序在if语句中中止并带有诊断消息.或者,即使给了它们不同的内存地址,它们似乎也指向相同的地址,反之亦然.

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.

这篇关于新指针(通过malloc)与已释放/旧指针之一相同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆