SV.FMT_STR.PRINT_FORMAT_MISMATCH.BAD
Mismatched specification and parameter
Print function parameters can occupy stack memory blocks that consist of whole numbers of machine words. If a print function parameter occupies an amount of stack memory different from that expected from the corresponding format-string specification, a vulnerability can result. The SV.FMT_STR.PRINT_FORMAT_MISMATCH.BAD checker flags code in which the size of the memory block for the print parameter and the corresponding format-string specification don't match.
Vulnerability and risk
A mismatched parameter and format-string specification can cause memory access violation and may lead to undesired program execution results. Undefined behavior and abnormal program termination are possible.
Vulnerable code example
# include <string>
# include <stdio.h>
void print_string(double weight, std::string str) {
printf("String of weight %d:", weight); // defect
printf(" %s\n", str); // defect
}
Klocwork flags line 4 because the %d specification doesn't match the parameter of type double. Different amounts of memory are required for type int, which is expected for the %d specification, and type double, which is actually provided. On most 32-bit systems, type int needs one machine word and type double needs two. A memory access violation may occur when one machine word is read from the stack instead of the two words actually occupied by the parameter.
Line 5 is flagged because there is no call to the std::string::c_str() method. A null-terminated string is expected for the %s specification, but an object is actually provided instead. A memory access violation can be caused when an attempt is made to read the memory bytes occupied by the object and any successive bytes until a null character is met.
Fixed code example
# include <string>
# include <stdio.h>
void print_string(double weight, std::string str) {
printf("String of weight %f:", weight);
printf(" %s\n", str.c_str());
}
In line 4 of the fixed code, the correct format specifier, %f, is used for printing a floating point value. In line 5, the call to std::string::c_str() method is added (it is often omitted by mistake).
Related checkers
- SV.FMT_STR.PRINT_FORMAT_MISMATCH.UNDESIRED
- SV.FMT_STR.SCAN_FORMAT_MISMATCH.BAD
- SV.FMT_STR.SCAN_FORMAT_MISMATCH.UNDESIRED
- SV.FMT_STR.PRINT_IMPROP_LENGTH
- SV.FMT_STR.PRINT_PARAMS_WRONGNUM.FEW
- SV.FMT_STR.PRINT_PARAMS_WRONGNUM.MANY
- SV.FMT_STR.SCAN_IMPROP_LENGTH
- SV.FMT_STR.SCAN_PARAMS_WRONGNUM.FEW
- SV.FMT_STR.SCAN_PARAMS_WRONGNUM.MANY
- SV.FMT_STR.UNKWN_FORMAT
- SV.FMT_STR.UNKWN_FORMAT.SCAN