Do not use deprecated or obsolete obsolescent functions when more secure equivalent functions are available. Deprecated functions are defined by the C Standard. Obsolete functions are typically functions for which there are more secure or portable alternatives available and Obsolescent functions are defined by this rulerecommendation.
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
Functions in the first column of the following table are hereby defined to be obsolete obsolescent functions. To remediate invocations of obsolete 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 nonobsolete 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 obsolete obsolescent because the ()strodstrtod(), strtof(), strtol(), strtold(), strtoll(), strotulstrtoul(), 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 obsolete 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 obsolete obsolescent because ()setbuf does not return a value and can be emulated using ()setvbuf. See FIO12ERR07-C. Prefer setvbuf() to setbuf()functions that support error checking over equivalent functions that don't.()
The rewind function is obsolete obsolescent because ()rewind does not return a value and can be emulated using ()fseek. See FIO07ERR07-C. Prefer fseek() to rewind()functions that support error checking over equivalent functions that don't.()
The asctime and ()ctime functions are obsolete obsolescent because they use non-reentrant static buffers and can be emulated using ()asctime_s and ()ctime_s.()
Unchecked
...
Obsolescent Functions
The following If you are using platforms that support Annex K, then functions in the first column of the following table are hereby defined to be unchecked obsolete functions:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
To remediate invocations of unchecked obsolete 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 nonobsolete functions from ISO/IEC TR 24731 (Part I):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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]or alternative nonobsolete functions from ISO/IEC TR 24731-2:2010 (Part II):
|
|
|
|
|
|
|
|
|
|
|
|
|
Noncompliant Code Example
In this noncompliant code example, the obsolete obsolescent functions strcat and strcpy are used.() and strcpy() are used:
| Code Block | ||
|---|---|---|
| ||
#include <string.h> #include <stdio.h> enum { BUFSIZE = 32 }; 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); } |
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); } |
Noncompliant Code Example
In this noncompliant code example, the obsolete function setbuf is used.
| Code Block | ||
|---|---|---|
| ||
FILE *file;
/* Setup file */
setbuf(file, NULL);
/* ... */
|
Compliant Solution
In this compliant solution, function setvbuf is used instead.
| Code Block | ||||
|---|---|---|---|---|
| ||||
FILE *file;
/* Setup file */
setvbuf(file, NULL, _IONBF, BUFSIZ);
/* ... */ |
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 */
}
|
Compliant Solution
In this compliant solution.
| Code Block | ||||
|---|---|---|---|---|
| ||||
|
Noncompliant Code Example
In this noncompliant code example, tmpfile is used.
| Code Block | ||
|---|---|---|
| ||
FILE *fp = tmpfile();
if (fp == NULL) {
/* Handle error */
}
|
Compliant Solution
In this compliant solution,
| Code Block | ||||
|---|---|---|---|---|
| ||||
|
Exceptions
MSC34-EX1: If an out-of-bounds store cannot occur in a specific invocation of a function, the invocation of that function is permitted by this rule. The rationale for this exception is that the simple use of such a function in a program does not mean the program is incorrect. To eliminate the use of such a function, the programmer must replace calls to the deprecated or obsolete function with calls to the alternative functions. Unfortunately, the process of modifying existing code frequently introduces defects and vulnerabilities and is not recommended. New code should be developed in conformance to this guideline, however.
Risk Assessment
The deprecated and obsolete functions enumerated in this guideline are commonly associated with software vulnerabilities.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
|---|---|---|---|---|---|
MSC34-C | High | Probable | Medium | P12 | L1 |
Related Vulnerabilities
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
| 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 Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
| CERT C Secure Coding Standard |
FIO07-C. Prefer fseek() to rewind()
FIO12-C. Prefer setvbuf() to setbuf()
Prefer functions that support error checking over equivalent functions that don't |
MSC34-C. Do not use deprecated or obsolete functions
Detect errors when converting a string to a number |
| 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) |
open Function"| [Seacord 2013] | Chapter 2, "Strings" Chapter 8, "File I/O" |
| [Seacord 2005b] | "Managed String Library for C, C/C++" |
...
...