...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stdio.h> #include <stdlib.h> #include <string.h> void func(void) { int ch; size_t buffer_size = 32; char *buffer = malloc(buffer_size); if (!buffer) { /* Handle error */ return; } if ((ssize_t size = getline(&buffer, &buffer_size, stdin)) == -1) { /* Handle error */ } else { char *p = strchr(buffer, '\n'); if (p) { *p = '\0'; } else { /* Newline not found; flush stdin to end of line */ while (((ch = getchar()) != '\n') && !feof(stdin) && !ferror(stdin)) ; } } free (buffer); } |
Note that the getline()
function uses an in-band error indicator, in violation of the recommendation ERR02-C. Avoid in-band error indicators.
Noncompliant Code Example (getchar()
)
This noncompliant cod code example uses the getchar()
function to read one character at a time from stdin
instead of reading the entire line at once. The stdin
stream is read until end-of-file is encountered or a newline character is read. Any newline character is discarded, and a null character is written immediately after the last character read into the array. Similar to the previous example, there are no guarantees that this code will not result in a buffer overflow.
...
Code Block | ||||
---|---|---|---|---|
| ||||
#define __STDC_WANT_LIB_EXT1__ 1 #include <stdlib.h> #include <string.h> int main(int argc, char *argv[]) { /* Be prepared for argv[0] to be null */ const char *const name = (argc && argv[0]) ? argv[0] : ""; char *prog_name; size_t prog_size; prog_size = strlen(name) + 1; prog_name = (char *)malloc(prog_size); if (prog_name != NULL) { if (strcpy_s(prog_name, prog_size, name)) { /* Handle error */ } } else { /* Handle error */ } /* ... */ free(prog_name); return 0; } |
...
Code Block | ||||
---|---|---|---|---|
| ||||
int main(int argc, char *argv[]) {
/* Be prepared for argv[0] to be null */
const char * const prog_name = (argc && argv[0]) ?
argv[0] : "";
/* ... */
return 0;
}
|
Noncompliant Code Example (getenv()
)
...
However, because the sprintf()
function makes no guarantees regarding the length of the generated string generated, a sufficiently long string in name
could generate a buffer overflow.
...
The buffer overflow can be prevented by providing adding a precision length to the %s
specifier conversion specification. If the precision is specified, no more than that many bytes are written. The value precision 123
in this compliant solution ensures that filename
can contain the first 123 characters of name
, the .txt
extension, and the null terminator.
...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stdio.h> void func(const char *name) { char filename[128]; snprintf(filename, sizeof(filename), "%s.txt", name); } |
Risk Assessment
Copying NTBS string data to a buffer that is too small to hold that data results in a buffer overflow. Attackers can exploit this condition to execute arbitrary code with the permissions of the vulnerable process.
...