G.SAF.MEM.03 Unsafe 模式下,应正确释放申请的内存
【级别】 要求
【描述】
当动态分配内存不再使用时应予以释放,否则会发生内存泄漏。如果攻击者可以有意触发该漏洞,则内 存资源可能被耗尽,造成拒绝服务。
优先推荐使用 RAII 模式进行内存释放,避免内存泄漏和重复释放的风险。
内存释放后,对应的指针变成悬空指针,建议重置为空指针, 一旦错误访问,可以立即得到反馈,避免 悬空指针的未定义行为(内存可能被其他业务模块重新分配,悬空指针的使用可能无意间修改了其他业务模块的数据)。
【反例】
- 双重释放
Rust
const BUF_SIZE: usize = 100;
unsafe {
let buf = malloc(BUF_SIZE) as *mut libc::c_char;
// 操作指针 , 写入数据
// 不符合:释放内存,但是指针没有设置为空
free(buf as *mut libc::c_void);
// ......
// 不符合:free 内存后,指针不是空,会导致双重释放错误
free(buf as *mut libc::c_void);
}
【正例】
- 双重释放
Rust
const BUF_SIZE: usize = 100;
unsafe {
let mut buf = malloc(BUF_SIZE) as *mut libc::c_char;
// 操作指针 , 写入数据
// 符合:释放内存后将指针设置为 null
if !buf.is_null() {
free(buf as *mut c_void);
buf = std::ptr::null_mut();
}
// ......
// 符合: `ptr` 为空,不会造成双重释放错误
if !buf.is_null() {
free(buf as *mut c_void);
buf = std::ptr::null_mut();
}
}
【反例】
- 忘记释放
Rust
const BUF_SIZE: usize = 100;
unsafe {
let buf = malloc(BUF_SIZE) as *mut libc::c_char;
// 操作指针 , 写入数据
// 不符合:忘记释放内存
}