描述
产品试图关闭或释放资源或处理不止一次,没有任何成功打开之间的关闭操作。
扩展描述
代码通常需要“开放”处理或引用资源如内存、文件、设备、套接字连接,服务,等。当代码完成和使用资源,它通常将“关闭”或“释放”的资源,这表明环境(如操作系统),可以重新分配资源或重用不相关的进程或演员,或者在某些情况下,在相同的过程。API函数或其他抽象通常用于执行此版本,如免费()或删除()在C / c++中,或文件句柄关闭()操作中使用多种语言。
不幸的是,这种api的实现或设计可能期望开发人员负责确保这些api只叫一次每释放资源。如果开发人员试图释放相同的资源/处理不止一次,那么这个API的期望没有得到满足,导致未定义和/或不安全的行为。这可能导致后果,比如内存损坏,数据丢失,执行路径腐败或其他后果。
注意,尽管大多数(如果不是全部的话)的实现资源预订涉及分配一个惟一的标识符/指针/符号引用,如果这个标识符是重用,检查资源的标识符关闭可能会导致一个错误的错误的资源的开放和关闭的状态。出于这个原因,标识符是气馁的重用。
的关系
此表显示了弱点和高水平类别相关的这一弱点。这些关系被定义为ChildOf、ParentOf MemberOf,并洞察类似项目可能存在的在较高和较低的抽象级别。此外,关系如PeerOf和CanAlsoBe定义显示类似的弱点,用户可能想要探索。
模式的介绍
不同模式的引入提供了信息如何以及何时可以纳入这一弱点。生命周期的阶段识别点的介绍可能发生,而相关的报告提供了一个典型的场景介绍在给定的阶段。
常见的后果
这个表指定不同的个人相关后果的弱点。标识应用程序范围的安全领域侵犯,而影响了负面的技术影响,如果敌人成功利用这个弱点。可能提供的信息如何可能的具体结果预计将看到列表中相对于其它后果。例如,可能会有高可能性,缺点将被利用来实现一定的影响,但较低的可能性,它将被利用来实现不同的影响。
示范例子
示例1
这个例子中两次试图关闭一个文件。在某些情况下,C库文件关闭()函数将捕获错误和返回一个错误代码。在其他实现双重释放(cwe - 415)发生,导致程序错误。注意,这里给出的例子是简单,双fclose()调用经常会遍布一个程序,使他们更难找到在代码审查。
字符b [2000]; 文件* f = fopen (“dbl_cls。c”、“r”); 如果(f) {
b [0] = 0; 从文件中读(b 1 sizeof (b) - 1, f); printf (" % s \ n’”, b); int r1 = fclose (f); printf (" \ n - - - - - - - - - - - - - - - - - - \ n1接近完成% d \ n”, r1);
int r2 = fclose (f);/ /双闭 printf(" 2近% d \ n”完成,r2); }
有多种可能的修复。这解决只有一个叫fclose(),它通常是首选的处理这个问题,但这个简单的方法并不总是可能的。
字符b [2000]; 文件* f = fopen (“dbl_cls。c”、“r”); 如果(f) {
b [0] = 0; 从文件中读(b 1 sizeof (b) - 1, f); printf (" % s \ n’”, b); int r =文件关闭(f); printf (" \ n - - - - - - - - - - - - - - - - - - \ n1接近完成% d \ n”, r); }
这个修复使用国旗叫fclose()只有一次。注意,这个标志是明确的。“f”的变量也可以被使用,因为它将是NULL如果文件不能被打开或一个有效的指针如果文件被成功打开了。如果“f”取代“f_flg”那么“f”后需要设置为NULL第一fclose()调用第二个文件关闭电话永远不会被执行。
字符b [2000]; int f_flg = 0; 文件* f = fopen (“dbl_cls。c”、“r”); 如果(f) {
f_flg = 1; b [0] = 0; 从文件中读(b 1 sizeof (b) - 1, f); printf (" % s \ n’”, b); 如果(f_flg) {
int r1 = fclose (f); f_flg = 0; printf (" \ n - - - - - - - - - - - - - - - - - - \ n1接近完成% d \ n”, r1);
}
如果(f_flg) {
int r2 = fclose (f);/ /双闭 f_flg = 0; printf(" 2近% d \ n”完成,r2);
}
}
示例2
下面的代码显示了一个简单的双自由漏洞的例子。
char * ptr = (char *) malloc(大小); … 如果(abrt) {
免费(ptr); } … 免费(ptr);
双自由漏洞有两个共同的(有时是重叠的)原因:
-
错误条件和其他特殊情况
-
混乱的程序负责释放内存的一部分
虽然有些双自由漏洞并不比这个例子更复杂,大多数分布在数百行代码,甚至不同的文件。程序员似乎特别容易释放全局变量不止一次。
观察到的例子
参考 |
描述 |
|
文件描述符双关闭可能会导致错误的文件被关联到一个文件描述符。 |
|
|
|
双合成摆脱某些错误条件。 |
潜在的缓解措施
实施阶段:
修改代码的逻辑,以便资源只收一次。这可能需要简化或重构。此修复小代码块可以是简单的,但是更加困难当多个关闭埋在复杂的条件。 |
实施阶段:
它可以有效实现国旗时(1)设置资源打开,(2)清除时关闭,(3)之前检查关闭。这种方法可能是有用的在不同的情况下,关闭必须执行。然而,flag-tracking可以增加代码的复杂性,需要由程序员勤奋的遵从性。 |
实施阶段:
当关闭一个资源时,资源相关联的变量设置为NULL或等值为给定的语言。一些api将忽略这个空值不会造成错误。对于其他api,这可能导致程序崩溃或例外,这可能仍然是比腐化一个意想不到的资源,如内存或数据。
|
检测方法
自动静态分析
对于常用的api和资源类型,自动化工具都有签名,可以发现这个问题。 |
自动动态分析
一些编译器仪表工具如AddressSanitizer(峨山)可以间接检测出这个弱点的一些实例。 |
笔记
术语
相关的术语“释放”可能取决于资源的类型,编程语言,规范,或框架。“关闭”也用于释放资源,比如文件描述符和文件句柄。“回归”有时被用来代替。“免费”通常用在当释放内存或缓冲回系统重用。
引用
|