【缺陷周话】第15期----资源未释放:文件
字数 1377 2025-08-18 11:37:49
资源未释放:文件缺陷详解与防护指南
1. 缺陷概述
资源未释放:文件是指在使用文件、IO流等资源时,未能及时关闭或释放已打开的文件描述符,导致系统资源泄露的安全缺陷。这类缺陷属于CWE-775: Missing Release of File Descriptor or Handle after Effective Lifetime。
关键特性:
- 文件操作的基本流程包括:打开、读写、删除、关闭
- 虽然程序退出时会自动关闭打开的文件,但依赖此机制存在风险
- 每个程序同时打开的文件数量有限制(≤FOPEN_MAX)
2. 危害分析
文件描述符未释放可能导致:
- 信息泄露:敏感文件可能被未授权的进程访问
- 拒绝服务(DoS):文件描述符耗尽导致系统无法处理新请求
- 系统性能下降:资源浪费影响整体性能
实际漏洞案例:
- CVE-2018-14621:libtirpc中的无限循环漏洞,文件描述符耗尽导致服务器拒绝服务
- CVE-2018-9275:Yubico PAM模块中的文件描述符泄露,导致信息泄露和DoS攻击
3. 缺陷代码示例与分析
3.1 缺陷代码
#include <stdio.h>
void badSink(FILE * data)
{
/* FLAW: No attempt to close the file */
; /* empty statement needed for some flow variants */
}
void bad()
{
FILE * data;
data = fopen("CWE775_Missing_Release_of_File_Descriptor__fopen_no_close_01_bad.txt", "w+");
badSink(data);
}
问题点:
- 第26行使用
fopen()打开文件 - 函数结束前未调用
fclose()释放资源 - 文件描述符会一直保持打开状态
3.2 修复代码
#include <stdio.h>
void goodSink(FILE * data)
{
/* FIX: If the file is still opened, close it */
if (data != NULL)
{
fclose(data);
}
}
void good()
{
FILE * data;
data = fopen("CWE775_Missing_Release_of_File_Descriptor__fopen_no_close_01_good.txt", "w+");
goodSink(data);
}
修复要点:
- 第30行显式调用
fclose()关闭文件 - 添加NULL检查确保指针有效
- 确保资源在任何执行路径下都能被释放
4. 检测与防护措施
4.1 防护建议
-
及时手动关闭:
- 文件使用完毕后立即调用
fclose() - 对于C++,使用RAII模式管理文件资源
- 文件使用完毕后立即调用
-
异常处理:
- 在所有异常处理分支中添加资源释放代码
- 使用
try-finally或类似机制确保资源释放
-
最佳实践:
- 将资源获取与释放放在同一抽象层次
- 使用智能指针或资源管理类自动处理释放
-
代码审查:
- 检查所有文件操作是否配对出现
open/close - 特别注意错误处理路径中的资源释放
- 检查所有文件操作是否配对出现
4.2 自动化检测
使用静态代码分析工具(如360代码卫士)可以:
- 自动识别未配对的资源操作
- 检测异常路径中的资源泄露
- 提供缺陷定位和修复建议
5. 扩展知识
相关CWE条目:
- CWE-775: Missing Release of File Descriptor or Handle after Effective Lifetime
- CWE-404: Improper Resource Shutdown or Release
- CWE-772: Missing Release of Resource after Effective Lifetime
编程语言差异:
- C/C++:需要显式调用
fclose() - Java:使用
try-with-resources或显式调用close() - Python:使用
with语句或显式调用close() - C#:使用
using语句或显式调用Dispose()
6. 总结
文件资源未释放是常见但容易被忽视的安全缺陷,开发者应当:
- 建立资源管理的规范意识
- 在所有代码路径中确保资源释放
- 利用自动化工具辅助检测
- 在代码审查中特别关注资源管理
通过规范的编码实践和工具辅助,可以有效预防此类缺陷,提高软件的安全性和可靠性。