The C99 exit()
function is used for normal program termination. If more than one call to exit()
is executed by a program, the behavior is undefined. This may occur when functions are registered with atexit()
, a function that causes the functions registered to it to be called with when the program exits. If a function called as a result of being registered with atexit()
has an exit()
call in it there is undefined behavior.
Non-Compliant Code Example
In this example the function exit1()
is registered by atexit()
so upon program termination exit1()
is called and certain cleanup and maintenance functions can occur. If some failure case <expr>
evaluates as true though the program attempts to fully exit before the cleanup code can be processed. In these cases where <expr>
evaluates to true exit()
will be called twice and the behavior is undefined. Some compilers will simply ignore the exit()
call as it in is a function registered by atexit()
.
#include <stdio.h> #include <stdlib.h> void exit1(void) { if(<expr>) { /* ...cleanup code... */ exit(0); } } int main (void) { atexit(exit1); /* ...program code... */ exit(0); }
Compliant Code
_Exit()
and abort()
will both immediately halt program execution, and may be used within functions registered by atexit()
.
According to C99, [[ISO/IEC 9899-1999:TC2]]:
The function
_exit
terminates the calling process "immediately". Any open file descriptors belonging to the process are closed; any children of the process are inherited by process 1,init
, and the process's parent is sent aSIGCHLD
signal. The value status is returned to the parent process as the process's exit status, and can be collected using one of the wait family of calls. The function_Exit
is equivalent to_exit
.
#include <stdio.h> #include <stdlib.h> void exit1(void) { if(<expr>) { /* ...cleanup code... */ _Exit(0); } } int main (void) { atexit(exit1); /* ...program code... */ exit(0); }
The call to _Exit()
will immediately terminate the program.
Risk Assessment
Multiple calls to exit
are unlikely, and at worst will only cause denial of service attacks or abnormal program termination.
Rule |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
ENV32-C |
1 (low) |
1 (unlikely) |
3 (low) |
P3 |
L3 |
References
[[ISO/IEC 9899-1999]] Section 7.20.4.3, "The exit
function"