Failing to close files when they are no longer needed may allow attackers to exhaust, and possibly manipulate, system resources. This phenomenon is typically referred to as file descriptor leakage, although file pointers may also be used as an attack vector. To prevent file descriptor leaks, files should be closed when they are no longer needed.
| In this non-compliant example inspired by a [vulnerability|BB. Definitions#vulnerability] in OpenBSD's {{chpass}} program \[[NAI 98|AA. C References#NAI 98]\], a file containing sensitive data is opened for reading. The program then retrieves the registered editor from the {{EDITOR}} environment variable and executes it using the {{system()}} command. If, the {{system()}} command is implemented in a way that spawns a child process, then the child process inherits the file descriptors opened by its parent. As a result, the child process, in this example whatever program is specified by the {{EDITOR}} environment variable, will be able to access the contents of {{Sensitive.txt}}. | 
| 
FILE* f;
char *editor;
f = fopen(file_name, "r");
if (f == NULL) {
  /* Handle fopen() error */
}
/* ... */
editor = getenv("EDITOR");
if (editor == NULL) {
  /* Handle getenv() error */
}
system(editor);
 | 
On UNIX-based systems, child processes are typically spawned using a form of fork() and exec() and the child process always receives copies of its parent's file descriptors. Under Microsoft Windows, the CreateProcess() function is typically used to start a child process. In Windows, file-handle inheritance is determined on a per-file bases. Additionally, the CreateProcess() function itself provides a mechanism to limit file-handle inheritance. As a result, the child process spawned by CreateProcess() may not receive copies of the parent process's open file handles.
To correct the Non-compliant code example, Sensitive.txt should be closed before launching the editor.
| 
FILE* f;
char *editor;
f = fopen(file_name, "r");
if (f == NULL) {
  /* Handle fopen() error */
}
/* ... */
fclose(f);
f = NULL;
editor = getenv("EDITOR");
if (editor == NULL) {
  /* Handle getenv() error */
}
/* Sanitize environment before calling system()! */
system(editor);
 | 
| There are multiple security issues in this example. Complying with recommendations, such as \[[STR02-A. Sanitize data passed to complex subsystems]\] and \[[FIO02-A. Canonicalize path names originating from untrusted sources]\] can help to mitigate attack vectors used to exploit this vulnerability. However, following these recommendations will not correct the underlying issue addressed by this rule: the file descriptor leak. | 
Failing to properly close files may allow unintended access to, or exhaustion of, system resources.
| Rule | Severity | Likelihood | Remediation Cost | Priority | Level | 
|---|---|---|---|---|---|
| FIO42-C | 2 (medium) | 1 (unlikely) | 2 (medium) | P4 | L3 | 
The LDRA tool suite V 7.6.0 is able to detect violations of this recommendation.
Fortify SCA Version 5.0 with CERT C Rule Pack can detect violations of this recommendation.
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
| \[[Dowd 06|AA. C References#Dowd 06]\] Chapter 10, "UNIX Processes" (File Descriptor Leaks 582-587) \[[MITRE 07|AA. C References#MITRE 07]\] [CWE ID 403|http://cwe.mitre.org/data/definitions/403.html], "UNIX file descriptor leaks" \[[MSDN|AA. C References#MSDN]\] [Inheritance|http://msdn.microsoft.com/en-us/library/ms683463.aspx] (Windows) \[[NAI 98|AA. C References#NAI 98]\] Bugtraq: Network Associates Inc. Advisory (OpenBSD) | 
FIO41-C. Do not call getc() or putc() with stream arguments that have side effects 09. Input Output (FIO) FIO43-C. Do not copy data from an unbounded source to a fixed-length array