JPCERT コーディネーションセンター

CON31-C. 他のスレッドのミューテックスをアンロックしたり破壊したりしない

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)

Top へ

Topへ
最新情報(RSSメーリングリストTwitter