CON31-C. 他のスレッドのミューテックスをアンロックしたり破壊したりしない
ミューテックスは、同時にアクセスされる共有データ構造を保護するために使用される。ミューテックスをロックするスレッドがこのミューテックスを所有し、唯一このスレッドがミューテックスをアンロックできるスレッドでなければならない。このミューテックスがまだ使用されているうちに破壊された場合、クリティカルセクションや共有データは保護されなくなってしまう。
C 言語規格 [ISO/IEC 9899:2011] セクション 7.26.4.1 第 2 段落には次のように記載されている。
mtx_destroy関数は、mtxで指定されるミューテックスが使用するリソースを解放する。mtxで指定されているミューテックスを待っているスレッドをブロックすることはできない。
これは、スレッドがミューテックスを待っている間にそのミューテックスを破壊することが未定義の動作であることを意味する。
違反コード
以下のコード例では、クリーンアップスレッドと作業スレッドの間に競合状態が存在する。クリーンアップスレッドは、もう使われていないと判断したロックを破壊する。システムに過度な負荷がかかっていると、ロックを保持していた作業スレッドは、予想よりも長く処理に時間がかかる可能性がある。作業スレッドが共有データを変更し終える前にロックが破壊されると、プログラムは予期せぬ動作を引き起こすかもしれない。
mtx_t theLock;
int data;
/* theLock を初期化 */
int cleanupAndFinish(void) {
  int result;
  mtx_destroy(&theLock);
  data++;
  return data;
}
void worker(int value) {
  if ((result = mtx_lock(&theLock)) == thrd_error) {
    /* エラー処理 */
  }
  data += value;
  if ((result = mtx_unlock(&theLock)) == thrd_error) {
    /* エラー処理 */
  }
}
適合コード
以下の適合コードにおいて、ミューテックスが破壊されたあとで必要になることがない。また、ミューテックスをロックするときはエラー条件をチェックすることが重要である。
mutex_t theLock;
int data;
int cleanupAndFinish(void) {
  int result;
  /* ユーザが書いたアプリケーション依存の関数 */
  wait_for_all_threads_to_finish();
  mtx_destroy(&theLock);
  data++;
  return data;
}
void worker(int value) {
  int result;
  if ((result = mtx_lock(&theLock)) == thrd_error) {
    /* エラー処理 */
  }
  data += value;
  if ((result = mtx_unlock(&theLock)) == thrd_error) {
    /* エラー処理 */
  }
}
リスク評価
ミューテックスの所有権を無視するリスクは、ミューテックスをまったく使用しないリスクと同等であり、データ完全性違反につながる可能性がある。
| 
         ルール  | 
      
         深刻度  | 
      
         可能性  | 
      
         修正コスト  | 
      
         優先度  | 
      
         レベル  | 
    
|---|---|---|---|---|---|
| 
         CON31-C  | 
      
         中  | 
      
         中  | 
      
         高  | 
      
         P4  | 
      
         L3  | 
    
自動検出(最新の情報はこちら)
| 
         ツール  | 
      
         バージョン  | 
      
         チェッカー  | 
      
         説明  | 
    
|---|---|---|---|
| 
         Fortify SCA  | 
      
         V. 5.0  | 
      
         
  | 
      
         CERT C Rule Pack を使ってこのルールの違反を検出できる。  | 
    
関連するガイドライン
| MITRE CWE | CWE-667, Insufficient locking | 
参考資料
| [ISO/IEC 9899:2011] | Section 7.26.4.1, "The mtx_destroy Function" | 
    
| [Open Group 2004] | pthread_mutex_lock()/pthread_mutex_unlock()pthread_mutex_destroy() | 
    
翻訳元
これは以下のページを翻訳したものです。
CON31-C. Do not unlock or destroy another thread's mutex (revision 58)



