Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Changed "Don't" to "Do not" in title to be consistent with other like titles. Is "...and a pointer to a pointer to modify to return the result" correct? Looks like it could either be "to modify the result" or "to return the result." Also, this sentence looks broken, but I'm not sure how to fix it: "The first time strtok() is called, the string is parsed into tokens, character delimiter, and address of the variable in which to return the result are passed as arguments." Also, I noticed the advent of the "editorial we" in this section, which seems inconsistent with others I've seen so far. Ed.

Wiki Markup
The C99 \[\[ISO/IEC 9899-1999\|AA. C References#ISO/IEC 9899-1999\]\] function {{strtok()}} is a string tokenization function
which
 that takes three arguments: an initial string to be parsed, a const-qualified character delimiter, and a pointer to a pointer to modify to return the result.

The first time strtok() is called, the string to be is parsed into tokens, character delimiter, and address of the variable in which to return the result are passed as arguments. The strtok() function parses the string up to the first instance of the delimiter character, replaces the character in place with a null byte ('\0'), and puts the address of the first character in the token to the passed-in variable. Subsequent calls to strtok() begin parsing immediately after the most recently-placed null character.

Because strtok() modifies its argument, the string is subsequently unsafe and cannot be used in its original form. If you need to preserve the original string, copy it into a buffer and pass the address of the buffer to strtok() instead of the original string.

Non-Compliant Code Example

In this example, the strtok() function is used to parse the first argument into colon-delimited tokens; it outputs each word from the string on a new line. Assume that PATH is "/usr/bin:/usr/sbin:/sbin".

Code Block
bgColor#FFCCCC
char *token;
char *path = getenv("PATH");

token = strtok(path, ":");
puts(token);

while (token = strtok(0, ":")) {
  puts(token);
}

printf("PATH: %s\n", path);
/* PATH is now just "/usr/bin" */

However, after the while loop ends, path will have been modified to look like this: "/usr/bin\0/bin\0/usr/sbin\0/sbin\0". This is an issue on several levels. If we check our local path variable, we will only see /usr/bin now. Even worse, we have unintentionally changed the environment variable PATH, which could cause unintended results.

Compliant Solution

In this solution the string being tokenized is copied into a temporary buffer which is not referenced after the calls to strtok():

...

Another possibility is to provide your own implementation of strtok() which does not modify the initial arguments.

Risk Assessment

To quote the Linux Programmer's Manual (man) page on strtok(3):

...

Fortify SCA Version 5.0 is able to detect violations of this recommendation.

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

References

Wiki Markup
\[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]\] Section 7.21.5.8, "The strtok function"
\[Unix Man page\] strtok(3)

...