EN JP CN

NPD.CHECK.CALL.MIGHT

NPD.CHECK.CALL.MIGHT

以前にチェックした null ポインターが関数呼び出しで逆参照される場合があります

null ポインターを使用してデータにアクセスしようとすると、ランタイムエラーが発生します。有効だと思っていたのに実際は null だと判明したポインターをプログラムが逆参照すると、null ポインター逆参照が起こります。null ポインター逆参照欠陥は、エラー処理または競合状態が無効なためにしばしば起こります。通常、プログラム終了の異常が発生します。ポインターが C/C++ コードにおいて逆参照される前に、null に等しくないことを確認するためにチェックする必要があります。

NPD チェッカーは、null または null ポインターが逆参照されるインスタンスを探します。

NPD.CHECK.CALL.MIGHT チェッカーは、null 値についてチェックされたポインターが後でそれを null についてチェックしないで逆参照する可能性のある関数に渡される場合がある状況にフラグを立てます。

脆弱性とリスク

通常、null ポインターの逆参照は、プロセスに失敗する結果となります。これらの指摘は通常、無効な例外処理が原因で発生します。

軽減と防止

この脆弱性を回避するには、次の操作を実行します。

  • 値を返すすべての関数の結果において null 値についてチェックします
  • すべての外部入力が検証されていることを確認します
  • 変数を明示的に初期化します
  • 異常な例外が正確に処理されていることを確認します

脆弱コード例

1  void reassign(int *argument, int *p) {
2    if (goodEnough(argument)) return;
3    *argument = *p;
4  }
5  
6  void npd_check_call_might(int *argument) {
7    int *p = getValue();
8    if (p != 0) {
9      *p = 1;
10   }
11   if (some_other_check()) return;
12   reassign(argument, p);
13 }

*p は、8 行目で null についてチェックされても、11 行目の条件付きステートメントの結果によっては、null についてチェックされずに逆参照される可能性がある関数 reassign に渡される場合があります。このタイプの脆弱性が原因で、予期しない結果や意図しない結果となる可能性があります。

修正コード例

1  void reassign(int *argument, int *p) {
2    if (goodEnough(argument)) return;
3    *argument = *p;
4  }
5  
6  void npd_check_call_might(int *argument) {
7    int *p = getValue();
8    if (p != 0) {
9      *p = 1;
10   }
11   if (some_other_check()) return;
12   if (p != 0) reassign(argument, p);
13 }

コードが修正されたバージョンでは、null についての 2 回目のチェックは 12 行目で行われます。

拡張機能

このチェッカーは、Klocwork knowledge base (ナレッジベース) を利用して拡張できます。詳細については、C/C++ 解析のチューニングを参照してください。