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

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

ミューテックスは、同時にアクセスされる共有データ構造を保護するために使用される。ミューテックスをロックするスレッドがミューテックスを所有し、唯一このスレッドがミューテックスをアンロックできるスレッドでなければならない。ミューテックスがまだ使用されている間に破棄された場合、クリティカルセクションや共有データは保護されなくなる。このガイドラインは「CON31-C. 他のスレッドのミューテックスをアンロックしたり破壊したりしない」の POSIX スレッドを使用した場合の例である。

違反コード

次の違反コード例では、クリーンアップスレッドと作業スレッドの間に競合状態が存在する。クリーンアップスレッドは、ロックはすでに使われていないものと想定して(即座に)ロックを破棄する。システムで負荷のかかる処理を行っている場合、ロックを保持していた作業スレッドは、予想よりも長く処理に時間がかかる可能性がある。作業スレッドが共有データを変更し終える前にロックが破棄されると、プログラムは予期せぬ動作を引き起こすかもしれない。

pthread_mutex_t theLock;
int data;

int cleanupAndFinish(void) {
  int result;
  if ((result = pthread_mutex_destroy(&theLock)) != 0) {
    /* エラー処理 */
  }
  data++;
  return data;
}

void worker(int value) {
  if ((result = pthread_mutex_lock(&theLock)) != 0) {
    /* エラー処理 */
  }
  data += value;
  if ((result = pthread_mutex_unlock(&theLock)) != 0) {
    /* エラー処理 */
  }
}
適合コード

次の適合コードでは、ミューテックスが不要になるまで待ってからミューテックスを破棄している。また、ミューテックスをロックするときはエラー条件をチェックすることが重要である。

mutex_t theLock;
int data;

int cleanupAndFinish(void) {
  int result;

  /* アプリケーションによって異なるユーザ定義の関数 */
  wait_for_all_threads_to_finish();
  if ((result = pthread_mutex_destroy(&theLock)) != 0) {
    /* エラー処理 */
  }
  data++;
  return data;
}

void worker(int value) {
  int result;
  if ((result = pthread_mutex_lock(&theLock)) != 0) {
    /* エラー処理 */
  }
  data += value;
  if ((result = pthread_mutex_unlock(&theLock)) != 0) {
    /* エラー処理 */
  }
}
リスク評価

ミューテックスの所有権を無視することのリスクは、ミューテックスを全く使用しないリスクと同等であり、データ完全性が損われる可能性がある。

ルール

深刻度

可能性

修正コスト

優先度

レベル

POS48-C

P4

L3

自動検出

Tool

Version

Checker

Description

Fortify SCA V. 5.0   CERT C Rule Packを使ってこのルールの違反を検出できる
関連するガイドライン
MITRE CWE CWE-667, Insufficient locking
参考資料
[Open Group 2004] pthread_mutex_lock()/pthread_mutex_unlock()
pthread_mutex_destroy()
翻訳元

これは以下のページを翻訳したものです。

POS48-C. Do not unlock or destroy another POSIX thread's mutex (revision 6)

Top へ

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