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 が提供しているアプリケーションセキュリティトレーニング教材。