“双免费”是什么意思?

时间:2014-01-11 01:25:27

标签: c theory double-free

正如标题所暗示的那样,我是C的新手并且很快就会出现中期。我正在修改过去的论文,一个反复出现的主题是双重免费问题。我知道这是在同一个内存位置上调用free()两次的过程,但我有几个问题,我不是100%肯定如何回答:

问题1:C中双重免费的结果是什么,为什么会出现这样的问题?

这将导致双重免费:

char* ptr = malloc(sizeof(char));

*ptr = 'a';
free(ptr);
free(ptr);

我对此的回应是,它会返回0x0内存地址并导致系统不稳定/崩溃。另外,如果我没记错的话,双重自由实际上可以调用malloc两次,这会导致缓冲区溢出,从而使系统容易受到攻击。

简要总结这个问题的最佳方式是什么?

问题2:描述一种特别容易引入的情况 C中双倍免费?

我在想当你绕过指针时可能会意外地将它释放到一个函数中,并且在没有意识到的情况下再次释放它?

再次,总结这个的“最佳”方式是什么?

4 个答案:

答案 0 :(得分:22)

从技术上讲,C中的双重免费会导致未定义的行为。这意味着该程序可以完全随意地运行,所有投注都不会发生。发生这当然是一件坏事!实际上,双重释放内存块会破坏内存管理器的状态,这可能会导致现有的内存块被破坏,或者将来的分配以奇怪的方式失败(例如,相同的内存分配给两个malloc)的不同连续调用。

双重自由可能发生在各种情况下。一个相当常见的问题是,当多个不同的对象都有指向彼此的指针并开始通过调用free进行清理时。发生这种情况时,如果您不小心,清理对象时可能会多次free同一指针。不过,还有很多其他案例。

希望这有帮助!

答案 1 :(得分:5)

因为free()将通过在每个区域之前管理存储在标签中的信息来合并相邻区域。这就像管理双链表一样。因此,如果ptr所指向的缓冲区已被攻击字符串覆盖,则可能会被注入伪标记。

答案 2 :(得分:2)

这个问题已经得到了很好的解答,但由于重复的问题,我添加了一个迟到的答案"链接,询问"如何避免它?"

在发布的示例代码中添加了一行。

char* ptr = malloc(sizeof(char));

*ptr = 'a';
free(ptr);
ptr = NULL;         // add this
free(ptr);

函数freeNULL指针不执行任何操作。

答案 3 :(得分:0)

根据已发布的C11标准,在已free内存位置调用free会导致未定义的行为。它可能导致奇怪的情况,例如内存即使在可用时也没有被分配,堆被破坏,相同的内存位置被分配给不同的mallocs等。基本上,它是未定义的,可以是任何东西。

ANSI C11标准可以在这里找到。 https://www.iso.org/obp/ui/#iso:std:iso-iec:9899:ed-3:v1:en

编辑:根据评论将NULL更改为已free d。此外,链接现在指向ISO / IEC 9899:2011(en)