Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: wordsmithing

...

  • SPACE—the space (" ") character
  • N/E—no effect
  • NTBS—char* argument pointing to a null-terminated byte string
  • NTWS—wchar_t* argument pointing to a null-terminated wide character string
  • XSI—ISO/IEC 9945-2003 XSI extension

The format input functions (fscanf() and related functions) use similarly-specified format strings and impose similar restrictions on their format strings and arguments.

Do not supply an unknown or invalid conversion specification or an invalid combination of flag character, precision, length modifier, conversion specifier; to a formatted IO function. Likewise, do not provide a number or type of arguments that do not match the conversion specifiers in the format string.

Noncompliant Code Example

Mismatches between arguments and conversion specifications may result in undefined behavior.  Many compilers can diagnose type mismatches in formatted output function invocations.  In the following noncompliant code example, the error_type argument to printf() is incorrectly matched with the %s specifier (should be %d), and the , rather than with the %d specifier. Likewise, the error_msg argument is incorrectly matched with the %d specifier (should be %s)instead of the %s specifier.  One possible result of this invocation is that printf() will interpret the error_type argument as a pointer, and try to read a string from the address that error_type contains (likely this will . This is likely to result in an access violation):.

Code Block
bgColor#ffcccc
langc
const char *error_msg = "Resource not available to user.";
int error_type = 3;
/* ... */
printf("Error (type %s): %d\n", error_type, error_msg);

...

Code Block
bgColor#ccccff
langc
const char *error_msg = "Resource not available to user.";
int error_type = 3;
/* ... */
printf("Error (type %d): %s\n", error_type, error_msg);

...

The width and precision arguments to printf() format directives must be of type int. Subclause 7.21.6.1 of the C Standard [ISO/IEC 9899:2011] states:

A field width, or precision, or both, may be indicated by an asterisk. In this case, an argument of type int supplies the field width or precision.

Passing them as any other type leads to undefined behavior. In this noncompliant code example, the width and precision are specified using parameters declared to be of size_t type. These are unsigned types that may not be the same size as int.

Code Block
bgColor#ffcccc
langc
int print_int(int i, size_t width, size_t prec) {
  int n;

  n = printf("%*.*d", width, prec, i);

  return n;
}

Compliant Solution

In this compliant solution, the field width and precision arguments to printf() format directives are of type int:

Code Block
bgColor#ccccff
langc
int print_int(int i, int width, int prec) {
  int n;

  n = printf("%*.*d", width, prec, i);

  return n;
}

Risk Assessment

In most cases, incorrectly specified format strings will result in abnormal program termination. However, in some cases they can be used to corrupt memory in manners controllable by an attacker.

Recommendation

Severity

Likelihood

Remediation Cost

Priority

Level

FIO00FIO47-C

High

Unlikely

Medium

P6

L2

Automated Detection

...