
...
The ISO/IEC TR 24731-1 functions were created by Microsoft to help retrofit its existing, legacy code base in response to numerous, well-publicized security incidents over the past decade. These functions were then proposed to the ISO/IEC WG14 international standardization working group for the programming language C (ISO/IEC JTC1/SC22/WG14) for standardization.
The strcpy_s()
function, for example, has this signature:
...
ISO/IEC TR 24731-1 functions are still capable of overflowing a buffer if the maximum length of the destination buffer and number of characters to copy are incorrectly specified. ISO/IEC TR 24731-2 functions may make it more difficult to keep track of memory that must be freed, leading to memory leaks. As a result, the ISO/IEC TR 24731 functions are not especially secure but may be useful in preventive maintenance to reduce the likelihood of vulnerabilities in an existing legacy code base.
Non-Compliant Code Example
The following non-compliant code overflows its buffer if msg
is too long.
Code Block | ||
---|---|---|
| ||
void complain(const char *msg) {
static const char prefix[] = "Error: ";
static const char suffix[] = "\n";
char buf[BUFSIZ];
strcpy(buf, prefix);
strcat(buf, msg);
strcat(buf, suffix);
fputs(buf, stderr);
}
|
Compliant Solution (run-time)
The following compliant solution will not overflow its buffer.
Code Block | ||
---|---|---|
| ||
void complain(const char *msg) {
errno_t err;
static const char prefix[] = "Error: ";
static const char suffix[] = "\n";
char buf[BUFSIZ];
if ((err = strcpy_s(buf, sizeof(buf), prefix)) != 0) {
/* handle error */
}
if ((err = strcat_s(buf, sizeof(buf), msg)) != 0) {
/* handle error */
}
if ((err = strcat_s(buf, sizeof(buf), suffix)) != 0) {
/* handle error */
}
fputs(buf, stderr);
}
|
Compliant Solution (partial compile-time)
The following compliant solution performs some of the checking at compile time using a static assertion (see DCL03-A. Use a static assertion to test the value of a constant expression).
Code Block | ||
---|---|---|
| ||
void complain(const char *msg) {
errno_t err;
static const char prefix[] = "Error: ";
static const char suffix[] = "\n";
char buf[BUFSIZ];
static_assert(sizeof(buf) > sizeof(prefix));
strcpy(buf, prefix);
if ((err = strcat_s(buf, sizeof(buf), msg)) != 0) {
/* handle error */
}
if ((err = strcat_s(buf, sizeof(buf), suffix)) != 0) {
/* handle error */
}
fputs(buf, stderr);
}
|
Risk Assessment
String handling functions defined in C99 Section 7.21 and elsewhere are susceptible to common programming errors that can lead to serious, exploitable vulnerabilities. Proper use of TR 24731 functions can eliminate the majority of these issues.
...