...
The
getenvfunction returns a pointer to a string associated with the matched list member. The string pointed to shall not be modified by the program but may be overwritten by a subsequent call to thegetenvfunction. If the specifiednamecannot be found, a null pointer is returned.
...
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
void func(void) {
char *tmpvar;
char *tempvar;
const char *temp = getenv("TMP");
if (temp != NULL) {
tmpvar = (char *)malloc(strlen(temp)+1);
if (tmpvar != NULL) {
strcpy(tmpvar, temp);
} else {
/* Handle error */
}
} else {
/* Handle error */
}
temp = getenv("TEMP");
if (temp != NULL) {
tempvar = (char *)malloc(strlen(temp)+1);
if (tempvar != NULL) {
strcpy(tempvar, temp);
} else {
/* Handle error */
}
} else {
/* Handle error */
}
if (strcmp(tmpvar, tempvar) == 0) {
printf("TMP and TEMP are the same.\n");
} else {
printf("TMP and TEMP are NOT the same.\n");
}
free(tmpvar);
free(tempvar);
}
|
Compliant Solution (
...
The C Standard, Annex K, provides the getenv_s() function for getting a value from the current environment. However, getenv_s() can still have data races with other threads of execution that modify the environment list.
| Code Block | ||||
|---|---|---|---|---|
| ||||
#define __STDC_WANT_LIB_EXT1__ 1
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
void func(void) {
char *tmpvar;
char *tempvar;
size_t requiredSize;
errno_t err;
err = getenv_s(&requiredSize, NULL, 0, "TMP");
if (err) {
/* Handle error */
}
tmpvar = (char *)malloc(requiredSize);
if (!tmpvar) {
/* Handle error */
}
err = getenv_s(&requiredSize, tmpvar, requiredSize, "TMP" );
if (err) {
/* Handle error */
}
err = getenv_s(&requiredSize, NULL, 0, "TEMP");
if (err) {
/* Handle error */
}
tempvar = (char *)malloc(requiredSize);
if (!tempvar) {
/* Handle error */
}
err = getenv_s(&requiredSize, tempvar, requiredSize, "TEMP" );
if (err) {
/* Handle error */
}
if (strcmp(tmpvar, tempvar) == 0) {
printf("TMP and TEMP are the same.\n");
} else {
printf("TMP and TEMP are NOT the same.\n");
}
free(tmpvar);
tmpvar = NULL;
free(tempvar);
tempvar = NULL;
}
|
Compliant Solution (Windows)
Microsoft Windows provides the _dupenv_s() and wdupenv_s() functions for getting a value from the current environment [MSDN]. The _dupenv_s() function searches the list of environment variables for a specified name. If the name is found, a buffer is allocated; the variable's value is copied into the buffer, and the buffer's address and number of elements are returned. The _dupenv_s() and _wdupenv_s() functions provide more convenient alternatives to getenv_s() and _wgetenv_s() because each function handles buffer allocation directly.
...
Storing the pointer to the string returned by getenv(), localeconv(), setlocale(), or strerror() can result in overwritten data.
Rule | Severity | Likelihood | Detectable | Remediation CostRepairable | Priority | Level |
|---|---|---|---|---|---|---|
ENV34-C | Low | Probable | Yes | NoMedium | P4 | L3 |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
...
Tool | Version | Checker | Description | ||||||
|---|---|---|---|---|---|---|---|---|---|
| Compass/ROSE | |||||||||
| Cppcheck Premium | 24.9.0 | premium-cert-env34-c | |||||||
| Helix QAC |
| DF2681, DF2682, DF2683 | |||||||
| Klocwork |
| MISRA.STDLIB.ILLEGAL_REUSE.2012_AMD1 | |||||||
| LDRA tool suite |
| 133 D | Fully implemented | ||||||
| Parasoft C/C++test |
| CERT_C-ENV34-a | Pointers returned by certain Standard Library functions should not be used following a subsequent call to the same or related function | ||||||
| CERT C: Rule ENV34-C | Checks for misuse of return value from nonreentrant standard function (rule fully covered) |
Related Guidelines
Key here (explains table format and definitions)
...