Do not use deprecated or obsolescent functions when more secure equivalent functions are available.
Deprecated functions are defined by the C99 standard and Technical CorrigendaC Standard. Obsolescent functions are defined by this guidelinerecommendation.
Deprecated Functions
The gets() function was deprecated by Technical Corrigendum 3 to C99 and eliminated from C11. The Annex K gets_s() function is a recommended alternative to gets().
Obsolescent Functions
The following functions are obsolescent and should be avoided in favor of either the portable equivalent or, if available, the more secure alternatives defined in [ISO/IEC TR 24731-1] Extensions to the C Library, — Part I: Bounds-checking interfaces, and [ISO/IEC TR 24731-2] Extensions to the C Library, — Part II: Dynamic Allocation Functions. (Several of the "Portable Equivalent" entries are specified in the POSIX standard.)
Functions in the first column of the following table are hereby defined to be obsolescent functions. To remediate invocations of obsolescent functions, an application might use inline coding that, in all respects, conforms to this guideline, or an alternative library that, in all respects, conforms to this guideline, or alternative non-obsolescent functions.
Obsolescent | Recommended | Rationale |
|---|---|---|
|
| Non-reentrant |
|
| No error detection |
|
| No error detection |
|
| No error detection |
|
| No error detection |
|
| Non-reentrant |
|
| No exclusive access to file |
|
| No exclusive access to file |
|
| No error detection |
|
| No error detection |
The atof, and (), atoi(), atol()atoll functions are obsolescent because the ()strtod(), strtof(), strtol(), strtold(), strtoll(), strtoul(), and strtoull functions can emulate their usage and have more robust error handling capabilities. See INT05-C. Do not use input functions to convert character data if they cannot handle all possible inputs.()
The fopen and ()freopen functions are obsolescent because the ()fopen_s and ()freopen_s functions can emulate their usage and improve security by protecting the file from unauthorized access by setting its file protection and opening the file with exclusive access [ISO/IEC WG14 N1173].()
The setbuf function is obsolescent because ()setbuf does not return a value and can be emulated using ()setvbuf. See ERR07-C. Prefer functions that support error checking over equivalent functions that don't.()
The rewind function is obsolescent because ()rewind does not return a value and can be emulated using ()fseek. See ERR07-C. Prefer functions that support error checking over equivalent functions that don't.()
The asctime and ()ctime functions are obsolescent because they use non-reentrant static buffers and can be emulated using ()asctime_s and ()ctime_s.()
Unchecked Obsolescent Functions
If you are using platforms that support Annex K, then functions in the first column of the following table are hereby defined to be obsolescent functions, with functions in the second column being the recommended alternatives from Annex K.
Obsolescent | Recommended |
|---|---|
| bsearch() | bsearch_s() |
| fprintf() | fprintf_s() |
| fscanf() | fscanf_s() |
| fwprintf() | fwprintf_s() |
| fwscanf() | fwscanf_s() |
| getenv() | getenv_s() |
| gmtime() | gmtime_s() |
| localtime() | localtime_s() |
| mbsrtowcs() | mbsrtowcs_s() |
| mbstowcs() | mbstowcs_s() |
| memcpy() | memcpy_s() |
| memmove() | memmove_s() |
| printf() | printf_s() |
| qsort() | qsort_s() |
| scanf() | scanf_s() |
| snprintf() | snprintf_s() |
| sprintf() | sprintf_s() |
| sscanf() | sscanf_s() |
| strcat() | strcat_s() |
| strcpy() | strcpy_s() |
| strerror() | strerror_s() |
| strlen() | strnlen_s() |
| strncat() | strncat_s() |
| strncpy() | strncpy_s() |
| strtok() | strtok_s() |
| swprintf() | swprintf_s() |
| swscanf() | swscanf_s() |
| vfprintf() | vfprintf_s() |
| vfscanf() | vfscanf_s() |
| vfwprintf() | vfwprintf_s() |
| vfwscanf() | vfwscanf_s() |
| vprintf() | vprintf_s() |
| vscanf() | vscanf_s() |
| vsnprintf() | vsnprintf_s() |
| vsprintf() | vsprintf_s() |
| vsscanf() | vsscanf_s() |
| vswprintf() | vswprintf_s() |
| vswscanf() | vswscanf_s() |
| vwprintf() | vwprintf_s() |
| vwscanf() | vwscanf_s() |
| wcrtomb() | wcrtomb_s() |
| wcscat() | wcscat_s() |
| wcscpy() | wcscpy_s() |
| wcslen() | wcsnlen_s() |
| wcsncat() | wcsncat_s() |
| wcsncpy() | wcsncpy_s() |
| wcsrtombs() | wcsrtombs_s() |
| wcstok() | wcstok_s() |
| wcstombs() | wcstombs_s() |
| wctomb() | wctomb_s() |
| wmemcpy() | wmemcpy_s() |
| wmemmove() | wmemmove_s() |
| wprintf() | wprintf_s() |
| wscanf() | wscanf_s() |
For information on the tmpfile() and tmpfile_s() functions, see FIO21-C. Do not create temporary files in shared directories.
For information on the memset() and memset_s() functions, see MSC06-C. Beware of compiler optimizations.
To remediate invocations of obsolescent functions, an application might use any of the following recommended functions from ISO/IEC TR 24731-2, Extensions to the C Library—Part II: Dynamic Allocation Functions [ISO/IEC TR 24731-2]:
|
|
|
|
|
|
|
|
|
|
|
|
|
Function
Portable Equivalent
Secure Alternative
asctime
asctime_s
atof
strtod
atoi
strtol
atol
strtol
atoll
strtoll
bsearch
bsearch_s
ctime
ctime_s
fopen
fmemopen,open_memstream
fopen_s
fopen
open_wmemstream
fprintf
fprintf_s
freopen
freopen_s
fscanf
getdelim,getline
fscanf_s
fwprintf
fwprintf_s
fwscanf
getwdelim,getwline
fwscanf_s
getenv
getenv_s
gmtime
gmtime_s
localtime
localtime_s
mbsrtowcs
mbsrtowcs_s
mbstowcs
mbstowcs_s
memcpy
memcpy_s
memmove
memmove_s
printf
printf_s
qsort
qsort_s
remove
rename
rewind
fseek
setbuf
vsetbuf
snprintf
snprintf_s
sprintf
asprintf
sprintf_s
sscanf
sscanf_s
strcat
strcat_s
strcpy
stpcpy,strdup
strcpy_s
strerror
strerror_r
strerror_s
strncat
strncat_s
strncpy
stpncpy,strndup
strncpy_s
strtok
strtok_r
strtok_s
swprintf
aswprintf
swprintf_s
swscanf
swscanf_s
tmpfile
mkstemp
tmpfile_s
tmpfile_s
mkstemp
tmpnam
mkstemp
tmpnam_s
vfprintf
vfprintf_s
vfscanf
vfscanf_s
vfwprintf
vfwprintf_s
vfwscanf
vfwscanf_s
vprintf
vprintf_s
vscanf
vscanf_s
vsnprintf
vsnprintf_s
vsprintf
vasprintf
vsprintf_s
vsscanf
vsscanf_s
vswprintf
vaswprintf
vswprintf_s
vswscanf
vswscanf_s
vwprintf
vwprintf_s
vwscanf
vwscanf_s
wcrtomb
wcrtomb_s
wcscat
wcscat_s
wcscpy
wcscpy_s
wcsncat
wcsncat_s
wcsncpy
wcsncpy_s
wcsrtombs
wcsrtombs_s
wcstok
wcstok_s
wcstombs
wcstombs_s
wctomb
wctomb_s
wmemcpy
wmemcpy_s
wmemmove
wmemmove_r
wprintf
wprintf_s
wscanf
wscanf_s Noncompliant Code Example
In this noncompliant code example, the obsolescent functions strcat() and and strcpy() are are used.:
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <string.h> #include <stdio.h> enum { BUFSIZE BUFFERSIZE=256 32 }; void complain(const char *msg) { static const char prefix[] = "Error: "; static const char suffix[] = "\n"; char buf[BUFFERSIZEBUFSIZE]; strcpy(buf, prefix); strcat(buf, msg); strcat(buf, suffix); fputs(buf, stderr); } |
Compliant Solution
In this compliant solution, strcat() and strcpy() are replaced by strcat_s() and strcpy_s().:
| Code Block | ||||
|---|---|---|---|---|
| ||||
#define __STDC_WANT_LIB_EXT1__ #include <string.h> #include <stdio.h> enum { BUFFERSIZE = 256 }; void complain(const char *msg) { static const char prefix[] = "Error: "; static const char suffix[] = "\n"; char buf[BUFFERSIZE]; strcpy_s(buf, BUFFERSIZE, prefix); strcat_s(buf, BUFFERSIZE, msg); strcat_s(buf, BUFFERSIZE, suffix); fputs(buf, stderr); } |
Risk Assessment
The deprecated and obsolescent functions enumerated in this guideline are commonly associated with software vulnerabilities.
Rule | Severity | Likelihood | Detectable |
|---|
Repairable | Priority | Level |
|---|
MSC24-C |
High | Probable |
Yes |
No | P12 | L1 |
Automated Detection
...
Unknown.
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
ISO/IEC 9899:1999 Section 7.21, "String handling <string.h>"
MISRA Rule 20.4
Bibliography
[Burch 2006]
[CERT 2006c]
[Seacord 2005a] Chapter 2, "Strings"
Using deprecated or obsolescent functions shall be diagnosed because there exist equivalent functions that are more secure.
Deprecated functions are defined by the C99 standard and Technical Corrigenda. Obsolescent functions are defined by this guideline.
When an analyzer determines that an out-of-bounds store cannot occur in a specific invocation of a function, the invocation of that function is permitted by this guideline, and the analyzer is not required to produce any diagnostic.
Deprecated Functions
The gets function was deprecated by Technical Corrigendum 3 to C99 and eliminated from C1X.
Obsolescent Functions
Functions in the first column of the following table are hereby defined to be obsolescent functions. To remediate invocations of obsolescent functions, an application might use inline coding that, in all respects, conforms to this guideline, or an alternative library that, in all respects, conforms to this guideline, or alternative non-obsolescent functions.
Obsolescent | Recommended | Rationale |
|---|---|---|
| | Non-reentrant. |
| | No error detection. |
| | No error detection. |
| | No error detection. |
| | No error detection. |
| | Non-reentrant. |
| | No exclusive access to file. |
| | No exclusive access to file. |
| | No error detection. |
| | No error detection. |
The atof, atoi, atol, and atoll functions are obsolescent because the strod, strtof, strtol, strtold, strtoll, strotul, and strtoull functions can emulate their usage and have more robust error handling capabilities. See guideline INT05-C. Do not use input functions to convert character data if they cannot handle all possible inputs [CERT C Secure Coding Standard 2010].
The fopen and freopen functions are obsolescent because the fopen_s and freopen_s functions can emulate their usage and improve security by protecting the file from unauthorized access by setting its file protection and opening the file with exclusive access [ISO/IEC WG14 N1173].
The setbuf function is obsolescent because setbuf does not return a value and can be emulated using setvbuf. See guideline FIO12-C. Prefer setvbuf() to setbuf() [CERT C Secure Coding Standard 2010].
The rewind function is obsolescent because rewind does not return a value and can be emulated using fseek. See guideline FIO07-C. Prefer fseek() to rewind() [CERT C Secure Coding Standard 2010].
The asctime and ctime functions are obsolescent because they use non-reentrant static buffers and can be emulated using asctime_s and ctime_s.
Unchecked Obsolescent Functions
The following are hereby defined to be unchecked obsolescent functions:
| |
| | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | |
|
|
To remediate invocations of unchecked obsolescent functions, an application might use inline coding that, in all respects, conforms to this guideline, or an alternative library that, in all respects, conforms to this guideline, or alternative non-obsolescent functions from ISO/IEC TR 24731 (Part 1)
|
| |
| | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| |
|
|
|
|
|
or alternative non-obsolescent functions from ISO/IEC DTR 24731-2 (Part 2)
| | | | | | |
| | | | | |
|
Noncompliant Code Example
In this noncompliant code example, the obsolescent functions strcat and strcpy are used.
| Code Block | ||
|---|---|---|
| ||
void complain(const char *msg) {
static const char prefix[] = "Error: ";
static const char suffix[] = "\n";
char buf[BUFSIZE];
strcpy(buf, prefix);
strcat(buf, msg);
strcat(buf, suffix);
fputs(buf, stderr);
}
|
Noncompliant Code Example
In this noncompliant code example, the obsolescent function setbuf is used.
| Code Block | ||
|---|---|---|
| ||
FILE *file;
/* Setup file */
setbuf(file, NULL);
/* ... */
|
Noncompliant Code Example
In this noncompliant code example, tmpnam is used.
| Code Block | ||
|---|---|---|
| ||
char file_name[L_tmpnam];
FILE *fp;
if (!tmpnam(file_name)) {
/* Handle error */
}
/* A TOCTOU race condition exists here */
fp = fopen(file_name, "wb+");
if (fp == NULL) {
/* Handle error */
}
|
Noncompliant Code Example
In this noncompliant code example, tmpfile is used.
| Code Block | ||
|---|---|---|
| ||
FILE *fp = tmpfile();
if (fp == NULL) {
/* Handle error */
}
|
Related Guidelines
ISO/IEC JTC1/SC22/WG11 Rationale for TR 24731 Extensions to the C Library Part I: Bounds-checking interfaces
ISO/IEC 9899:1999 Section 7.19.3, "Files," and Section 7.19.4, "Operations on Files," Section 7.19.5.5, "The setbuf function"; 7.19.9.2, "The fseek function"; 7.19.9.5 "The rewind function"; and 7.21, "String handling <string.h>," Section 7.20.1.4, "The strtol, strtoll, strtoul, and strtoull functions," and Section 7.19.6, "Formatted input/output functions," Section 7.21.5.8, "The strtok function"
ISO/IEC TR 24772 "TRJ Use of Libraries"
MITRE CWE: CWE-73 "External Control of File Name or Path, "CWE-367, "Time-of-check Time-of-use Race Condition," CWE-676, "Use of Potentially Dangerous Function," CWE-192, "Integer Coercion Error," CWE-197, "Numeric Truncation Error," CWE-464, "Addition of Data Structure Sentinel," CWE-676, "Use of Potentially Dangerous Function," and CWE-20, "Insufficient Input Validation"
Bibliography
...
| Tool | Version | Checker | Description | ||||||
|---|---|---|---|---|---|---|---|---|---|
| Astrée |
| stdlib-use-ato stdlib-macro-ato stdlib-use-atoll stdlib-macro-atoll | Partially checked | ||||||
| Axivion Bauhaus Suite |
| CertC-MSC24 | Fully implemented | ||||||
| CodeSonar |
| BADFUNC.* (customization) | A number of CodeSonar's "Use of *" checks are for deprecated/obsolescent functions CodeSonar also provides a mechanism for users to create custom checks for uses of specified functions | ||||||
| CC2.MSC34 | Fully implemented | |||||||
| Helix QAC |
| C5039 | |||||||
| LDRA tool suite |
| 44 S | Fully implemented | ||||||
| Parasoft C/C++test |
| CERT_C-MSC24-a | The 'atof', 'atoi', 'atol' and 'atoll' functions from the 'stdlib.h' or 'cstdlib' library should not be used | ||||||
| PC-lint Plus |
| 586 | Fully supported | ||||||
| Polyspace Bug Finder |
| CERT C: Rec. MSC24-C | Checks for use of obsolete standard function (rec. fully covered) | ||||||
| PVS-Studio |
| V513, V2001, V2002 | |||||||
| RuleChecker |
| stdlib-use-ato stdlib-macro-ato stdlib-use-atoll stdlib-macro-atoll | Partially checked | ||||||
| Security Reviewer - Static Reviewer |
| CuEV | Fully implemented |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
| CERT C Secure Coding Standard | ERR07-C. Prefer functions that support error checking over equivalent functions that don't |
| ISO/IEC TR 24772 | Use of Libraries [TRJ] |
| MISRA C:2012 | Rule 21.3 (required) |
| MITRE CWE | CWE-20, Insufficient input validation |
Bibliography
| [Apple 2006] | Apple Secure Coding Guide, "Avoiding Race Conditions and Insecure File Operations" |
| [ |
...
| Burch 2006] | Specifications for Managed Strings, Second Edition |
| [Drepper 2006] | Section 2.2.1 "Identification When Opening" |
| [IEEE Std 1003.1:2013] | XSH, System Interfaces, open |
| ISO/IEC 23360-1:2006 | |
| [ISO/IEC WG14 N1173] | Rationale for TR 24731 Extensions to the C Library Part I: Bounds-checking interfaces |
| [Klein 2002] | "Bullet Proof Integer Input Using strtol()" |
| [Linux |
...
| 2008] | strtok(3) |
| [ |
...
| Seacord 2013] | Chapter 2, "Strings |
...
| " |
...
Chapter |
...
| 8, "File I/O" | |
| [Seacord 2005b] | "Managed String Library for C, C/C++" |
...
49. Miscellaneous (MSC) MSC35-C. Do not include any executable statements inside a switch statement before the first case label