Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: minor edits; reviewed

...

Code Block
bgColor#ccccff
langc
#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
bgColor#ccccff
langc
#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
bgColor#ccccff
langc
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
bgColor#ccccff
langc
#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.

...