Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Arguments read from the command line and are stored in process memory. The function main(), called at program startup, is typically declared as follows when the program accepts command line arguments:

...

Code Block
bgColor#ccccff
int main(int argc, char *argv[]) {
  /* ... */
  char * prog_name = (char *)malloc(strlen(argv[0])+1);
  if (prog_name != NULL) {
    strcpy(prog_name, argv[0]);
  }
  else {
    /* Couldn't get the memory - recover */
  }
  /* ... */
}

...

While the above example is secure, the more generic case where the source string is changeable is vulnerable to a TOCTOU race condition.

Code Block
bgColor#ffcccc
ccharchar * copy_string(const char * src) {
  /* ... */
  char * dest = (char *)malloc(strlen(src)+1);
  if (dest != NULL) {
    strcpy(dest, src);
  }
  else {
    /* Couldn't get the memory - recover */
  }
  /* ... */
}

...

Compliant Solution ( memcpy() )

The memcpy() function operates in principle just like can provide the same functionality for this example as strcpy_s(), but is more universally available.

Code Block
bgColor#ccccff
int main(int argc, char *argv[]) {
    /* ... */
    char * prog_name;
    size_t prog_size;

    prog_size = strlen(argv[0])+1;
    prog_name = (char *)malloc(prog_size);

    if (prog_name != NULL) {
	memcpy(prog_name, argv[0], prog_size);
    }
    else {
	/* Couldn't get the memory - recover */
    }
    /* ... */
}

The memcpy() function differs from {[strcpy_s()}} in that it never returns an error. It always returns a pointer to the destination string, e.g. its first argument. However, memcpy() does not validate that the destination pointer has enough space for the memory being copied. And it should not be used if the source and destination strings overlap.

...