MEM00- C. 在同一个模块、同一个抽象层次上分配和释放内存 |
|
不遵循该建议所导致的常见软件错误和漏洞包括:内存泄漏, double-free漏洞, 非法访问已经释放的内存,写入已释放或未分配的内存区域 |
MEM01- C. 在调用free()之后立刻给相应的指针赋一个新值 |
MEM01- EX1:如果一个非静态变量在调用free()释放内存后就立刻失去作用域(例如子函数中的一个局部非静态变量), 则没有必要执行重新赋值操作,因为该变量已经不会再被访问到。 |
一般赋的新值是NULL |
MEM02- C. 在调用内存分配函数后立刻对返回的指针进行类型转换 |
|
推荐采用CERT的宏替换法来重新封装malloc系列函数(注意区分简单单个对象、简单数组对象、包含变长数组的单个结构体对象的不同宏封装定义方法) |
MEM03- C. 清理存储在可重复使用资源中的敏感信息 |
|
例如在free()之前先调用memset_s置全0 |
MEM04- C. 禁止执行长度为0的内存分配操作 |
|
如果试图调用malloc(), calloc(), realloc()系列函数分配长度为0的内存,其行为是具体编译器/操作系统实现相关的,会导致不可预料的结果。 |
MEM05- C. 避免进行较大的栈内存分配 |
|
C99标准中引入了变长数组支持,如果变长数组的长度传入未进行任何检 查和处理则很容易被攻击者利用来实施DoS攻击 |
MEM06- C. 确保敏感数据没有写入磁盘 |
|
导致敏感数据被“意外”写入磁盘的两种常见机制是:虚拟内存管理中 swap机制和操作系统异常处理时的core dump机制 |
MEM07- C. 确保calloc()的参数进行乘法操作时,乘数的大小可以用size_t表示 |
|
标准C库(*nix系统上通常是/usr/include /stdint.h)中定义了SIZE_MAX宏,该值是size_t的最大值。该条建议主要是检查calloc()的第一个参数是否越界,例如以下代 码:
long *buffer;
size_t num_elements;
if (num_elements > SIZE_MAX/sizeof(long)) {
/* Handle error condition */
}
buffer = (long *)calloc(num_elements, sizeof(long));
if (buffer == NULL) {
/* Handle error condition */
} |
MEM08- C. 仅对动态分配内存的数组调整容量时才使用realloc()函数 |
|
根据C语言规范:调用realloc(ptr, size)时会先释放ptr所指向的旧对象的内存再返回一个size字节指向新对象的指针。新对象会”继承“旧对象被释放内存前相应内存位置的值(继承多 少取决于size参数的值,最多只能”继承“旧对象的所有值),超过旧对象长度部分的值是”未确定“(未初始化,等同于malloc效果)的。 |
MEM09- C. 不要假设在内存分配函数中会初始化内存 |
|
|