【缺陷周话】第15期——资源未释放:文件

 

 

1、资源未释放:文件

在使用文件、IO流、数据库连接等资源时,应该在使用后及时关闭或释放,否则可能造成资源未释放问题,本文对其中的文件资源未释放的情况进行描述。文件的基本操作包括打开、读写、删除、关闭等,打开一个文件后,一般来说当一个程序退出时,所有打开的文件将会自动关闭。尽管如此,还是应该在不使用时及时手动关闭或释放文件描述符,因为会存在这样的一种情况:程序打开的文件数量超过同时可以打开的文件数量的上限(一个程序可以同时打开的文件数量是有限的,数量上限小于等于常量 FOPEN_MAX 的值)。此外,SEI CERT C Coding StandardFIO42-C. Close files when they are no longer needed 中的非顺应性示例中也描述了虽然 exit() 会关闭文件,但是当程序异常终止时,同时也失去了对文件是否关闭的判断,因此不推荐依赖于操作系统回收资源的方式。

本缺陷详情请参见 CWE-775: Missing Release ofFile Descriptor or Handle after Effective Lifetime。

 

2、 “资源未释放:文件” 的危害

由于文件描述符没有释放或丢失导致的漏洞并不多,但当资源未释放:文件缺陷被攻击者利用,仍旧可能会导致信息泄露、服务器资源耗尽而产生的拒绝服务等后果。

2018年1月至12月,CVE中共有5条漏洞信息与其相关。部分漏洞如下:

CVE 概述
CVE-2018-14621 libtirpc 1.0.2-rc2 版本之前,存在一个无限循环漏洞,当端口通过轮询方式被使用时,文件描述符耗尽会导致服务器进入无限循环,消耗大量 CPU 时间并拒绝对其他服务端提供服务。
CVE-2018-9275 Yubico PAM模块(aka pam_yubico)的2.18-2.25 版本 util.c 文件中的 check_user_token,成功登陆后可以使认证映射文件描述符泄露,从而导致信息泄露(设备的SN号)和拒绝服务攻击(达到文件描述符的最大值)

 

3、示例代码

示例源于 Samate Juliet Test Suitefor C/C++ v1.3 (https://samate.nist.gov/SARD/testsuite.php),源文件名:CWE775_Missing_Release_of_File_Descriptor_or_Handle__fopen_no_close_01.c。

3.1缺陷代码

在上述示例代码中,在第26行使用fopen() 进行文件打开操作,但是在29行函数结束前,没有对打开的文件进行关闭,存在资源未释放问题。

使用360代码卫士对上述示例代码进行检测,可以检出“资源未释放:文件”缺陷,显示等级为中。如图1所示:

图1:资源未释放:文件的检测示例

3.2 修复代码

在上述修复代码中,Samate 给出的修复方式为:在第30行使用 fclose()进行手动文件关闭。

使用360代码卫士对修复后的代码进行检测,可以看到已不存在“资源未释放:文件”缺陷。如图2:

图2:修复后检测结果

 

4 、如何避免资源未释放:文件

要避免资源未释放:文件,需要注意以下几点:

(1)当文件资源不再使用的情况下,及时手动进行关闭。

(2)需要特别注意的是,在异常处理的分支中常常忽略对资源的关闭,应多加注意。

(3)使用源代码静态分析工具进行自动化的检测,可以辅助定位资源未释放问题。

(完)