新指针(通过malloc)与已释放/旧指针之一相同 [英] New pointer (by malloc) is same as one of the freed/old pointers
问题描述
我正在尝试跟踪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中检查了ptr
和new_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_ptr
和ptr
指向相同的地址时会出现问题,因为一旦malloc()
被调用,而flag
的flag
将变为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.
However, the C standard says that even using the pointer value has undefined behaviour (Appendix J.2):
-
在以下情况下该行为未定义:
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屋!