编号:415 状态:草稿 |
摘要:变量 结构:简单 |
描述
对同一地址调用两次free()。潜在导致对未知内存位置的修改。
扩展描述
当程序调用两次带有同一参数的free(),程序的内存管理数据结构会崩溃。程序也随之崩溃,或者在某些情况下,会后续导致两次调用返回统一指针malloc()。如果malloc()返回同一指针两次,攻击者将获得对这段两次分配的内存中写入的数据的控制,对于缓冲区溢出攻击,程序会变得脆弱不堪。
关系
下表显示同此弱点相关的弱点以及相关的上层分类。这些关系被定义为“子女”、“父母”、“成员”等等,通过这些关系显示出存在于不同层级的分类中的同此弱点类似的弱点。另外,也定义了“同事”、“还可能是”等关系以便用户探究类似的弱点。
同 "研究层面"视图相关 (CWE-1000)
同"开发层面" 开发概念相关(CWE-699)
引入模式
阶段 | 说明 |
体系结构设计 | |
实现 |
应用平台
语言
C (出现频率不确定)
C++ (出现频率不确定)
一般后果
范围 | 冲击 | 可能性 |
完整性 | 技术冲击: 执行未授权的代码或者命令 双重释放内存可能会导致write_what-where条件,允许攻击者执行任意代码 |
被利用的可能性
高
示例
例1
Example Language: C
char* ptr = (char*)malloc (SIZE);
...
if (abrt) {
free(ptr);
}
...
free(ptr);
“双重释放”有两个通用的原因(有时重叠):
- 错误的条件和其它异常情况
- 对程序哪部分负责释放内存不清楚
虽然有些“释放内存”弱点并不比前面的例子复杂,但是大多数发生在成百上千行代码甚至不同的文件当中。程序员似乎特别容易多次释放全局变量,
例2
虽然是人为设计的,但在Linux发行版上应该可以使用此代码,因为Linux发行版没有启用堆块检查求和功能
(问题代码)
Example Language: C
#include <stdio.h>
#include <unistd.h>
#define BUFSIZE1 512
#define BUFSIZE2 ((BUFSIZE1/2) - 8)
int main(int argc, char **argv) {
char *buf1R1;
char *buf2R1;
char *buf1R2;
buf1R1 = (char *) malloc(BUFSIZE2);
buf2R1 = (char *) malloc(BUFSIZE2);
free(buf1R1);
free(buf2R1);
buf1R2 = (char *) malloc(BUFSIZE1);
strncpy(buf1R2, argv[1], BUFSIZE1-1);
free(buf2R1);
free(buf1R2);
}
潜在缓解措施
阶段: 体系结构规划与设计 选择提供自动内存管理的开发语言 |
阶段: 实现. 确保每块分配的内存仅释放一次。释放后,将指针设置为空,以确保指针无法再次释放。在复杂的错误处理中,请确保清理操作中恰当的考虑了内存分配状态。如果语言是面向对象的,请确保对象析构函数对每个内存块只删除一次。 |
阶段: 实现 使用静态分析工具检测“双重释放” 。 |
从属关系
关系 | 类型 | ID | 名称 |
属于 | 398 | ||
属于 | 399 | ||
属于 | 742 | CERT C Secure Coding Standard (2008) Chapter 9 - Memory Management (MEM) | |
属于 | 876 | ||
属于 | 969 | ||
属于 | 1162 | SEI CERT C Coding Standard - Guidelines 08. Memory Management (MEM) |
说明
维护
关于“双重释放”应该被作为“释放后使用”的子弱点存在争议,但是在弱点理论中,“使用”和“释放”是作为两个不同的操作的,因此“过期或者释放后释放资源”可能会更精确,但目前仍不存在这样的描述。
关联关系
此弱点通常由另外一个弱点引发,例如未处理的错误或者线程间的竞争条件。它也可能会是缓冲区溢出的前导。