
C99 The C Standard, 7.29.3.1 [ISO/IEC 9899:2024], provides the following sample implementation of the asctime()
function in Section 7.23.3.1:
Code Block |
---|
char *asctime(const struct tm *timeptr) { static const char wday_name[7][3] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; static const char mon_name[12][3] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; static char result[26]; sprintf( result, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n", wday_name[timeptr->tm_wday], mon_name[timeptr->tm_mon], timeptr->tm_mday, timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec, 1900 + timeptr->tm_year ); return result; } |
This function is supposed to output a character string of 26 positions 26 characters at most, including the terminating zeronull character. If we count the length indicated by the format directives, we arrive at 25. Taking into account the terminating zeronull character, the array size of the string appears sufficient.
However, this implementation assumes that the values of the struct tm
data in timeptr
are within normal ranges , and does nothing to enforce thisthe range limit. If any of the values print more characters than expected, the sprintf()
function may overflow the result
array. For instanceexample, if tm_year
has the value 12345,
then 27 characters (including the terminating null character) are printed, resulting in a buffer overflow.
The asctime()
function primarily exists for compatibility with older implementations. Also, the asctime()
function does POSIX® Base Specifications [IEEE Std 1003.1:2013] says the following about the asctime()
and asctime_r()
functions:
These functions are included only for compatibility with older implementations. They have undefined behavior if the resulting string would be too long, so the use of these functions should be discouraged. On implementations that do not detect output string length overflow, it is possible to overflow the output buffers in such a way as to cause applications to fail, or possible system security violations. Also, these functions do not support localized date and time formats. To avoid these problems, applications should use
strftime()
to generate strings from broken-down times.
The The POSIX standard developers decided to mark the asctime()
function obsolescent even though they are in C99 because of the possibility of buffer overflow. C99 also provides the strftime()
function which can be used to avoid these problemsappears in the list of obsolescent functions in MSC24-C. Do not use deprecated or obsolescent functions.
Noncompliant Code Example
Avoid using This noncompliant code example invokes the asctime()
function with potentially unsanitized data.:
Code Block | ||
---|---|---|
| ||
struct tm time_tm;
/* initialize time_tm */
char *time = asctime(&time_tm);
|
Compliant Solution
You can sanitize the data before invoking asctime()
.
| ||
#include <time.h>
void func | ||
Code Block | ||
---|---|---|
| ||
int validate_tm(struct tm * time_tm) { /* * The range of valid values of the tm_sec member is [0, 60] * inclusive (to allow for leap seconds). */ if (time->tm_sec < 0 || time->tm_sec > 60) return 0; if (time->tm_min < 0 || time->tm_min >= 60) return 0; if (time->tm_hour < 0 || time->tm_hour >= 24) return 0; if (time->tm_mday <= 0 || time->tm_mday > 31) return 0; if (time->tm_mon < 0 || time->tm_mon >= 12) return 0; /* While other years are legit, they may overflow asctime()'s buffer */ if (time->tm_year < -999 || time->tm_year > 9999) return 0; if (time->tm_wday < 0 || time->tm_wday >= 7) return 0; if (time->tm_yday < 0 || time->tm_yday >= 366) return 0; return 1; } struct tm time_tm; /* initialize time_tm */ if (!validate_tm(&time_tm)) { /* handle error */ } char *time = asctime(&time_tm); |
Compliant Solution
char *time = asctime(time_tm);
/* ... */
} |
Compliant Solution (strftime()
)
The strftime()
function allows you the programmer to specify a more rigorous format , and also to specify the maximum size of the resulting time string.:
Code Block | ||||
---|---|---|---|---|
| ||||
#include <time.h> enum { struct tm time; const size_t maxsize = 26 }; /* or maximum size of time string */; void func(struct tm *time) { char s[maxsize]; const char *format = "%c"; /* currentCurrent time representation for locale */ const struct tm *timeptrchar *format = "%c"; size_t size = strftime(s, maxsize, format, timeptrtime); } |
While this This call has the same effects as asctime()
, it ensures but also ensures that no more than maxsize
chars characters are printed, preventing buffer overflow.
Risk Assessment
On implementations that do not detect output-string-length overflow, it is possible to overflow the output buffers resulting in a vulnerability.
Rule | Severity | Likelihood |
---|
Detectable | Repairable | Priority | Level |
---|---|---|---|
MSC33-C | High |
Likely |
No |
No | P9 | L2 |
Automated Detection
Unknown.
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Astrée |
| Supported, but no explicit checker | |||||||
Axivion Bauhaus Suite |
| CertC-MSC33 | |||||||
CodeSonar |
| BADFUNC.TIME_H | Use of <time.h> Time/Date Function | ||||||
Cppcheck Premium |
| premium-cert-msc33-c | |||||||
Helix QAC |
| C5032 C++5030 | |||||||
Klocwork |
| CERT.MSC.ASCTIME | |||||||
LDRA tool suite |
| 44 S | Enhanced Enforcement | ||||||
Parasoft C/C++test |
| CERT_C-MSC33-a | The 'asctime()' and 'asctime_r()' functions should not be used | ||||||
PC-lint Plus |
| 586 | Fully supported | ||||||
Polyspace Bug Finder |
| CERT C: Rule MSC33-C | Checks for use of obsolete standard function (rule partially covered) | ||||||
RuleChecker |
| Supported, but no explicit checker |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
...
Related Guidelines
Key here (explains table format and definitions)
Taxonomy | Taxonomy item | Relationship |
---|---|---|
CERT C Secure Coding Standard | MSC24-C. Do not use deprecated or obsolescent functions | Prior to 2018-01-12: CERT: Unspecified Relationship |
Bibliography
...
[IEEE Std 1003.1:2013] | XSH, System Interfaces, asctime |
...
...
2024] | 7.29.3.1, |
...
"The |
...
asctime Function" |
...
http://www.opengroup.org/onlinepubs/9699919799/functions/asctime.html
MSC32-C. Ensure your random number generator is properly seeded 49. Miscellaneous (MSC) MSC34-C. Do not use deprecated or obsolescent functions