Versions Compared

Key

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

...

ISO/IEC TR 24731-1 functions are still capable of overflowing a buffer if the maximum length of the destination buffer and number of characters to copy are incorrectly specified.   ISO/IEC TR 24731-2 functions may make it more difficult to keep track of memory that must be freed, leading to memory leaks.  As a result, the ISO/IEC TR 24731 functions are not especially secure but may be useful in preventive maintenance to reduce the likelihood of vulnerabilities in an existing legacy code base.

Non-Compliant Code Example

The following noncompliant code overflows its buffer if msg is too long, and has undefined behavior if msg is a null pointer.

Code Block
bgColor#FFCCCC
void complain(const char *msg) {
  static const char prefix[] = "Error: ";
  static const char suffix[] = "\n";
  char buf[BUFSIZ];

  strcpy(buf, prefix);
  strcat(buf, msg);
  strcat(buf, suffix);
  fputs(buf, stderr);
}

Compliant Solution (run time)

The following compliant solution will not overflow its buffer.

Code Block
bgColor#ccccff
void complain(const char *msg) {
  errno_t err;
  static const char prefix[] = "Error: ";
  static const char suffix[] = "\n";
  char buf[BUFSIZ];

  if ((err = strcpy_s(buf, sizeof(buf), prefix)) != 0) {
    /* handle error */
  }
  if ((err = strcat_s(buf, sizeof(buf), msg)) != 0) {
    /* handle error */
  }
  if ((err = strcat_s(buf, sizeof(buf), suffix)) != 0) {
    /* handle error */
  }
  fputs(buf, stderr);
}

Compliant Solution (partial compile time)

The following compliant solution performs some of the checking at compile time using a static assertion (see DCL03-A. Use a static assertion to test the value of a constant expression).

Code Block
bgColor#ccccff
void complain(const char *msg) {
  errno_t err;
  static const char prefix[] = "Error: ";
  static const char suffix[] = "\n";
  char buf[BUFSIZ];

  /* Ensure that more than one character is available for msg. */
  static_assert(sizeof(buf) > sizeof(prefix) + sizeof(suffix),
                "Buffer for complain() is too small");
  strcpy(buf, prefix);
  if ((err = strcat_s(buf, sizeof(buf), msg)) != 0) {
    /* handle error */
  }
  if ((err = strcat_s(buf, sizeof(buf), suffix)) != 0) {
    /* handle error */
  }
  fputs(buf, stderr);
}

Risk Assessment

String handling functions defined in C99 Section 7.21 and elsewhere are susceptible to common programming errors that can lead to serious, exploitable vulnerabilities. Proper use of TR 24731 functions can eliminate the majority of these issues.

Recommendation

Severity

Likelihood

Remediation Cost

Priority

Level

STR00-A

3 (high)

2 (probable)

2 (medium)

P12

L1

Automated Detection

The LDRA tool suite V 7.6.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 TR 24731-1-2007|AA. C References#ISO/IEC TR 24731-1-2007]\]
\[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]\] Section 7.21, "String handling <string.h>"
\[[Seacord 05a|AA. C References#Seacord 05a]\] Chapter 2, "Strings"
\[[Seacord 05b|AA. C References#Seacord 05b]\]

...