SV.FMT_STR.SCAN_FORMAT_MISMATCH.UNDESIRED

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

SV.FMT_STR.SCAN_FORMAT_MISMATCH.UNDESIRED チェッカーは、スキャン関数パラメーターと対応する書式文字列仕様が一致しない場合、コードにフラグを立てます。このチェッカーは、このパラメーターが指定する項目の型サイズが、対応する書式文字列仕様が指定するサイズ以上だと、欠陥をレポートします。

脆弱性とリスク

このパラメーターが指定する型のサイズは、仕様で指定するサイズと同じかそれ以上であるため、メモリ破壊の可能性はないものの、このような状況は、指定された項目への予期しない値の書き込みの原因となる場合があります。また、このコードを異なるプラットフォームに移植する場合にも問題が発生する可能性があります。

脆弱コード例

1  char* pc;
2  int i;
3  char c;
4  long l;
5  long long ll;
6 
7  void scan_all(FILE* f) {
8    fscanf(f, "%s", pc);
9    fscanf(f, "%d", &pc);  // fscanf format mismatch
10   fscanf(f, "%d", &i);
11   fscanf(f, "%hx", &i);  // fscanf format mismatch
12   fscanf(f, "%c", &l);   // fscanf format mismatch
13   fscanf(f, "%p", &ll);  // fscanf format mismatch
14 }

Klocwork は 9、11、12、13 行目で、書式文字列指定とパラメーターの間の不一致を示すエラーにフラグを立てます。書式仕様からわかるように、9 行目では int 型へのポインターが期待され、11 行目では short 型へのポインターが期待され、12 行目では char 型へのポインターが期待され、13 行目ではポインターへのポインターが期待されているのに、これらの行のいずれのパラメーターもこれらの期待値と一致していません。ただし、いずれの場合も、パラメーターが占有するメモリ項目が、仕様で指定された期待値よりも大きいため、エラーは BAD ではなく UNDESIRED と見なされています。その一方で、8 行目と 10 行目は、指定とパラメーターが一致する例を示しています。

修正コード例

1  char* pc;
2  int i;
3  char c;
4  long l;
5  long long ll;
6  short s;
7 
8  void scan_all(FILE* f) {
9    fscanf(f, "%s", pc);
10   fscanf(f, "%p", &pc);
11   fscanf(f, "%d", &i);
12   fscanf(f, "%hx", &s);
13   fscanf(f, "%ld", &l);
14   fscanf(f, "%lld", &ll);
15 }

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