...
- 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 | ||||
---|---|---|---|---|
| ||||
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 | ||||
---|---|---|---|---|
| ||||
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 | ||||
---|---|---|---|---|
| ||||
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 | ||||
---|---|---|---|---|
| ||||
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
...