Versions Compared

Key

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

...

Code Block
bgColor#ccccff
langc
enum { ARRAY_SIZE = 32 };
 
void func(void) {
  char dest[ARRAY_SIZE];
  char src[ARRAY_SIZE];
  size_t i;

  for (i = 0; src[i] && (i < sizeof(dest) - 1); ++i) {
    dest[i] = src[i];
  }
  dest[i] = '\0';
}

...

Command-line arguments are passed to main() as pointers to null-terminated byte strings in the array members argv[0] through argv[argc - 1]. If the value of argc is greater than 0, the string pointed to by argv[0] is, by convention, the program name. If the value of argc is greater than 1, the strings referenced by argv[1] through argv[argc - 1] are the actual program arguments.

Vulnerabilities can occur when inadequate space is allocated to copy a command-line argument or other program input. In this noncompliant code example, the contents of argv[0] can be manipulated by an attacker to cause a buffer overflow:

...

Code Block
bgColor#ccccff
langc
#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 = (char *)malloc(strlen(name) + 1);
  if (prog_name != NULL) {
    strcpy(prog_name, name);
  } else {
    /* Handle error */
  }
  free(prog_name);
  return 0;
}

Remember to add a byte to accommodate the null-terminated byte string.

...

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;
}

The strcpy_s() function can be used to copy data to or from dynamically allocated memory or a statically allocated array. If insufficient space is available, strcpy_s() returns an error.

...

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] : "";
  size_t prog_size;
  return 0;
}

Noncompliant Code Example (getenv())

The getenv() function searches an searches the environment list, provided by the host environment, for a string that matches the string pointed to by name. The set of environment names and the method for altering the environment list are implementation-defined. Environment variables can be arbitrarily large, and copying them into fixed-length arrays without first determining the size and allocating adequate storage can result in a buffer overflow.

...

Code Block
bgColor#ccccff
langc
#include <stdlib.h>
#include <string.h>
 
void func(void) {
  char *buff;
  char *editor = getenv("EDITOR");
  if (editor == NULL) {
    /* EDITOR environment variable not set */
  } else {
    size_t len = strlen(editor) + 1;
    buff = (char *)malloc(len);
    if (buff == NULL) {
      /* Handle error */
    }  
    memcpy(buff, editor, len);
    free(buff);
  }
}

Noncompliant Code Example (sprintf())

...