SV.FMT_STR.PRINT_FORMAT_MISMATCH.UNDESIRED

予期しない指定とパラメーターの一致

SV.FMT_STR.PRINT_FORMAT_MISMATCH.UNDESIRED チェッカーは、表示する関数パラメーターと対応する書式文字列指定が一致しない場合、コードにフラグを立てます。このような場合、対応する書式文字列指定のとおり、このパラメーターが占有するスタックメモリのブロックは一致します。

脆弱性とリスク

メモリブロックのサイズが指定から期待されるサイズと一致するため、メモリ破壊が発生する可能性はありませんが、この状態によって出力が予期しないものとなる可能性があります。また、コードを異なるプラットフォームに移植する場合にも問題が発生する可能性があります。この場合、メモリのサイズが異なる可能性があります。

脆弱コード例

コピー
 void foo(FILE* f, char* pc, int i, char c, long l, struct SomeStruct ss) {
     fprintf(f, "%s", pc);
     fprintf(f, "%d", pc);// fprintf format mismatch: unexpected parameter type
     fprintf(f, "%10d", i);
     fprintf(f, "%hx", i);
     fprintf(f, "%c", l); // fprintf format mismatch: unexpected parameter type
     fprintf(f, "%p", i); // fprintf format mismatch: unexpected parameter type
 }

Klocwork は、書式文字列仕様とパラメーターの間の不一致を示す 3、6、7 行目にエラーのフラグを立てます。書式指定からわかるように、3 行目では整数、6 行目では文字、7 行目ではポインターアドレスが期待され、また、これらの行のパラメーターで期待値と一致するものはありません。ただし、メモリの不一致はないため、エラーは BAD というより UNDESIRED と考えられます。その一方で、2、4、5 行目は、指定とパラメーターが一致する例を示しています。

修正コード例

コピー
 void foo(FILE* f, char* pc, int i, char c, long l, struct SomeStruct ss) {
     fprintf(f, "%s", pc);
     fprintf(f, "%d", i);
     fprintf(f, "%10d", i);
     fprintf(f, "%hx", i);
     fprintf(f, "%c", c); 
     fprintf(f, "%p", pc); 
 }

修正例では、それぞれの書式指定とパラメーターは対応しています。