Wiki Markup |
---|
Copying data to a buffer that is not large enough to hold that data results in a buffer overflow. While not limited to null-terminated byte strings (NTBS), buffer overflows often occurs when manipulating NTBS data. To prevent such errors, limit copies either through truncation (although consult \[[STR03-A. Do not inadvertently truncate a null-terminated byte string]\] for problems that may cause) or, preferably, ensure that the destination is of sufficient size to hold the character data to be copied and the null-termination character. |
Non-Compliant Code Example (off-by-
...
one error)
Wiki Markup |
---|
This non-compliant code example demonstrates what is commonly referred to as an _off-by-one_ error \[[Dowd 06|AA. C References#Dowd 06]\]. The loop copies data from {{src}} to {{dest}}. However, the null terminator may incorrectly be written one byte past the end of {{dest}}. The flaw exists because the loop does not account for the null-termination character that must be appended to {{dest}}. |
Code Block | ||
---|---|---|
| ||
char dest[ARRAY_SIZE]; char src[ARRAY_SIZE]; size_t i; /* ... */ for (i=0; src[i] && (i < sizeof(dest)); i++) { dest[i] = src[i]; } dest[i] = '\0'; /* ... */ |
Compliant Solution (off-by-
...
one error)
To correct this example, the loop termination condition must be modified to account for the null-termination character that is appended to dest
.
...
The memcpy()
function differs from strcpy_s()
in that it never returns an error. It always The memcpy()
function returns a pointer to the destination string (e.g.that is, its first argument). However, memcpy()
does not validate that the destination pointer has enough space for the memory being copied, and cannot be used if the source and destination strings overlap.
Compliant Solution (argv
)
If an argument is not going to be modified or concatenated, there is no reason to make a copy of the string. Not copying a string is the best way to prevent a buffer overflow, and is also the most efficient solution.
Code Block | ||
---|---|---|
| ||
int main(int argc, char *argv[]) { /* ... */ const char *progname = argv[0]; size_t prog_size; /* ... */ } |
Non-Compliant Code Example (getenv()
)
...
Code Block | ||
---|---|---|
| ||
/* ... */ char buff[256]; if (char *editor = getenv("EDITOR"); if (editor == NULL) { /* No EDITOR environment variable! not set */ } else { strcpy(buff, getenv("EDITOR"editor)); } /* ... */ |
Compliant Solution
...
Code Block | ||
---|---|---|
| ||
/* ... */ char *editorbuff; char *buff; editor = getenv("EDITOR"); if (!editor == NULL) { /* No EDITOR environment variable! not set */ } else { size_t len = strlen(editor)+1; buff = (char *)malloc(len); if (!buff == NULL) { /* Handle malloc() Error */ } memcpy(buff, editor, len); } /* ... */ |
...
Fortify SCA Version 5.0 is able to detect violations of this rule.
The tool Compass Rose /ROSE can detect violations of the rule except for strcpy_s()
and manual string copies such as the first example.
...