概念
指对同一个指针指向的内存释放了两次。
对于C语言,同一个指针进行两次Free()操作,可导致二次释放。
对于C++语言,浅复制操作不当时导致二次释放的常见原因之一。例如,调用一次赋值运算符或复制构造函数将会导致两个对象的数据成员指向相同的动态内存。此时,引用计数机制变得非常重要。若引用计数不当,一个对象超出作用域时,析构函数将会释放这两个对象共享的内存。另一个对象中对应的数据成员将会指向已经释放的内存地址,而当这个对象也超出作用域时,他的析构函数试图再次释放这块内存,导致二次释放。
二次释放内存可能导致应用程序崩溃,拒绝服务攻击等,是C/C++常见漏洞之一。
漏洞编号 | 漏洞概述 |
CVE-2018-18751 | GNU gettext 0.19.8 的read-catalog.c 文件中的default_add_message()函数存在二次释放漏洞 |
CVE-2018-17098 | OllieParviainen SoundTouch 2.0 的WavFile.cpp文件中的WavFileBase类存在安全漏洞。远程攻击者可以利用该漏洞造成拒绝服务。 |
CVE-2018-16425 | OpenSC 0.19.0-rcl之前的版本libopensc/pkcs15-sc-hsm.c文件中sc_pkcs15emu_sc-hsm_init()函数存在二次释放漏洞。攻击者可以借助特定的智能卡,利用该漏洞造成拒绝服务(应用程序崩溃)。 |
CVE-2018-16402 | elfutils 0.173的libelf/elf_end.c文件存在安全问题,远程攻击者可利用该漏洞造成拒绝服务(二次释放和应用程序崩溃) |
CVE-2019-5460 | Video LANVLCmediaplayer 3.0.6及之前版本存在二次释放漏洞 |
CVE-2020-8432 | Denx Das U-Boot 2020.01及之前版本的cmd/gpt.c文件中的do_rename_gpt_parts()函数存在二次释放,攻击者可以借助特制请求,利用该漏洞在系统上执行任意代码 |
CVE-2021-26411 | Internet Explorer 中的一个漏洞,2021年黑客组织使用。 |
代码
void Double_Free()
{
int i,j;
char *data;
data = NULL;
for (i=0;i<1;i++)
{
data = (char *) malloc(100*sizeof(char));
if (data==NULL){exit (-1);}\
/*释放data*/
free(data);
}
for (j=0;j<1;j++)
{
/*二次释放data*/
free(data);
}
}
避免Double Free
1. 野指针是导致二次释放和释放后使用的重要原因之一,消除野指针的有效方式是在释放指针后立即把它置为NULL或者设置为指向另一个合法对象。
2. 针对C++浅拷贝导致的二次释放问题,建议使用深拷贝。