Do not make any assumptions about the size of environment variables , because an adversary might have full control over the environment. If the environment variable needs to be stored, then the length of the associated string should be calculated , and the storage dynamically allocated (see STR31-C. Guarantee that storage for strings has sufficient space for character data and the NULL null terminator).
Noncompliant Code Example
This noncompliant code example copies the string returned by getenv()
into a fixed-size buffer.:
Code Block | ||||
---|---|---|---|---|
| ||||
void f() { char path[PATH_MAX]; /* assume $PATH is defined and no longer thanRequires PATH_MAX to be charactersdefined */ strcpy(path, getenv("PATH")); /* useUse path */ } |
However, the string copied from temp
may exceed the size of copy
, leading to a buffer overflowEven if your platform assumes that $PATH
is defined, defines PATH_MAX
, and enforces that paths not have more than PATH_MAX
characters, the $PATH
environment variable still is not required to have less than PATH_MAX
chars. And if it has more than PATH_MAX
chars, a buffer overflow will result. Also, if $PATH
is not defined, then strcpy()
will attempt to dereference a null pointer.
Compliant Solution
In the following this compliant solution, the strlen()
function is used to calculate the size of the string, and the required space is dynamically allocated.:
Code Block | ||||
---|---|---|---|---|
| ||||
void f() { char *copypath = NULL; /* avoidAvoid assuming $PATH is defined or has limited length */ const char *temp = getenv("PATH"); if (temp != NULL) { path = (char*) malloc(strlen(temp) + 1); if (copypath == NULL) { /* Handle error condition */ } else { strcpy(path, temp); } /* Use path * use path */ } } / free(path); } } |
Compliant Solution (POSIX or C2x)
In this compliant solution, the strdup()
function is used to dynamically allocate a duplicate of the string:
Code Block | ||||
---|---|---|---|---|
| ||||
void f() {
char *path = NULL;
/* Avoid assuming $PATH is defined or has limited length */
const char *temp = getenv("PATH");
if (temp != NULL) {
path = strdup(temp);
if (path == NULL) {
/* Handle error condition */
}
/* Use path */
free(path);
}
} |
Risk Assessment
Making assumptions about the size of an environmental variable can result in a buffer overflow.
Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
ENV01-C |
High |
Likely |
Medium | P18 | L1 |
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
CodeSonar |
| LANG.MEM.BO | Buffer overrun | ||||||
Compass/ROSE |
...
Can detect violations of the rule by using the same method as STR31-C. Guarantee that storage for strings has sufficient space for character data and the null terminator | |||||||||
Klocwork |
| ABV.ANY_SIZE_ARRAY ABV.GENERAL ABV.GENERAL.MULTIDIMENSION ABV.ITERATOR ABV.MEMBER ABV.STACK ABV.TAINTED ABV.UNKNOWN_SIZE ABV.UNICODE.BOUND_MAP ABV.UNICODE.FAILED_MAP ABV.UNICODE.NNTS_MAP ABV.UNICODE.SELF_MAP | |||||||
Parasoft C/C++test |
| CERT_C-ENV01-a | Don't use unsafe C functions that do write to range-unchecked buffers | ||||||
PC-lint Plus |
| 669 | Fully supported | ||||||
Polyspace Bug Finder |
| Checks for tainted NULL or non-null-terminated string (rec. partially covered) |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Other Languages
This rule appears in the C++ Secure Coding Standard as ENV01-CPP. Do not make assumptions about the size of an environment variable.
References
Wiki Markup |
---|
\[[ISO/IEC 9899:1999|AA. C References#ISO/IEC 9899-1999]\] Section 7.20.4, "Communication with the environment"
\[[MITRE 07|AA. C References#MITRE 07]\] [CWE ID 119|http://cwe.mitre.org/data/definitions/119.html], "Failure to Constrain Operations within the Bounds of an Allocated Memory Buffer"
\[[Open Group 04|AA. C References#Open Group 04]\] Chapter 8, "Environment Variables"
\[[Viega 03|AA. C References#Viega 03]\] Section 3.6, "Using Environment Variables Securely" |
Related Guidelines
MITRE CWE | CWE-119, Improper Restriction of Operations within the Bounds of a Memory Buffer CWE-123, Write-what-where Condition CWE-125, Out-of-bounds Read |
Bibliography
[IEEE Std 1003.1:2013] | Chapter 8, "Environment Variables" |
[Viega 2003] | Section 3.6, "Using Environment Variables Securely" |
...
ENV00-C. Do not store the pointer to the string returned by getenv() 10. Environment (ENV)