EN JP CN

NNTS.MIGHT

NNTS.MIGHT

可能性のある非 null 終了文字列からのバッファオーバーフロー

C とC++ では、C 文字列または null 終了文字列では、null 文字 (\0) で終了する文字のシーケンスです。C 文字列の長さは、null 文字を検索することで求められます。

チェッカーの NNTS ファミリーは、null 終了しないまたはしない可能性のある文字配列を持つ文字列操作関数を使用するコードを探します。NNTS.MIGHT チェッカーは、文字の長さが不明な引数など、必要な情報を評価できない文字列操作関数を使用して、コードを探します。

脆弱性とリスク

従来は、null 終了によりセキュリティに関する問題が発生しました。たとえば、次のようになります。

  • 文字列に挿入する null 文字は、予期せずにそれを一部省略できます。
  • null 文字に十分なスペースが割り当てられていない、または、null を忘れた一般的なバグです
  • 多くのプログラムでは、文字列を固定サイズのバッファにコピーする前に長さをチェックせず、長すぎるとバッファオーバーフローが発生します
  • null 文字を保存できないということは、間違った関数が使用された場合に問題が発生する可能性のあるさまざまな関数が文字列とバイナリデータを処理する必要があるという意味です

軽減と防止

問題を回避するには、次を実行します。

  • パフォーマンスの制約が許せば、特別なコードを追加して文字列バッファの null 終了を検証します
  • strncpy のようなバインドされた文字列操作関数に切り替えます
  • バッファオーバーラントレースバックに関与するバッファの長さを検査します

脆弱コード例

1  int nnts_m_m_2(char * src)
2  { 
3      char buf[8];
4      char tgt[1024];
5      
6      strncpy(buf, src, 3);
7      strcpy(tgt, buf);
8      return 0;
9  }

この例では、Klocwork は 7 行目で NNTS.MIGHT バッファオーバーフロー指摘レポートを生成します。パラメーター 'src' の文字の長さは不明です。'src' の文字列の長さが 3 以上の場合は、6 行目の strncpy への呼び出しは、3 文字のみを 'buf' へ書き込みます。'buf' が割り当てられているスタックメモリに null 終了がない場合、7 行目での呼び出しは、その範囲外の配列にアクセスします。'buf' に null 終了がある場合、strcpy は初期化されていないデータを 'tgt' バッファにまだコピーできます。このコードは、バッファオーバーフローとなる可能性があり、セキュリティに関するさまざまな重大問題が生じる可能性があります。

Klocwork は、'src' の文字長が 3 以上であるとわかっていたら、NNTS.MUST 指摘レポートを生成したでしょう。

修正コード例

1  int nnts_m_m_2(char * src)
2  { 
3      char buf[8];
4      char tgt[1024];
5      
6      strncpy(buf, src, 3);
7      // ensure null termination
8      buf[3] = '\0';
9      strcpy(tgt, buf);
10     return 0;
11 }

修正例では、null 終了文字が 8 行目で 'buf' に明示的に追加されます。'buf' はもはや非 null 終了文字列ではないため、指摘は 9 行目で回避されました。

拡張機能

このチェッカーは機能を拡張できます。詳細については、C/C++ 解析のチューニングを参照してください。