CERT.CONC.UNSAFE_COND_VAR

条件変数の使用時にはスレッドセーフと活性を維持してください。

wait() 関数は、条件述語が当てはまるかをチェックするループから呼び出す必要があります。条件述語は関数の変数から構成された式です。スレッドを継続的に実行させるには、条件述語が真でなければなりません。

脆弱性とリスク

条件述語ループでネストして wait() を呼び出さないと、通知を受け取った後、チェッカーは条件述語のチェックを行いません。通知が偽物であったり、悪意のあるものであった場合、スレッドが早々に起動する可能性があります。

軽減と防止

wait() 関数は、条件述語が当てはまるかをチェックするループから呼び出す必要があります。

コピー
  #include <condition_variable>
  #include <mutex>
  
  struct Node {
    void *node;
    struct Node *next;
  };
  
  static Node list;
 static std::mutex m;
 static std::condition_variable condition;
 
 void consume_list_element1(std::condition_variable &condition) {
   std::unique_lock<std::mutex> lk(m);
 
   if (list.next == nullptr) {
     condition.wait(lk);          // Uncompliant code.
   }
 
   // Proceed when condition holds.
 }
 
 void consume_list_element2() {
   std::unique_lock<std::mutex> lk(m);
 
   while (list.next == nullptr) {
     condition.wait(lk);         // Compliant code
   }
 
   // Proceed when condition holds.
 }
 
 void consume_list_element3() {
   std::unique_lock<std::mutex> lk(m);
 
   condition.wait(lk, []{ return list.next; });       //Compliant code.
   // Proceed when condition holds.
 }