CONC.NO_UNLOCK

ロック解除の欠落

CONC.NO_UNLOCK チェッカーは、対応するロック解除がないロックされたスレッドにより、可能性のあるデッドロックをレポートします。

脆弱性とリスク

ロックの解放を忘れるとデッドロックになる場合があります。ロックが維持されたまま解放されない場合、そのロックが解放されるまで、それ以降のロック獲得の呼び出しは進みません。

軽減と防止

ロック競合を回避するための指針:

  • コードのロックされるセクションを、できるだけ小さく、できるだけ単純にして、理解しやすいようにします。
  • データ競合のような同時実行問題を起こす可能性のあるコードのセクションをロックしないこと。
  • 循環待ち条件は、是が非でも避けること。
  • いくつかのロックを、通常はエスカレートしたガードパターンで使用する場合、環境ごとに厳密に同じエスカレーションが実行されることを必ず確認する。

脆弱コード例

コピー
  #include <pthread.h>
  
  extern int z();
  
  void foo(pthread_mutex_t *mutex) {
    pthread_mutex_lock(mutex);
    switch (z()) {
      case 0
        return;
     case 1
       break;
   }
   pthread_mutex_unlock(mutex);
 }

Klocwork は、case 0 が有効な場合に、6 行目で mutex がロックされ 9 行目でロック解除されていないことをレポートします。

修正コード例

コピー
  #include <pthread.h>
 
  extern int z();
  
  void foo(pthread_mutex_t *mutex) {
    pthread_mutex_lock(mutex);
    switch (z()) {
      case 0
        pthread_mutex_unlock(mutex);
        return;
     case 1
       break;
   }
   pthread_mutex_unlock(mutex);
 }

修正バージョンでは、ロック解除が 9 行目に含まれています。

関連チェッカー

セキュリティトレーニング

Secure Code Warrior が提供しているアプリケーションセキュリティトレーニング教材。

拡張機能

このチェッカーは機能を拡張できます。関連するナレッジベースレコードには以下の種類があります。

詳細については、C/C++ 解析のチューニングを参照してください。